//--------------------------------------------------------- //Orignal code functions // Toggle the relay on void RelayOn() { if (!resetRequired) { digitalWrite( RELAY, HIGH ); relayState = true; Blynk.virtualWrite( V0, HIGH ); // Sync the Blynk button widget state Blynk.virtualWrite( V1, relayState*255 ); } } // Toggle the relay off void RelayOff() { digitalWrite( RELAY, LOW ); relayState = false; Blynk.virtualWrite( V0, LOW ); // Sync the Blynk button widget state Blynk.virtualWrite( V1, relayState*255 ); } /* // Handle switch changes originating on the Blynk app BLYNK_WRITE( V0 ) { int SwitchStatus = param.asInt(); if ( SwitchStatus ) RelayOn(); else RelayOff(); } */ // Handle hardware switch activation. void ButtonCheck() { // look for new button press boolean SwitchState = ( digitalRead( SWITCH ) ); // toggle the switch if there's a new button press if ( !SwitchState && SwitchReset == true ) { if ( relayState ) RelayOff(); else RelayOn(); // Flag that indicates the physical button hasn't been released SwitchReset = false; delay( 50 ); // De-bounce interlude. relayOveride = true; //If button is used, overide the temperature control Blynk.virtualWrite(V59,relayOveride); //Feedback to the app } else if ( SwitchState ) { // reset flag the physical button release SwitchReset = true; } } // Relay toggle helper function. void ToggleRelay() { relayState = !relayState; if ( relayState ) RelayOn(); else RelayOff(); } // CSE7766 checksum. bool CheckSum() { unsigned char checksum = 0; for (unsigned char i = 2; i < 23; i++) checksum += serialBuffer[i]; return checksum == serialBuffer[23]; } // Process a cse7766 data packet. void ProcessCse7766Packet() { // Confirm packet checksum. if ( !CheckSum() ) { error = SENSOR_ERROR_CRC; return; } // Check for calibration error. if ( serialBuffer[0] == 0xAA ) { error = SENSOR_ERROR_CALIBRATION; return; } if ( (serialBuffer[0] & 0xFC) == 0xFC ) { error = SENSOR_ERROR_OTHER; return; } // Retrieve calibration coefficients. unsigned long coefV = (serialBuffer[2] << 16 | serialBuffer[3] << 8 | serialBuffer[4] ); unsigned long coefC = (serialBuffer[8] << 16 | serialBuffer[9] << 8 | serialBuffer[10]); unsigned long coefP = (serialBuffer[14] << 16 | serialBuffer[15] << 8 | serialBuffer[16]); uint8_t adj = serialBuffer[20]; // Calculate voltage. voltage = 0; if ( (adj & 0x40) == 0x40 ) { unsigned long voltageCycle = serialBuffer[5] << 16 | serialBuffer[6] << 8 | serialBuffer[7]; voltage = ratioV*coefV/voltageCycle/CSE7766_V2R; } // Calculate power. power = 0; if ( (adj & 0x10) == 0x10 ) { if ( (serialBuffer[0] & 0xF2) != 0xF2 ) { unsigned long powerCycle = serialBuffer[17] << 16 | serialBuffer[18] << 8 | serialBuffer[19]; power = ratioP*coefP/powerCycle/CSE7766_V1R/CSE7766_V2R; } } // Calculate current. current = 0; if ( (adj & 0x20) == 0x20 ) { if ( power > 0 ) { unsigned long currentCycle = serialBuffer[11] << 16 | serialBuffer[12] << 8 | serialBuffer[13]; current = ratioC*coefC/currentCycle/CSE7766_V1R; } } // Calculate energy. unsigned int difference; static unsigned int cfPulsesLast = 0; unsigned int cfPulses = serialBuffer[21] << 8 | serialBuffer[22]; if (0 == cfPulsesLast) cfPulsesLast = cfPulses; if (cfPulses < cfPulsesLast) difference = cfPulses + (0xFFFF - cfPulsesLast) + 1; else difference = cfPulses - cfPulsesLast; energy += difference*(float)coefP/1000000.0; cfPulsesLast = cfPulses; // Energy reset. if ( power == 0 ) energyResetCounter++; else energyResetCounter = 0; if ( energyResetCounter >= MAX_ENREGY_RESET_COUNT ) { energy = 0.0; energyResetCounter = 0; } // Push data to Blynk app. Blynk.virtualWrite( V3, voltage ); // Voltage (Volts). Blynk.virtualWrite( V4, current ); // Current (Amps). Blynk.virtualWrite( V5, power ); // Power (Watts). Blynk.virtualWrite( V6, energy ); // Energy (kWh). } // Read serial cse7766 power monitor data packet. void ReadCse7766() { // Assume a non-specific error. error = SENSOR_ERROR_OTHER; static unsigned char index = 0; while ( Serial.available() > 0 ) { uint8_t input = Serial.read(); // first byte must be 0x55 or 0xF?. if ( index == 0 ) { if ( (input != 0x55) && (input < 0xF0) ) continue; } // second byte must be 0x5A. else if ( index == 1 ) { if ( input != 0x5A ) { index = 0; continue; } } serialBuffer[index++] = input; if ( index > 23 ) { Serial.flush(); break; } } // Process packet. if ( index == 24 ) { error = SENSOR_ERROR_OK; ProcessCse7766Packet(); index = 0; } // Report error state (LED) of cse7766. if ( error == SENSOR_ERROR_OK ) Blynk.virtualWrite( V18, 0 ); else Blynk.virtualWrite( V18, 255 ); } //--------------------------------- //Basic functions that must run void process() { if (timer(2000,0)) { ReadCse7766(); } if (timer(100,1)) { ButtonCheck(); } } bool cooldownCheck() { if (timerCheck(3) >= cooldownPeriod*1000) { return true; } else { return false; } } #ifdef normalMode //Create normalMode process function void tempProcess() { if (temp.cur < temp.target && relayState == false) { //If colder than set do next check if (cooldownCheck() == true && temp.cur < temp.target - temp.offset) { //If cooldown has passed and temp is below turn on temp, turn on RelayOn(); } } else { if (temp.cur >= temp.target && relayState == true) { RelayOff(); timerReset(3); //Reset cooldown timer when turning off relay } } } #endif #ifdef inverseMode void tempProcess() { if (temp.target < temp.cur && relayState == false) { //If hotter than set do next check if (cooldownCheck() == true && temp.target + temp.offset < temp.cur) { //If cooldown has passed and temp is above turn on temp, turn on RelayOn(); } } else { if (temp.cur <= temp.target && relayState == true) { RelayOff(); timerReset(3); //Reset cooldown timer when turning off relay } } } #endif void configSave() { EEPROM.write(0,1); //Flag for autoload EEPROM.put(3,configVersion); int i=10; EEPROM.put(i,temp.target); i+=sizeof(temp.target); EEPROM.put(i,temp.offset); i+=sizeof(temp.offset); EEPROM.put(i,temp.unit); i+=sizeof(temp.unit); EEPROM.put(i,cooldownPeriod); i+=sizeof(cooldownPeriod); EEPROM.commit(); } void configLoad() { int i=10; EEPROM.get(i,temp.target); i+=sizeof(temp.target); EEPROM.get(i,temp.offset); i+=sizeof(temp.offset); EEPROM.get(i,temp.unit); i+=sizeof(temp.unit); EEPROM.get(i,cooldownPeriod); i+=sizeof(cooldownPeriod); } byte returnConfigVersion() { byte grabbedVersion; EEPROM.get(3,grabbedVersion); return grabbedVersion; } bool overloadCheck() { if (current > 15) { safeLoad = false; return true; timerReset(4); } else { return false; } } void safetyNet() { overloadCheck(); if (!safeLoad && timerCheck(4) >= loadCooldown*1000 && loadAttempt < loadConnectAttempts) { safeLoad = true; loadAttempt++; timerReset(4); timerReset(5); } if (loadAttempt > 0) { if (timerCheck(5) > 30*1000) { //If relay hasn't overloaded for 30 seconds, reset the loadAttempt count loadAttempt = 0; } if (loadAttempt > loadConnectAttempts) { resetRequired = true; } } }