Zero Cross Dimmer EEPROM Problem
Posted: Sat Apr 06, 2019 5:02 am
Hi I am working on MQTT Dimmer using NODEMCU. Normally the project is working flawlessly but when I try to save the change the state of dimmer i.e (Switch State and Brightness Value) the light glows fully and then return to new set state . My Code for the mqtt dimmer is
I think when it tries to call EEPROM.Commit function light glows and when I remove this function light behaves normally but state does not save.
EEPROM.Commit funtion is like...
Please guide me the proper way to save the last state and Last Brightness of MQTT Dimmer.
Code: Select all
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "hw_timer.h"
/************************* Pin Definition *********************************/
//Dimmer Pins
#define zcPin D6
#define pwmPin D7
#define led D0
byte fade = 1;
byte state = 0;
byte tarBrightness = 255;
byte curBrightness = 0;
int val;
int dimstate;
byte zcState = 0; // 0 = ready; 1 = processing;
void zcDetectISR();
void dimTimerISR();
IPAddress ip(192, 168, 1, 80);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
/************************* WiFi Access Point *********************************/
#define WLAN_SSID "xxxxx"
#define WLAN_PASS "xxxxxx"
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER "xxxxxx" //IP address of RPi
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME ""
#define AIO_KEY ""
/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient esp8client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;
const char MQTT_CLIENTID[] PROGMEM = "Test Dimmer";
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&esp8client, AIO_SERVER, AIO_SERVERPORT,MQTT_CLIENTID, AIO_USERNAME, AIO_KEY);
/****************************** Feeds ***************************************/
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe testspeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/testspeed");
Adafruit_MQTT_Subscribe testswitch = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/testswitch");
/*************************** Sketch Code ************************************/
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();
//Servo myservo;
void ICACHE_RAM_ATTR setup() {
Serial.begin(115200);
EEPROM.begin(4);
delay(10);
pinMode(zcPin, INPUT_PULLUP);
pinMode(pwmPin, OUTPUT);
pinMode(led, OUTPUT);
attachInterrupt(zcPin, zcDetectISR, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
hw_timer_init(NMI_SOURCE, 0);
hw_timer_set_func(dimTimerISR);
digitalWrite(led, 1);
Serial.print("Fan/Light MQTT Dimmer");
tarBrightness = EEPROM.read(0);
Serial.println(tarBrightness);
state = EEPROM.read(1);
Serial.println(state);
// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.config(ip, gateway, subnet); // forces to use the fix IP
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Setup MQTT subscription for onoff feed.
mqtt.subscribe(&testswitch);
mqtt.subscribe(&testspeed);
}
uint32_t x = 0;
void ICACHE_RAM_ATTR loop() {
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();
// this is our 'wait for incoming subscription packets' busy subloop
// try to spend your time here
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(20000))) {
if (subscription == &testswitch) {
Serial.print(F("On-Off button: "));
Serial.println((char *)testswitch.lastread);
if (strcmp((char *)testswitch.lastread, "0") == 0) {
digitalWrite(led, 0);
state = 1;
EEPROM.write(1, state);
EEPROM.commit();
}
if (strcmp((char *)testswitch.lastread, "1") == 0) {
digitalWrite(led, 1);
state = 0;
EEPROM.write(1, state);
EEPROM.commit();
}
}
if (subscription == &testspeed) {
Serial.print(F("Slider 2: "));
Serial.println((char *)testspeed.lastread);
val = atoi((char *)testspeed.lastread); // convert to a number
if ((val>0) && (state == 1)){
tarBrightness =val;
EEPROM.write(0, tarBrightness);
EEPROM.commit();
Serial.println(tarBrightness);
}
else{
state = 0;
}
}
}
// ping the server to keep the mqtt connection alive
// NOT required if you are publishing once every KEEPALIVE seconds
if(! mqtt.ping()) {
mqtt.disconnect();
}
}
void ICACHE_RAM_ATTR dimTimerISR() {
if (fade == 1) {
if (curBrightness > tarBrightness || (state == 0 && curBrightness > 0)) {
--curBrightness;
}
else if (curBrightness < tarBrightness && state == 1 && curBrightness < 255) {
++curBrightness;
}
}
else {
if (state == 1) {
curBrightness = tarBrightness;
}
else {
curBrightness = 0;
}
}
if (curBrightness == 0) {
state = 0;
digitalWrite(pwmPin, 0);
}
else if (curBrightness == 255) {
state = 1;
digitalWrite(pwmPin, 1);
}
else {
digitalWrite(pwmPin, 1);
}
zcState = 0;
}
void ICACHE_RAM_ATTR zcDetectISR() {
if (zcState == 0) {
zcState = 1;
if (curBrightness < 255 && curBrightness > 0) {
digitalWrite(pwmPin, 0);
int dimDelay = 30 * (255 - curBrightness) + 400;//400
hw_timer_arm(dimDelay);
Serial.println(dimDelay);
}
}
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
I think when it tries to call EEPROM.Commit function light glows and when I remove this function light behaves normally but state does not save.
EEPROM.Commit funtion is like...
Code: Select all
bool EEPROMClass::commit() {
bool ret = false;
if (!_size)
return false;
if(!_dirty)
return true;
if(!_data)
return false;
noInterrupts();
if(spi_flash_erase_sector(_sector) == SPI_FLASH_RESULT_OK) {
if(spi_flash_write(_sector * SPI_FLASH_SEC_SIZE, reinterpret_cast<uint32_t*>(_data), _size) == SPI_FLASH_RESULT_OK) {
_dirty = false;
ret = true;
}
}
interrupts();
return ret;
}
Please guide me the proper way to save the last state and Last Brightness of MQTT Dimmer.