#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...
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.