Here is a copy of my code.
I’m waiting for the new iOS version to try some of the new features.
/* V0 - ADJUSTER
* V1 - TEMPERATURE
* V2 - SETPOINT
* V3 - DEADBAND
* V4 - VALUE++
* V5 - VALUE--
* V6 - ADJUST++
* V7 - lOW SET
* V8 - OUTSIDE TEMP
* V9 - LOW HOUR
* V10 - HIGH SET
* V11 - HEATER STATE FOR TREND
* V12 - ELAPSED TIMER
* V13 - HIGH HOUR
* V14 - DIAGNOSTIC CODE
* V15 - DOOR OPERATOR
* V16 - OPERATION
* V17 - DOOR SWITCH
*
* EEPROM0 - SETPOINT
* EEPROM1 - DEADBAND
* EEPROM2 - BOOT
* EEPROM3 - OPERATION
* EEPROM4 - LOW SET
* EEPROM5 - LOW HOUR
* EEPROM6 - HIGH SET
* EEPROM7 - HIGH HOUR
*/
//#define BLYNK_DEBUG
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <Bounce2.h>
#define therm 4
#define door 12
#define door_swt 14
char auth[] = "";
const char* ssid = "High Country";
const char* password = "";
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
const int timeZone = -4; // Eastern Daylight Time (USA)
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
byte Sensor[8] ={0x28,0xFF,0xD0,0x90,0x50,0x14,0x04,0x3A};
byte Outside[8] ={0x28,0xF0,0xAB,0xD6,0x06,0x00,0x00,0xF6};
byte adj = 0;
float temp = 18;
byte set = 15;
byte low_set = 10;
byte low_hr = 21;
byte high_set = 19;
byte high_hr = 6;
float out = 0;
byte db = 2;
boolean heater_state = 0;
String str = "";
byte count = 0;
long start = 0;
long etime = 0;
byte boot;
byte oper = 0;
boolean t_sync = 0;
byte diag = 0;
boolean door_sta;
SimpleTimer timer;
OneWire ds(5);
Bounce debouncer = Bounce();
void updateData(){
switch(count){
case 0: Blynk.virtualWrite(V1,temp);
break;
case 1: Blynk.virtualWrite(V2, set);
break;
case 2: Blynk.virtualWrite(V3, (float)db/10);
break;
case 3: if(heater_state==1){Blynk.virtualWrite(V11, 30);}
else{Blynk.virtualWrite(V11, 0);}
break;
case 4: if(heater_state==0){str = "Off";}
else{etime=((millis()-start)/1000);str=String(etime/60)+":";if(etime%60<10){str+="0";}str+=String(etime%60);}
Blynk.virtualWrite(V12,str);
break;
case 5: diag=0;
if(boot>0){diag+=1;}
if(t_sync==0){diag+=2;}
Blynk.virtualWrite(V14, diag);
break;
case 6: Blynk.virtualWrite(V8, out);
break;
case 7: if(oper==0){str = "Off";}
if(oper==1){str = "Down";}
if(oper==2){str = "U/D";}
Blynk.virtualWrite(V16, str);
break;
case 8: Blynk.virtualWrite(V7, low_set);
break;
case 9: str=String(low_hr)+":00";
Blynk.virtualWrite(V9, str);
break;
case 10: Blynk.virtualWrite(V10, high_set);
break;
case 11: str=String(high_hr)+":00";
Blynk.virtualWrite(V13, str);
break;
case 12: switch(adj){
case 0: str = "SET";break;
case 1: str = "DB";break;
case 2: str = "L_S";break;
case 3: str = "L_H";break;
case 4: str = "H_S";break;
case 5: str = "H_H";break;
case 6: str = "OPER";break;
case 7: str = "RST";break;
}
Blynk.virtualWrite(V0, str);
break;
case 13: if(door_sta==1){str = "CLD";}
else{str = "OPEN";}
Blynk.virtualWrite(V17, str);
break;
}
if(count==13){count=0;}
else{count++;}
debouncer.update();
door_sta = debouncer.read();
}
BLYNK_WRITE(V4){
if(param.asInt()==1){
switch(adj){
case 0: set++;count=1;updateData();break;
case 1: db++;count=2;updateData();break;
case 2: low_set++;count=8;updateData();break;
case 3: if(low_hr==23){low_hr=0;}else{low_hr++;}count=9;updateData();break;
case 4: high_set++;count=10;updateData();break;
case 5: if(high_hr==23){high_hr=0;}else{high_hr++;}count=11;updateData();break;
case 6: if(oper==2){oper=0;}else{oper++;}count=7;updateData();break;
case 7: boot=0;t_sync=0;EEPROM.write(2,boot);EEPROM.commit();count=5;updateData();break;
}}}
BLYNK_WRITE(V5){
if(param.asInt()==1){
switch(adj){
case 0: set--;count=1;updateData();break;
case 1: db--;count=2;updateData();break;
case 2: low_set--;count=8;updateData();break;
case 3: if(low_hr==0){low_hr=23;}else{low_hr--;}count=9;updateData();break;
case 4: high_set--;count=10;updateData();break;
case 5: if(high_hr==0){high_hr=23;}else{high_hr--;}count=11;updateData();break;
case 6: if(oper==0){oper=2;}else{oper--;}count=7;updateData();break;
}}}
BLYNK_WRITE(V6){if(param.asInt()==1){if(adj==7){adj=0;}else{adj++;}count=12;updateData();}}
BLYNK_WRITE(V15){digitalWrite(door, param.asInt());}
float getTemp(byte add[8]){
byte i, dat;
byte data[12];
ds.reset();
ds.select(add);
ds.write(0x44,1);
dat = ds.read();
while (!dat){
dat = ds.read();}
dat = ds.reset();
ds.select(add);
ds.write(0xBE);
for ( i = 0; i < 9; i++) {
data[i] = ds.read();}
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
return (float)raw / 16.0;
}
void init_temp(byte add[8]){
ds.reset();
ds.select(add);
ds.write(0x4E); // Write scratchpad
ds.write(0); // TL
ds.write(0); // TH
ds.write(0x3F); // Configuration Register 12bit=0X7F 11bit=0X5F 10bit= 0X3F
ds.write(0x48);
}
void read_in(){
temp=getTemp(Sensor)-2;
if((temp>=set||door_sta==0)&&heater_state==1){heater_state=0;digitalWrite(therm,LOW);}
if(temp<=(set-(float)db/10)&&heater_state==0&&door_sta==1){heater_state=1;digitalWrite(therm,HIGH);start=millis();}
}
void read_out(){
out=getTemp(Outside);
}
void mem(){
boolean s = 0;
if(set!=EEPROM.read(0)){EEPROM.write(0,set);s=1;}
if(db!=EEPROM.read(1)){EEPROM.write(1,db);s=1;}
if(oper!=EEPROM.read(3)){EEPROM.write(3,oper);s=1;}
if(low_set!=EEPROM.read(4)){EEPROM.write(4,low_set);s=1;}
if(low_hr!=EEPROM.read(5)){EEPROM.write(5,low_hr);s=1;}
if(high_set!=EEPROM.read(6)){EEPROM.write(6,high_set);s=1;}
if(high_hr!=EEPROM.read(7)){EEPROM.write(7,high_hr);s=1;}
if(s==1){EEPROM.commit();}
}
void clockDisplay(){
BLYNK_LOG("Current time: %02d:%02d:%02d %02d %02d %d",
hour(), minute(), second(),
day(), month(), year());
if(t_sync==1){
if(oper!=0&&hour()>=low_hr&&set!=low_set){set=low_set;}
if(oper==2&&hour()>=high_hr&&hour()<low_hr&&set!=high_set){set=high_set;}
}
}
void setup(){
Serial.begin(9600);
EEPROM.begin(8);
set=EEPROM.read(0);
db=EEPROM.read(1);
oper=EEPROM.read(3);
boot=EEPROM.read(2);
low_set=EEPROM.read(4);
low_hr=EEPROM.read(5);
high_set=EEPROM.read(6);
high_hr=EEPROM.read(7);
boot++;
EEPROM.write(2,boot);
EEPROM.commit();
Blynk.begin(auth, ssid, password);
while (Blynk.connect() == false) {}
Serial.print("IP number assigned by DHCP is ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(3600);
timer.setInterval(500000L, clockDisplay);
timer.setInterval(1250L, read_in);
timer.setInterval(250L, updateData);
timer.setInterval(300000L, mem);
timer.setInterval(10000L, read_out);
init_temp(Sensor);
init_temp(Outside);
pinMode(therm, OUTPUT);
digitalWrite(therm, LOW);
pinMode(door, OUTPUT);
digitalWrite(door, LOW);
pinMode(door_swt,INPUT_PULLUP);
debouncer.attach(door_swt);
debouncer.interval(1000); // interval in ms
read_in();
read_out();
}
void loop(){
Blynk.run();
timer.run(); // Initiates SimpleTimer
}
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime(){
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
t_sync=0;
sendNTPpacket(timeServer);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
t_sync=1;
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address){
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}