Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdint.h>
- #include <ESP8266WiFi.h>
- #include <WiFiUdp.h>
- #include <Time.h>
- #include <EEPROM.h>
- extern "C" {
- #include "user_interface.h"
- }
- //PINs definition
- #define WOK_PIN 14 //WiFi status led
- #define RLY_PIN 4 //Relay+led (Pompa ricircolo)
- #define LED_PIN 5 //Led (Pompa scarico)
- #define MOD_PIN 0 //Mode switch (0 -> fw update/debug, 1 -> normal operation)
- #define DEBUG_PUMP_PERIOD_SEC 10 //How long pump stays on (seconds)
- #define TIMEZONE 1 //Timezone (Rome UTC+1)
- #define TIME_SYNC_INTERVAL 24*60*60 //Interval between two internet time sync (seconds)
- #define SHORT_TIME_SYNC_INTERVAL 5*60
- #define MAX_SYNC_TRIES 5 //Maximum time sync tries before give up
- //UDP send/receive settings
- WiFiUDP udp_handle;
- WiFiUDP udp_log_handle;
- WiFiUDP udp_time_handle;
- unsigned int udp_port = 4200;
- char udp_buffer[255];
- int udp_size;
- int udp_len;
- unsigned int udp_log_port = 4201;
- unsigned int udp_time_port = 4202;
- IPAddress udp_timeserver_ip(192,168,1,101);
- IPAddress udp_logserver_ip(192,168,1,101);
- //UDP commands/reply
- char command_start[] = "START";
- char command_stop[] = "STOP";
- char command_toggle[] = "TOGGLE";
- char command_status[] = "STATUS";
- char command_debug[] = "DEBUG";
- char reply_roger[] = "ROGER";
- char reply_err[] = "ERR";
- char period_set_char = 0x80; //Command to set pump period duration
- char count_reset_char = 0x81; //Command to reset total pump count
- char valid_udp_time = 0x82;
- uint8_t reply_roger_len = 5;
- uint8_t PUMP_PERIOD_SEC; //How long pump stays on (seconds) 0-255
- uint16_t PUMP_COUNT; //Total count of pump use
- //Timer handle
- os_timer_t tmr_handle;
- //Timestamps
- uint32_t tmst = 0; //Internal timestamp
- uint32_t stop_tmst = 0; //When stop the pump
- uint32_t boot_tmst = 0; //Last boot timestamp
- uint32_t last_sync_tmst = 0; //Last time sync
- uint32_t next_sync_tmst = 0; //Next time sync
- uint32_t last_hot_pump_tmst = 0; //Last time hot pump started
- int flag_every_sec_routine = 0;
- void every_sec(void *pArg) { //Increments the timestamp every second
- tmst++;
- flag_every_sec_routine = 1;
- }
- void every_sec_routine(){
- if(tmst>next_sync_tmst) sync_time();
- flag_every_sec_routine = 0;
- }
- void setup() {
- //IO settings
- pinMode(WOK_PIN,OUTPUT);
- pinMode(RLY_PIN,OUTPUT);
- pinMode(LED_PIN,OUTPUT);
- pinMode(MOD_PIN,INPUT);
- //Serial settings and welcome message
- Serial.begin(115200);
- Serial.println("\nBooted into normal mode");
- //WiFi connection
- Serial.println("Started V2...");
- Serial.print("Connecting... ");
- WiFi.enableAP(0);
- WiFi.hostname("ESP_Cantina");
- IPAddress ip(192, 168, 1, 100);
- IPAddress gateway(192, 168, 1, 1); // set gateway to match your network
- IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your
- WiFi.config(ip, gateway, subnet);
- WiFi.begin("EIR-0366", "69449390076557713985");
- while(WiFi.status() != WL_CONNECTED) {digitalWrite(WOK_PIN,!digitalRead(WOK_PIN)); delay(200);}
- Serial.print("Connected: IP address: ");
- Serial.println(WiFi.localIP());
- //EEprom init
- EEPROM.begin(512); //512 byte eeprom
- load_EEPROM_conf();
- udp_time_handle.begin(udp_time_port);
- sync_time();
- boot_tmst = tmst;
- //Set the timer for increment the timstamp every second
- os_timer_setfn(&tmr_handle, every_sec, NULL);
- os_timer_arm(&tmr_handle, 1000, true);
- //Start listening for UDP packets
- udp_handle.begin(udp_port);
- }
- void loop() {
- while(1){ //Main loop
- ESP.wdtFeed(); //Reset watchdog
- if(flag_every_sec_routine) every_sec_routine();
- if(WiFi.status() == WL_CONNECTED) digitalWrite(WOK_PIN,HIGH); else digitalWrite(WOK_PIN, LOW); //WiFi led ok
- //Controlla se ha ricevuto pacchetti UDP
- udp_size = udp_handle.parsePacket();
- if(udp_size) udp_received();
- //Ferma la pompa quando necessario
- if(digitalRead(RLY_PIN) && (tmst > stop_tmst)) digitalWrite(RLY_PIN,LOW);
- yield();
- }
- }
- void udp_received() { //Routine che viene chiamata in caso di ricezione di pacchetti
- delay(10);
- udp_len = udp_handle.read(udp_buffer,255);
- if(udp_len>0){
- udp_buffer[udp_len] = '\0'; //Inserisco il terminatore alla fine
- //Parsing del comando
- if(!strcmp(udp_buffer,command_start)) {
- if((!digitalRead(RLY_PIN)) && (!debug())) {
- uint16_t tmp = PUMP_COUNT+1;
- while(PUMP_COUNT != tmp) {
- set_EEPROM_count(tmp);
- delay(10);
- load_EEPROM_conf();
- }
- sprintf(udp_buffer,"%lu\n",tmst);
- udp_log_handle.beginPacket(udp_logserver_ip,udp_log_port);
- udp_log_handle.write(udp_buffer);
- udp_log_handle.endPacket();
- }
- digitalWrite(RLY_PIN,HIGH);
- if(!debug()) last_hot_pump_tmst = tmst;
- strcpy(udp_buffer,reply_roger);
- if(debug()){
- stop_tmst = tmst + DEBUG_PUMP_PERIOD_SEC;
- udp_buffer[reply_roger_len] = DEBUG_PUMP_PERIOD_SEC;
- } else {
- stop_tmst = tmst + PUMP_PERIOD_SEC;
- udp_buffer[reply_roger_len] = PUMP_PERIOD_SEC;
- }
- udp_buffer[reply_roger_len+1] = '\0';
- udp_send(udp_buffer,udp_handle.remoteIP());
- } else if (!strcmp(udp_buffer,command_stop)) {
- digitalWrite(RLY_PIN,LOW);
- udp_send(reply_roger,udp_handle.remoteIP());
- } else if (!strcmp(udp_buffer,command_debug)) {
- //Format: utc_timestamp;local_timestamp;last_boot;last_sync;hot_water_pump_status
- Serial.print("Received DEBUG command from ");
- Serial.println(udp_handle.remoteIP());
- sprintf(udp_buffer,"%lu;%lu;%lu;%lu;%d;%lu;%u;%u",tmst,local_time(tmst),local_time(boot_tmst),local_time(last_sync_tmst),digitalRead(RLY_PIN),local_time(last_hot_pump_tmst),PUMP_PERIOD_SEC,PUMP_COUNT);
- udp_send(udp_buffer,udp_handle.remoteIP());
- } else if (udp_buffer[0] == period_set_char) {
- uint8_t tmp;
- tmp = udp_buffer[1];
- while(PUMP_PERIOD_SEC != tmp) {
- set_EEPROM_period(tmp);
- delay(10);
- load_EEPROM_conf();
- }
- udp_send(reply_roger,udp_handle.remoteIP());
- } else if (udp_buffer[0] == count_reset_char) {
- uint16_t tmp;
- tmp = (udp_buffer[1]<<8) + udp_buffer[2];
- while(PUMP_COUNT != tmp) {
- set_EEPROM_count(tmp);
- delay(10);
- load_EEPROM_conf();
- }
- udp_send(reply_roger,udp_handle.remoteIP());
- } else {
- udp_send(reply_err,udp_handle.remoteIP());
- }
- }
- }
- void udp_send(char *message, IPAddress ip){
- udp_handle.beginPacket(ip,udp_port);
- udp_handle.write(message);
- udp_handle.endPacket();
- }
- void sync_time(){ //sync system time with internet
- uint16_t l,i = millis();
- bool timeset = false;
- char str_buff[255];
- Serial.println("Requested time sync");
- udp_time_handle.beginPacket(udp_timeserver_ip,udp_time_port);
- udp_time_handle.write("TMRQ");
- udp_time_handle.endPacket();
- while(((millis()-i) < 5000) && (timeset == false)){
- l = udp_time_handle.parsePacket();
- if(l){
- udp_len = udp_time_handle.read(udp_buffer,16);
- if(udp_len > 0){
- //sprintf(str_buff,"\nRECV: %x | %x %x %x %x | %x\n",udp_buffer[0],udp_buffer[1],udp_buffer[2],udp_buffer[3],udp_buffer[4],udp_buffer[5]);
- //Serial.printf(str_buff);
- if(udp_buffer[0] == valid_udp_time){
- tmst = udp_buffer[1]<<24 | udp_buffer[2]<<16 | udp_buffer[3]<<8 | udp_buffer[4];
- Serial.println("Time set!");
- timeset=true;
- last_sync_tmst = tmst;
- next_sync_tmst = tmst + TIME_SYNC_INTERVAL;
- if(boot_tmst < 10000){
- boot_tmst = tmst;
- }
- }
- }
- }
- yield();
- }
- if(!timeset) {
- next_sync_tmst = tmst + SHORT_TIME_SYNC_INTERVAL;
- Serial.println("Giveup :(");
- }
- }
- uint32_t local_time(uint32_t UTC) { //give UTC time gives the local time
- return UTC + (TIMEZONE + is_DST(UTC))*3600;
- }
- int is_DST(uint32_t t){ //return 1 if DST is in use in t timestamp, 0 otherwise
- tmElements_t DST_start, DST_end;
- uint32_t DST_start_t, DST_end_t;
- DST_start.Second = 0;
- DST_start.Minute = 0;
- DST_start.Hour = 1;
- DST_start.Year = year(t) - 1970;
- DST_end = DST_start;
- DST_start.Month = 3; DST_end.Month = 10;
- DST_start.Day = (31-((((5*year(t))/4)+4)%7));
- DST_end.Day = (31-((((5*year(t))/4)+1)%7));
- DST_start_t = (uint32_t) makeTime(DST_start);
- DST_end_t = (uint32_t) makeTime(DST_end);
- if( (t > DST_start_t) && (t < DST_end_t) ) return 1;
- return 0;
- }
- //EEPROM fun
- /*
- * ADDR DESC
- *
- * 0 Pump interval (seconds)
- * 1 Pump count (msb)
- * 2 Pump count (lsb)
- */
- void load_EEPROM_conf() {
- PUMP_PERIOD_SEC = EEPROM.read(0);
- PUMP_COUNT = (EEPROM.read(1))<<8 | EEPROM.read(2);
- }
- void set_EEPROM_count(uint16_t count) {
- EEPROM.write(2, count & 0xFF);
- EEPROM.write(1, count>>8);
- EEPROM.commit();
- }
- void set_EEPROM_period(uint8_t period) {
- EEPROM.write(0,period);
- EEPROM.commit();
- }
- boolean debug() {
- return !digitalRead(MOD_PIN);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement