//#define BLYNK_DEBUG // Optional, this enables lots of prints //#define BLYNK_PRINT Serial #include #include //Software i2C library for ESP8266 #include #include #include // BLYNK --------------------------------------- #include #include #include #define DEST_I2C_ADDR 0x09 //5 set destination I2C address (must match firmware in Colorduino module) #define TIME_TO_CONFIG 4000 //number of milliseconds to set config mode #define TIME_TO_CLOCK 2000 //number of milliseconds to set clock mode #define CYCLE_TIME 250 //number of milliseconds of particles cycles #define BOXMODE_CYCLE_TIME 300000 //number of milliseconds to cycle between effects boxmodes (not for clock mode) #define SERVER_TIMEOUT 3500 //number of milliseconds server connection timeout (SCT) #define WIFI_TIMEOUT 10000 //number of milliseconds WiFi connection timeout (WCT) #define BLYNK_INTERVAL 600000 //number of milliseconds check server frequency (CSF) /* USED PINS D0 GPIO16 - D1 GPIO05 SDA D2 GPIO04 SCL D3 GPIO00 - D5 GPIO14 BUZZER D6 GPIO12 - D7 GPIO13 - D8 GPIO15 TOUCH */ int SDAPin = D2; int SCLPin = D1; int buzzPin = D5; int touchPin = D8; // Var init boolean touched = false; // Touch button status byte boxMode = 0; // Mode-Function shown on RGB Matrix unsigned long startseconds,nowseconds; // alarm set time in seconds, current time in seconds unsigned long alarmHour,alarmMinute; // alarm set time Hours and Minutes String terminalCmd,msg,writeTxt; boolean alarmTrigger,alarmStatus,colorChange; unsigned int BlynkR,BlynkG,BlynkB,particleColor,i,txtSpeed; byte dataArray[]={0}; unsigned long timeInit1, timeInit2, colortimeInit1,startCicleTime,startWiFi; WidgetRTC rtc; BlynkTimer timer; WidgetTerminal terminal(V9); ESP8266WebServer server(80); WiFiClient espClient; //Blynk Auth Token char auth[] = "84xxxa7dxxxe4axxxbbbxxxe5dfbaxx"; //Write your auth token //AP Mode Credentials. IP: 192.168.4.1 char ssidAP[] = "RGBBox"; char passAP[] = ""; // Your WiFi credentials. Set password to "" for open networks. char ssid[25] = ""; char pass[25] = ""; char txtRGBBox[25]=""; //CONFIGURATION WEBPAGE CODE String webpage = "" "" "" "RGBBOX Connection" "" "" "" "" "
" "SSID:

" "
" "PASSWORD:

" "

" "

" "
"; String endWebpage = ""; //CONFIGURATION WEBPAGE CODE SEND void confPage() { server.send(200, "text/html", webpage + msg + endWebpage); } void save_conf() { writeEEPROM(0,server.arg("ssid")); writeEEPROM(25,server.arg("pass")); msg = "SSID and Password Saved..."; readEEPROM(0).toCharArray(ssid, 25); readEEPROM(25).toCharArray(pass, 25); confPage(); } void writeEEPROM(int addr, String a) { int varSize = a.length(); char inchar[25]; a.toCharArray(inchar, varSize+1); for (int i = 0; i < varSize; i++) { EEPROM.write(addr+i, inchar[i]); } for (int i = varSize; i < 25; i++) { EEPROM.write(addr+i, 255); } EEPROM.commit(); } String readEEPROM(int addr) { byte reading; String strRead; for (int i = addr; i < addr+25; i++) { reading = EEPROM.read(i); if (reading != 255) { strRead += (char)reading; } } return strRead; } byte sendI2CArray(byte addr, byte data[], byte answerI2C=9) { Wire.beginTransmission(addr); Wire.write(data, 32); answerI2C = Wire.endTransmission(true); delay(100); return(answerI2C); } BLYNK_CONNECTED(){ terminal.println("BLYNK HAS BEEN CONNECTED!"); Blynk.syncVirtual(V3,V0); if(startseconds!=99999)Blynk.syncVirtual(V2); rtc.begin(); boxMode = 0; } void setup() { Serial.begin(9600); delay(1000); EEPROM.begin(512); Serial.println("READING EEPROM DATA..."); readEEPROM(0).toCharArray(ssid, 25); readEEPROM(25).toCharArray(pass, 25); readEEPROM(50).toCharArray(txtRGBBox, 25); Serial.println(ssid); Serial.println(pass); Serial.println(txtRGBBox); delay(300); Serial.println("CONNECTING WIFI..."); WiFi.mode(WIFI_STA); timer.setInterval(BLYNK_INTERVAL, checkBlynk); // check connection to server per BLYNK_INTERVAL startWiFi = millis(); startCicleTime = millis(); Blynk.config(auth); while (WiFi.status() != WL_CONNECTED){ Serial.println(ssid); Serial.println(pass); WiFi.begin(ssid, pass); delay(1000); if(millis() > startWiFi + WIFI_TIMEOUT){ Serial.println("\tNO WIFI CONNECTION!"); break; } } if(WiFi.status() == WL_CONNECTED)Blynk.connect(); Serial.println("RTC CLOCK STARTED..."); rtc.begin(); setSyncInterval(10 * 60); // Sync interval in seconds (10 minutes) Serial.println("I2C STARTED..."); Wire.begin(SDAPin,SCLPin); Wire.setClockStretchLimit(15000); // This is a critical parameter for i2C good comm Serial.println("PINMODE DEFINITION..."); pinMode(touchPin, INPUT_PULLUP); pinMode(buzzPin, OUTPUT); Serial.println("DEFAULT VALUES..."); alarmTrigger = false; alarmStatus = false; colorChange = false; touched = false; txtSpeed=20; BlynkR = 125; BlynkG = 125; BlynkB = 125; Serial.println("SETUP FINISHED!"); } void checkBlynk() { if (WiFi.status() == WL_CONNECTED) { unsigned long startConnecting = millis(); while(!Blynk.connected()){ Blynk.connect(); if(millis() > startConnecting + SERVER_TIMEOUT){ Serial.print("Unable to connect to server. "); break; } } if(Blynk.connected()){ Serial.println("SYNCING BLYNK..."); Blynk.syncVirtual(V3,V0); if(startseconds!=99999)Blynk.syncVirtual(V2); } } if (WiFi.status() != 3) { Serial.print("\tNo WiFi. "); WiFi.mode(WIFI_OFF); delay(1000); WiFi.mode(WIFI_STA); WiFi.begin(ssid, pass); WiFi.printDiag(Serial); delay(5000); } Serial.printf("\tCHEKING AGAIN IN %is.\n", BLYNK_INTERVAL / 1000); Serial.println(); } // Blynk Speed parameter BLYNK_WRITE(V0){ txtSpeed = param.asInt(); } // Blynk Alarm Setup BLYNK_WRITE(V2){ TimeInputParam t(param); if (t.hasStartTime()) { // start time alarmHour = t.getStartHour(); alarmMinute = t.getStartMinute(); startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60); Serial.println(String("Start: ") + t.getStartHour() + ":" + t.getStartMinute() + ":" + t.getStartSecond()); Serial.println(String("Comp: ") + startseconds + "-" + nowseconds); } } // Blynk Alarm Enabled/Disabled BLYNK_WRITE(V3) { if (param.asInt()) { //HIGH alarmStatus = true; } else { //LOW alarmStatus = false; } } // Blynk RGB Color Selection BLYNK_WRITE(V4) { BlynkR = param[0].asInt(); BlynkG= param[1].asInt(); BlynkB = param[2].asInt(); boxMode = 6; byte dataArray[4]; dataArray[0]=6; dataArray[1]=BlynkR; dataArray[2]=BlynkG; dataArray[3]=BlynkB; sendI2CArray(DEST_I2C_ADDR,dataArray); } //Blynk Terminal Writing BLYNK_WRITE(V9) { terminalCmd = getValue(param.asStr(),' ',0); if (String("help") == terminalCmd) { terminal.println("RGBBOX COMMANDS"); terminal.println("---------------"); terminal.println("Config > Show current WIFI ssid and password"); terminal.println("Token > Show current Token key for Blynk server"); terminal.println("Alarm > Alarm values"); terminal.println("Write > Write something to RGBBox (max. 15 chars)"); } if (String("Config") == terminalCmd) { terminal.println("WIFI PARAMS"); terminal.println("-----------"); terminal.print("SSID:");terminal.println(ssid); terminal.print("PASS:");terminal.println(pass); } if (String("Token") == terminalCmd) { terminal.print("Token: ");terminal.print(auth); } if (String("Alarm") == terminalCmd) { terminal.print("Alarm time is: ");terminal.println(String(alarmHour) + ":" + String(alarmMinute)); } if (String("Write") == terminalCmd) { writeTxt = param.asStr(); writeTxt.remove(0,5); writeTxt += "~"; writeTxt.remove(24); writeEEPROM(50,writeTxt); terminal.println("Writing text... >> "); terminal.print(writeTxt); boxMode=2; } } void handleRoot(){ server.send(200, "text/html", webpage + endWebpage); } void wifiAPMode() { if(boxMode!=9){ boxMode = 9; Serial.print("ENTERING WIFI AP_MODE..."); WiFi.mode(WIFI_AP_STA); WiFi.softAP(ssidAP, passAP); Serial.println(); Serial.print("Server IP address: "); Serial.println(WiFi.softAPIP()); Serial.print("Server MAC address: "); Serial.println(WiFi.softAPmacAddress()); server.on("/save_conf", save_conf); server.on("/", handleRoot); server.begin(); Serial.println("Server listening"); analogWrite(buzzPin, 255); delay(75); analogWrite(buzzPin, 0); delay(1000); } } void loop() { server.handleClient(); if (Blynk.connected()) { Blynk.run(); }else{ if(boxMode!=9){ boxMode = 10; delay(1000); checkBlynk(); } } byte dataArray[32]; timer.run(); // BoxMode Effects auto change --------------------------------- if((millis() > (startCicleTime + BOXMODE_CYCLE_TIME))&&(boxMode<2)){ if(boxMode==1){ boxMode = 0; }else{ boxMode++; } startCicleTime = millis(); } // Alarm management -------------------------------------------- nowseconds = ((hour() * 3600) + (minute() * 60) + second()); if(nowseconds<2)Blynk.syncVirtual(V2);; if(startseconds5){ boxMode = 0; }else{ boxMode++; } } if (touchValue && touched){ //Serial.println(millis()-timeInit1); if(millis() >(timeInit1+TIME_TO_CLOCK)){ boxMode= 7; } if(millis() >(timeInit1+TIME_TO_CONFIG)){ wifiAPMode(); } } if (!touchValue){ touched = false; } //-------------------------------------------------------------- // RGBBox Mode Management -------------------------------------- //Serial.print("boxMode: "); Serial.println(boxMode); switch (boxMode) { case 0: // Plasma dataArray[0] = 0; dataArray[1] = txtSpeed/10; sendI2CArray(DEST_I2C_ADDR,dataArray); break; case 1: // Particles 1 if(!colorChange){ colorChange = true; colortimeInit1 = millis(); }else{ if(millis()>colortimeInit1+CYCLE_TIME){ particleColor++; colorChange = false; } } dataArray[0] = 1; dataArray[1] = particleColor; dataArray[2] = txtSpeed/10; sendI2CArray(DEST_I2C_ADDR,dataArray); delay(250); break; case 2: // Text Show1 readEEPROM(50).toCharArray(txtRGBBox, 25); dataArray[0] = 2; dataArray[1] = BlynkR;; dataArray[2] = BlynkG; dataArray[3] = BlynkB; dataArray[4] = txtSpeed; i=0; while(txtRGBBox[i]!=126){ dataArray[5+i] = txtRGBBox[i]; i++; } dataArray[5+i] = 126; sendI2CArray(DEST_I2C_ADDR,dataArray); break; case 3: // Nothing //dataArray[0] = 3; //sendI2CArray(DEST_I2C_ADDR,dataArray); boxMode++; break; case 4: // Nothing //dataArray[0] = 4; //sendI2CArray(DEST_I2C_ADDR,dataArray); boxMode++; break; case 5: // Nothing //dataArray[0] = 5; //sendI2CArray(DEST_I2C_ADDR,dataArray); boxMode++; break; case 6: // Full RGB Color mode, with Blynk selection if(!alarmTrigger)Blynk.syncVirtual(V4); break; case 7: // Clock dataArray[0] = 7; dataArray[1] = hour(); dataArray[2] = minute(); dataArray[3] = second(); sendI2CArray(DEST_I2C_ADDR,dataArray); delay(10); break; case 8: // Alarm dataArray[0] = 8; sendI2CArray(DEST_I2C_ADDR,dataArray); break; case 9: // Mode AP to config WIFI with ESP8266 web server dataArray[0] = 9; sendI2CArray(DEST_I2C_ADDR,dataArray); wifiAPMode(); break; case 10:// No Blynk connection warn if(dataArray[0] != 10){ dataArray[0] = 10; sendI2CArray(DEST_I2C_ADDR,dataArray); } break; } //-------------------------------------------------------------- terminal.flush(); delay(100); } String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = {0, -1}; int maxIndex = data.length()-1; for(int i=0; i<=maxIndex && found<=index; i++){ if(data.charAt(i)==separator || i==maxIndex){ found++; strIndex[0] = strIndex[1]+1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found>index ? data.substring(strIndex[0], strIndex[1]) : ""; }