/******************************************************************** * web_server - example code providing a framework that supports * either an http web server or mqtt * * created Jan-6, 2016 by Dave St. Aubin * changed 26.10.2016 by pe * This example code is in the public domain. ********************************************************************/ #include "sketch.h" #include //http server library #include //MQTT server library #include //OTA libraries #include #include #include #include #include #include #include "PAGE_Style.css.h" #include "PAGE_NetworkConfiguration.h" // Include API-Headers extern "C" { //SDK functions for Bertl IDE access #include "ets_sys.h" #include "os_type.h" #include "osapi.h" #include "mem_manager.h" #include "mem.h" #include "string.h" #include "user_interface.h" #include "cont.h" #include "espconn.h" #include "eagle_soc.h" #include void * pvPortZalloc(int size,char *, int); //void * pvPortZalloc(int size); } /******************************************************** * Global Variables ********************************************************/ //----Initial EEPROM Values------// char init_ssid[32] = "cisco"; char init_pass[32] = "ciscoclass"; const char* init_ip0 = "172"; const char* init_ip1 = "16"; const char* init_ip2 = "63"; const char* init_ip3 = "154"; // PE!!! const char* init_nm0 = "255"; const char* init_nm1 = "255"; const char* init_nm2 = "255"; const char* init_nm3 = "0"; const char* init_gw0 = "172"; const char* init_gw1 = "16"; const char* init_gw2 = "63"; const char* init_gw3 = "254"; const char* init_ap0 = "192"; const char* init_ap1 = "168"; const char* init_ap2 = "4"; // PE!!! const char* init_ap3 = "1"; const char* init_port = "80"; // PE!! Port: 8266 const char* init_fota_port = "18266"; const char* init_fota_pass = ""; const char* init_mqtt_port = "1883"; const char* init_bk = "172.16.63.188"; const char* init_ci = MQQT_CLIENT_ID; const char* init_un = ""; const char* init_pw = ""; const char* init_rt = "mqtt_bertl_rx_154"; const char* init_tt = "mqtt_bertl_tx_154"; const char* init_bd = "9600"; const char* init_sr = "true"; const char* init_mqpwen = "false"; String mqtt_svr = ""; String mqtt_ci = ""; String mqtt_un = ""; String mqtt_pw = ""; String mqtt_rt = ""; String mqtt_tt = ""; bool bertl_server =false; bool mqtt_pw_enable =false; int http_port; int mqtt_port; int serial_baud; int timezone = 0; int dst = 0; //SerialEvent String SerialInString; bool NewSerialLineRx=false; int active_svr_rqst=SVR_NONE; long start_wait=0; long lastMsg = 0; uint32_t state=0; int initRx=0; int stoprepub = 0; int sz,blinkarg[4]; static int busy=0; float Ain; char Ain0[20],Ain1[20],Ain2[20],Ain3[20],Ain4[20],Ain5[20],Ain6[20],Ain7[20]; bool complete=false; int lc=0; int wifi=99; //sdk web server char *precvbuffer; static uint32 dat_sumlength = 0; bool httpsend_ready = true; /******************************************************** * Local Function Prototypes ********************************************************/ void SetEepromCfg(void *arg); void SetSysCfgFromEeprom(void); void InitEepromValues(void); void printEEprom(void); void SetEepromAscii(void *arg, int index, int eeprom_offset); void GetEepromCfg(String *page); void SetCfgPageWithEepromVal(String *page, String par, int offset, int fmt); void GetEepromVal(String *val,int offset, int fmt); void SetEepromVal(char *val,int offset, int fmt); void SdkWebServer_Init(int port); void SdkWebServer_listen(void *arg); void SdkWebServer_recv(void *arg, char *pusrdata, unsigned short length); void SdkWebServer_discon(void *arg); void SdkWebServer_recon(void *arg, sint8 err); void SdkWebServer_senddata(void *arg, bool responseOK, char *psend, char *contenttype); bool SdkWebServer_savedata(char *precv, uint16 length); void SdkWebServer_parse_url_params(char *precv, URL_Param *purl_param); void SdkWebServer_sent_cb(void *arg); void util_printStatus(char * status, int s); void util_startWIFI(void); void jsonEncode(int pos, String * s, String key, String val); void jsonAdd(String *s, String key,String val); void MqttServer_Init(void); void MqttServer_reconnect(void); void MqttServer_callback(char* topic, byte* payload, unsigned int length); void MqttServer_Processor(void); void Server_ProcessRequest(int servertype, char *payload, char *reply); void Server_ExecuteRequest(int servertype,RQST_Param rparam, String* reply, String BertlRequest); void Server_SendReply(int servertype, int replytype, String payld); void ReadSensors(int interval); void ResetEspTimerCallback(void); void BlinkCallback(int *pArg); void wifi_event_cb(System_Event_t *evt); String BertlSendReceive(String req); void MonitorSerialLine(); /******************************************************** * Instantiate class objects ********************************************************/ WiFiClient espClient; //Create Wifi Client object PubSubClient client(espClient); //Create Mqtt Client object os_timer_t BlinkLedTimer; //Timer to blink LED os_timer_t ResetEspTimer; //Timer to reset Esp8266 struct espconn *ptrespconn; /******************************************************** * Set MQTT Topic Using ESP8266 MAC * * * ********************************************************/ void AddMAC(char * prefix, char * topic) { uint8_t MAC_array[6]; WiFi.macAddress(MAC_array); sprintf(topic,"%s", prefix); for (int i = 0; i < sizeof(MAC_array); ++i){ sprintf(topic,"%s%02x",topic, MAC_array[i]); } } /******************************************************** * URL Parameter Decoder ********************************************************/ int url_decode(char *encoded_str, char *decoded_str) { // While we're not at the end of the string (current character not NULL) while (*encoded_str) { // Check to see if the current character is a % if (*encoded_str == '%') { // Grab the next two characters and move encoded_str forwards encoded_str++; char high = *encoded_str; encoded_str++; char low = *encoded_str; // Convert ASCII 0-9A-F to a value 0-15 if (high > 0x39) high -= 7; high &= 0x0f; // Same again for the low byte: if (low > 0x39) low -= 7; low &= 0x0f; // Combine the two into a single byte and store in decoded_str: *decoded_str = (high << 4) | low; } else { // All other characters copy verbatim *decoded_str = *encoded_str; } // Move both pointers to the next character: encoded_str++; decoded_str++; } // Terminate the new string with a NULL character to trim it off *decoded_str = 0; } /******************************************************** * Update EEPROM configuration * Function: SetEepromCfg(URL_Param *pURL_Param) * * Parameter Description * --------- --------------------------------------- * *pURL_Param pointer to parameters * return no return value ********************************************************/ void SetEepromCfg(void *arg) { int i,j,serserver=0,mqtt_pwen=0; struct URL_Param *pURL_Param = (URL_Param *)arg; char szT[64]; for(i=0;inPar;i++) { if(os_strcmp(pURL_Param->pParam[i], "ssid")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_WIFISSID); } if(os_strcmp(pURL_Param->pParam[i], "password")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_WIFIPASS); } if(os_strcmp(pURL_Param->pParam[i], "fota_pw")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_FOTA_PW); } if(os_strcmp(pURL_Param->pParam[i], "fota_pt")==0) { EEPROM.write(EEPROM_FOTA_PT+1, (uint8_t) (atoi(pURL_Param->pParVal[i])&0xFF)); EEPROM.write(EEPROM_FOTA_PT, (uint8_t) ((atoi(pURL_Param->pParVal[i])>>8)&0xFF)); } if(os_strcmp(pURL_Param->pParam[i], "ip_0")==0) EEPROM.write(EEPROM_WIFI_IP0, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ip_1")==0) EEPROM.write(EEPROM_WIFI_IP1, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ip_2")==0) EEPROM.write(EEPROM_WIFI_IP2, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ip_3")==0) EEPROM.write(EEPROM_WIFI_IP3, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "nm_0")==0) EEPROM.write(EEPROM_WIFI_NM0, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "nm_1")==0) EEPROM.write(EEPROM_WIFI_NM1, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "nm_2")==0) EEPROM.write(EEPROM_WIFI_NM2, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "nm_3")==0) EEPROM.write(EEPROM_WIFI_NM3, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "gw_0")==0) EEPROM.write(EEPROM_WIFI_GW0, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "gw_1")==0) EEPROM.write(EEPROM_WIFI_GW1, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "gw_2")==0) EEPROM.write(EEPROM_WIFI_GW2, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "gw_3")==0) EEPROM.write(EEPROM_WIFI_GW3, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ap_0")==0) EEPROM.write(EEPROM_WIFI_AP0, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ap_1")==0) EEPROM.write(EEPROM_WIFI_AP1, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ap_2")==0) EEPROM.write(EEPROM_WIFI_AP2, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "ap_3")==0) EEPROM.write(EEPROM_WIFI_AP3, (uint8_t) atoi(pURL_Param->pParVal[i])); if(os_strcmp(pURL_Param->pParam[i], "mqtt_bk")==0) SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_BK); if(os_strcmp(pURL_Param->pParam[i], "mqtt_ci")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_CI); } if(os_strcmp(pURL_Param->pParam[i], "mqtt_un")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_UN); } if(os_strcmp(pURL_Param->pParam[i], "mqtt_pw")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_PW); } if(os_strcmp(pURL_Param->pParam[i], "mqtt_rt")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_RT); } if(os_strcmp(pURL_Param->pParam[i], "mqtt_tt")==0) { url_decode((char *)pURL_Param->pParVal[i], (char *)szT ); os_strcpy(pURL_Param->pParVal[i],szT); SetEepromAscii((void *)pURL_Param, i, EEPROM_MQTT_TT); } if(os_strcmp(pURL_Param->pParam[i], "ser_baud")==0) { EEPROM.write(EEPROM_SER_BAUD+2, (int) (atoi(pURL_Param->pParVal[i])&0xFF)); EEPROM.write(EEPROM_SER_BAUD+1, (int) ((atoi(pURL_Param->pParVal[i])>>8)&0xFF)); EEPROM.write(EEPROM_SER_BAUD+0, (int) ((atoi(pURL_Param->pParVal[i])>>16)&0xFF)); } if(os_strcmp(pURL_Param->pParam[i], "ser_serv")==0) { SetEepromVal((char *)"true",EEPROM_SER_SERV, EEPROM_CHR); serserver=1; } if(os_strcmp(pURL_Param->pParam[i], "mqtt_pw_en")==0) { SetEepromVal((char *)"true",EEPROM_MQTTPWEN, EEPROM_CHR); mqtt_pwen=1; } if(os_strcmp(pURL_Param->pParam[i], "mqtt_pt")==0) { EEPROM.write(EEPROM_MQTT_PT+1, (uint8_t) (atoi(pURL_Param->pParVal[i])&0xFF)); EEPROM.write(EEPROM_MQTT_PT, (uint8_t) ((atoi(pURL_Param->pParVal[i])>>8)&0xFF)); } if(os_strcmp(pURL_Param->pParam[i], "svrport")==0) { EEPROM.write(EEPROM_SVR_PORT+1, (uint8_t) (atoi(pURL_Param->pParVal[i])&0xFF)); EEPROM.write(EEPROM_SVR_PORT, (uint8_t) ((atoi(pURL_Param->pParVal[i])>>8)&0xFF)); } } if(!serserver) { //Set Bertl Server via serial off if not in parameter list SetEepromVal((char *)"false",EEPROM_SER_SERV, EEPROM_CHR); } if(!mqtt_pwen) { //Set MQTT Password Enable off if not in parameter list SetEepromVal((char *)"false",EEPROM_MQTTPWEN, EEPROM_CHR); } EEPROM.commit(); } /******************************************************** * Sets variables associated with EEPROM residing values * for use during execution so EEPROM does not need to be * read excessively. * Function: SetSysCfgFromEeprom(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void SetSysCfgFromEeprom(void) { String Param=""; // Initialize MQTT Parameters for this session GetEepromVal(&mqtt_svr, EEPROM_MQTT_BK, EEPROM_CHR); GetEepromVal(&mqtt_rt, EEPROM_MQTT_RT, EEPROM_CHR); GetEepromVal(&mqtt_tt, EEPROM_MQTT_TT, EEPROM_CHR); GetEepromVal(&mqtt_ci, EEPROM_MQTT_CI, EEPROM_CHR); GetEepromVal(&mqtt_un, EEPROM_MQTT_UN, EEPROM_CHR); GetEepromVal(&mqtt_pw, EEPROM_MQTT_PW, EEPROM_CHR); // Initialize Network Parameters for this session GetEepromVal(&Param, EEPROM_SVR_PORT, EEPROM_INT16); http_port = atoi(Param.c_str()); GetEepromVal(&Param, EEPROM_MQTT_PT, EEPROM_INT16); mqtt_port = atoi(Param.c_str()); // Get Serial baud for this session Param=""; GetEepromVal(&Param, EEPROM_SER_BAUD, EEPROM_INT24); serial_baud = atoi(Param.c_str()); // Enable Servers for this session Param=""; GetEepromVal(&Param, EEPROM_SER_SERV, EEPROM_CHR); bertl_server = os_strcmp(Param.c_str(), "true")==0; GetEepromVal(&Param, EEPROM_MQTTPWEN, EEPROM_CHR); mqtt_pw_enable = os_strcmp(Param.c_str(), "true")==0; } /******************************************************** * Initialize EEPROM with default values * Function: InitEepromValues(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void InitEepromValues(void) { char topic[20]; SetEepromVal((char *)init_ssid,EEPROM_WIFISSID, EEPROM_CHR); SetEepromVal((char *)init_pass,EEPROM_WIFIPASS, EEPROM_CHR); SetEepromVal((char *)init_ip0,EEPROM_WIFI_IP0, EEPROM_INT); SetEepromVal((char *)init_ip1,EEPROM_WIFI_IP1, EEPROM_INT); SetEepromVal((char *)init_ip2,EEPROM_WIFI_IP2, EEPROM_INT); SetEepromVal((char *)init_ip3,EEPROM_WIFI_IP3, EEPROM_INT); SetEepromVal((char *)init_nm0,EEPROM_WIFI_NM0, EEPROM_INT); SetEepromVal((char *)init_nm1,EEPROM_WIFI_NM1, EEPROM_INT); SetEepromVal((char *)init_nm2,EEPROM_WIFI_NM2, EEPROM_INT); SetEepromVal((char *)init_nm3,EEPROM_WIFI_NM3, EEPROM_INT); SetEepromVal((char *)init_gw0,EEPROM_WIFI_GW0, EEPROM_INT); SetEepromVal((char *)init_gw1,EEPROM_WIFI_GW1, EEPROM_INT); SetEepromVal((char *)init_gw2,EEPROM_WIFI_GW2, EEPROM_INT); SetEepromVal((char *)init_gw3,EEPROM_WIFI_GW3, EEPROM_INT); SetEepromVal((char *)init_ap0,EEPROM_WIFI_AP0, EEPROM_INT); SetEepromVal((char *)init_ap1,EEPROM_WIFI_AP1, EEPROM_INT); SetEepromVal((char *)init_ap2,EEPROM_WIFI_AP2, EEPROM_INT); SetEepromVal((char *)init_ap3,EEPROM_WIFI_AP3, EEPROM_INT); SetEepromVal((char *)init_bk,EEPROM_MQTT_BK, EEPROM_CHR); SetEepromVal((char *)init_ci,EEPROM_MQTT_CI, EEPROM_CHR); SetEepromVal((char *)init_un,EEPROM_MQTT_UN, EEPROM_CHR); SetEepromVal((char *)init_pw,EEPROM_MQTT_PW, EEPROM_CHR); AddMAC("mqtt_rx_", topic); SetEepromVal((char *)topic,EEPROM_MQTT_RT, EEPROM_CHR); AddMAC("mqtt_tx_", topic); SetEepromVal((char *)topic,EEPROM_MQTT_TT, EEPROM_CHR); SetEepromVal((char *)init_port,EEPROM_SVR_PORT, EEPROM_INT16); SetEepromVal((char *)init_bd,EEPROM_SER_BAUD, EEPROM_INT24); SetEepromVal((char *)init_sr,EEPROM_SER_SERV, EEPROM_CHR); SetEepromVal((char *)init_mqpwen,EEPROM_MQTTPWEN, EEPROM_CHR); SetEepromVal((char *)init_mqtt_port,EEPROM_MQTT_PT, EEPROM_INT16); SetEepromVal((char *)init_fota_port,EEPROM_FOTA_PT, EEPROM_INT16); SetEepromVal((char *)init_fota_pass,EEPROM_FOTA_PW, EEPROM_CHR); EEPROM.commit(); } /******************************************************** * Prints a HEX map of EEPROM Values * Function: printEEprom(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void printEEprom(void) { int i,j,v; for(j=0;j<32;j++) { Serial.print(j*16,HEX); Serial.print(" "); for(i=0;i<16;i++) { v = EEPROM.read(i+(16*j)); Serial.print(v, HEX); Serial.print(" "); } Serial.println(""); } } /******************************************************** * Update EEPROM ascii parameter * Function: SetEepromAscii(void *arg, int index, int eeprom_offset) * * Parameter Description * --------- --------------------------------------- * *arg pointer to input parameter structure * index Parameter index * eeprom_offset Parameter EEPROM offset * return no return value ********************************************************/ void SetEepromAscii(void *arg, int index, int eeprom_offset) { struct URL_Param *pURL_Param = (URL_Param *)arg; int len = os_strlen(pURL_Param->pParVal[index]); for(int i=0;ipParVal[index][i]); //Update EEPROM char value } EEPROM.write(eeprom_offset+len, (uint8_t) 0); //Null Terminate String } /******************************************************** * Insert EEPROM configuration in webpage * Function: GetEepromCfg(String *page) * * Parameter Description * --------- --------------------------------------- * *page pointer to webpage string * return no return value ********************************************************/ void GetEepromCfg(String *page) { *page = reinterpret_cast(PAGE_NetCfg); String css = reinterpret_cast(PAGE_Style_css); page->replace("ADDSTYLE",css); css = ""; SetCfgPageWithEepromVal(page, "set_ssid", EEPROM_WIFISSID, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_pass", EEPROM_WIFIPASS, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_fota_pw", EEPROM_FOTA_PW, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_fota_pt", EEPROM_FOTA_PT, EEPROM_INT16); SetCfgPageWithEepromVal(page, "set_ip0", EEPROM_WIFI_IP0, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ip1", EEPROM_WIFI_IP1, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ip2", EEPROM_WIFI_IP2, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ip3", EEPROM_WIFI_IP3, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_nm0", EEPROM_WIFI_NM0, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_nm1", EEPROM_WIFI_NM1, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_nm2", EEPROM_WIFI_NM2, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_nm3", EEPROM_WIFI_NM3, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_gw0", EEPROM_WIFI_GW0, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_gw1", EEPROM_WIFI_GW1, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_gw2", EEPROM_WIFI_GW2, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_gw3", EEPROM_WIFI_GW3, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ap0", EEPROM_WIFI_AP0, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ap1", EEPROM_WIFI_AP1, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ap2", EEPROM_WIFI_AP2, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_ap3", EEPROM_WIFI_AP3, EEPROM_INT); SetCfgPageWithEepromVal(page, "set_bk", EEPROM_MQTT_BK, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_ci", EEPROM_MQTT_CI, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_un", EEPROM_MQTT_UN, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_pw", EEPROM_MQTT_PW, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_rt", EEPROM_MQTT_RT, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_tt", EEPROM_MQTT_TT, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_port", EEPROM_SVR_PORT, EEPROM_INT16); SetCfgPageWithEepromVal(page, "set_pt", EEPROM_MQTT_PT, EEPROM_INT16); SetCfgPageWithEepromVal(page, "set_pt", EEPROM_MQTT_CI, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_fota_pt", EEPROM_FOTA_PT, EEPROM_INT16); SetCfgPageWithEepromVal(page, "set_fota_pw", EEPROM_FOTA_PW, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_baud", EEPROM_SER_BAUD, EEPROM_INT24); SetCfgPageWithEepromVal(page, "set_serv", EEPROM_SER_SERV, EEPROM_CHR); SetCfgPageWithEepromVal(page, "set_mqtt_pw_en", EEPROM_MQTTPWEN, EEPROM_CHR); } /******************************************************** * Insert EEPROM configuration in webpage * Function: SetCfgPageWithEepromVal(String *page, String par, int offset, int fmt) * * Parameter Description * --------- --------------------------------------- * *page pointer to webpage string * par token in webpage to replace * offset parameter EEPROM offset * fmt EEPROM data format * return no return value ********************************************************/ void SetCfgPageWithEepromVal(String *page, String par, int offset, int fmt) { String SetVal =""; GetEepromVal(&SetVal, offset, fmt); page->replace(par,SetVal); } /******************************************************** * Get EEPROM Value * Function: GetEepromVal(String *val,int offset, int fmt) * * Parameter Description * --------- --------------------------------------- * *val string to hold parameter value * offset parameter EEPROM offset * fmt EEPROM data format * return no return value ********************************************************/ void GetEepromVal(String *val,int offset, int fmt) { int i; *val = ""; switch(fmt) { case EEPROM_CHR: for(i=offset;i<(offset+32);i++) { if(EEPROM.read(i)!=0) *val += char(EEPROM.read(i)); else break; } break; case EEPROM_INT: *val = EEPROM.read(offset); break; case EEPROM_INT16: *val = EEPROM.read(offset+1) + (EEPROM.read(offset) * 256); break; case EEPROM_INT24: *val = EEPROM.read(offset+2) + (EEPROM.read(offset+1) * 256) + (EEPROM.read(offset+0) * 256 * 256); break; } } /******************************************************** * Set EEPROM Value * Function: SetEepromVal(String *val,int offset, int fmt) * * Parameter Description * --------- --------------------------------------- * *val string to hold parameter value * offset parameter EEPROM offset * fmt EEPROM data format * return no return value ********************************************************/ void SetEepromVal(char *val,int offset, int fmt) { int i; switch(fmt) { case EEPROM_CHR: for(i=0;i>8); break; case EEPROM_INT24: EEPROM.write(offset+2, atoi(val)&0xFF); EEPROM.write(offset+1, (atoi(val)&0xFF00)>>8); EEPROM.write(offset+0, (atoi(val)&0xFF0000)>>16); break; } } /******************************************************** * Resets ESP8266 after delay set when callback is armed * Function: ResetEspTimerCallback(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void ResetEspTimerCallback(void) { ESP.reset(); } /******************************************************** * Initiates LED blink count-down * Function: blinkLed(int nblink) * extern "C" {} required so function can be called * from endpoints.c file * * Parameter Description * --------- --------------------------------------- * nblink number of times to blink LED * return no return value ********************************************************/ extern "C"{ void blinkLed(int nblink) { blinkarg[0] = nblink; //Number of blinks blinkarg[1] = 1; //LED state to command blinkarg[2] = 1; //First Callback Iteration os_timer_disarm(&BlinkLedTimer); os_timer_setfn(&BlinkLedTimer, (os_timer_func_t *)BlinkCallback, &blinkarg[0]); os_timer_arm(&BlinkLedTimer, 500, false); } } /******************************************************** * Callback for Blink timer * Function: BlinkCallback(int *pArg) * * Parameter Description * --------- ----------------------------------------- * *pArg int - number of times to blink LED * *pArg+1 int - set LED state (0=off,1=on) * *pArg+2 int - set to 1 first time to print header * return no return value ********************************************************/ void BlinkCallback(int *pArg) { int i; int nblinks,ledstate,start; nblinks = *(int *)pArg; ledstate = *(int *)(pArg+1); start = *(int *)(pArg+2); if(start == 1) { Serial.print("Blink countdown:"); blinkarg[2] = 0; //do not print header next time } if(ledstate==1) { Serial.print( nblinks); if(nblinks>1) { Serial.print("."); } else { Serial.println("..."); } digitalWrite(LED_IND, HIGH); blinkarg[1] = 0; os_timer_arm(&BlinkLedTimer, 500, false); } else { digitalWrite(LED_IND, LOW); blinkarg[1] = 1; //start with led on cmd if(--nblinks!=0) { --blinkarg[0]; //remaining blinks os_timer_arm(&BlinkLedTimer, 500, false); } } } /******************************************************** * SDK API Web Server Initialization * Function: SdkWebServer_Init(int port) * * Parameter Description * --------- --------------------------------------- * port http server listen port * return no return value ********************************************************/ void SdkWebServer_Init(int port) { LOCAL struct espconn esp_conn; LOCAL esp_tcp esptcp; //Fill the connection structure, including "listen" port esp_conn.type = ESPCONN_TCP; esp_conn.state = ESPCONN_NONE; esp_conn.proto.tcp = &esptcp; esp_conn.proto.tcp->local_port = port; esp_conn.recv_callback = NULL; esp_conn.sent_callback = NULL; esp_conn.reverse = NULL; //Register the connection timeout(0=no timeout) espconn_regist_time(&esp_conn,0,0); //Register connection callback espconn_regist_connectcb(&esp_conn, SdkWebServer_listen); //Start Listening for connections espconn_accept(&esp_conn); Serial.print("Web Server initialized: Type = SDK API\r\n"); } /******************************************************** * SDK API Web Server TCP Client Connection Callback * Function: SdkWebServer_listen(void *arg) * * Parameter Description * --------- --------------------------------------- * *arg pointer to espconn structure * return no return value ********************************************************/ void SdkWebServer_listen(void *arg) { struct espconn *pesp_conn = ( espconn *)arg; espconn_regist_recvcb(pesp_conn, SdkWebServer_recv); espconn_regist_reconcb(pesp_conn, SdkWebServer_recon); espconn_regist_disconcb(pesp_conn, SdkWebServer_discon); espconn_regist_sentcb(pesp_conn, SdkWebServer_sent_cb); } void SdkWebServer_sent_cb(void *arg) { //Serial.println("html sent complete"); httpsend_ready = true; } /******************************************************** * SDK API Web Server Receive Data Callback * Function: SdkWebServer_recv(void *arg, char *pusrdata, * unsigned short length) * * Parameter Description * --------- --------------------------------------- * *arg pointer to espconn structure * *pusrdata data received after IP:port * length data length (bytes) * return no return value ********************************************************/ void SdkWebServer_recv(void *arg, char *pusrdata, unsigned short length) { URL_Param *pURL_Param = NULL; char *pParseBuffer = NULL; char * pRequest = NULL; char * pReply = NULL; bool parse_flag = false; ptrespconn = ( espconn *)arg; espconn_set_opt(ptrespconn, ESPCONN_REUSEADDR); parse_flag = SdkWebServer_savedata(pusrdata, length); pURL_Param = (URL_Param *)os_zalloc(sizeof(URL_Param)); pRequest = (char *)os_zalloc(1024); pReply = (char *)os_zalloc(1024); os_memcpy(pRequest, precvbuffer, length); if(!bertl_server) { Serial.println(F("-------------------------------------")); Serial.println(F("HTTP Message Rx: [Code: SDK API]")); Serial.println(F("-------------------------------------")); } Server_ProcessRequest(SVR_HTTP_SDK, pRequest, pReply); //Clean up the memory if (precvbuffer != NULL) { os_free(precvbuffer); precvbuffer = NULL; } os_free(pURL_Param); os_free(pRequest); os_free(pReply); pURL_Param = NULL; pRequest=NULL; pReply=NULL; } void Server_SendReply(int servertype, int replytype, String payld) { // Now send reply if(!bertl_server) { Serial.println(F("-------------------------------------")); Serial.println(F("Reply Payload:")); Serial.println(payld); Serial.println(F("-------------------------------------")); } switch(servertype) { case SVR_MQTT: client.publish((char *)mqtt_tt.c_str(), payld.c_str(), false); break; case SVR_HTTP_LIB: //httpClient.print(payld); break; case SVR_HTTP_SDK: switch(replytype) { case REPLY_JSON: SdkWebServer_senddata(ptrespconn, true, (char *)payld.c_str(),"application/json"); break; case REPLY_TEXT: SdkWebServer_senddata(ptrespconn, true, (char *)payld.c_str(),"text/html"); break; } break; case SVR_COAP: //endpoint api returns reply break; } } /****************************************************************************************** * Get Request & Process ******************************************************************************************/ void Server_ProcessRequest(int servertype, char *payload, char *reply) { int i,nblink; String payld = ""; String BertlRequest = ""; String WebPage = ""; RQST_Param rparam; URL_Param *pURL_Param = NULL; pURL_Param = (URL_Param *)os_zalloc(sizeof(URL_Param)); SdkWebServer_parse_url_params(payload, pURL_Param); switch (pURL_Param->Type) { case GET: // ---------------------------------------------------------------------------- // Serving Requests // ---------------------------------------------------------------------------- if(os_strcmp(pURL_Param->pParam[0], "request")==0) { // GetSensors is 1 of 4 requests the server currently supports if(os_strcmp(pURL_Param->pParVal[0], "GetSensors")==0) { rparam.request = Get_SENSORS; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } // LedOn is 2 of 4 requests the server currently supports else if(os_strcmp(pURL_Param->pParVal[0], "LedOn")==0) { rparam.request = SET_LED_ON; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } // LedOff is 3 of 4 requests the server currently supports else if(os_strcmp(pURL_Param->pParVal[0], "LedOff")==0) { rparam.request = SET_LED_OFF; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } // BlinkLed is 4 of 4 requests the server currently supports else if(os_strcmp(pURL_Param->pParVal[0], "BlinkLed")==0) { rparam.request = BLINK_LED; if(os_strcmp(pURL_Param->pParam[1], "nblink")==0) { rparam.requestval = atoi(pURL_Param->pParVal[1]); } else { rparam.requestval = 1; } // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } else if(os_strcmp(pURL_Param->pParVal[0], "MV")==0) { rparam.request = MV; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } else if(os_strcmp(pURL_Param->pParVal[0], "TL")==0) { rparam.request = TL; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } else if(os_strcmp(pURL_Param->pParVal[0], "TR")==0) { rparam.request = TR; rparam.requestval = 0; // Execute request & get reply string Server_ExecuteRequest(servertype, rparam, &payld,""); } // Add additional requests here else //Invalid request { rparam.request == INVALID_REQUEST; payld = "Invalid Request"; } // Now send reply Server_SendReply(servertype, REPLY_JSON, payld); } // ---------------------------------------------------------------------------- // Serving Web Pages // ---------------------------------------------------------------------------- // // ------------- Load Test Page ----------------------------------------------- //NOTE: From this, a 1927 byte limit for serving web-pages to external domains // No such limit exists for local network access if(os_strcmp(pURL_Param->pParam[0], "test")==0) { WebPage = reinterpret_cast(PAGE_NetCfg2); String css = reinterpret_cast(PAGE_Style2_css); WebPage.replace("ADDSTYLE",css); css = ""; SdkWebServer_senddata(ptrespconn, true, (char *) WebPage.c_str(),"text/html"); } // ------------- Load Config Page --------------------------------------------- if(os_strcmp(pURL_Param->pParam[0], "config")==0) { GetEepromCfg(&WebPage); SdkWebServer_senddata(ptrespconn, true, (char *) WebPage.c_str(),"text/html"); } // -------------- Save config or Reset ESP8266 -------------------------------- if(os_strcmp(pURL_Param->pParam[0], "ssid")==0) { if(os_strcmp(pURL_Param->pParVal[0], "reset")==0){ // ------------- Reset ESP8266 ---------------------------------------- WebPage = reinterpret_cast(PAGE_WaitAndReset); SdkWebServer_senddata(ptrespconn, true, (char *) WebPage.c_str(),"text/html"); os_timer_arm(&ResetEspTimer, 3000, false); } else { // -------------- Save config to EEPROM and reload config page -------- SetEepromCfg((void *)pURL_Param); WebPage = reinterpret_cast(PAGE_WaitAndReload); //reload config page SdkWebServer_senddata(ptrespconn, true, (char *) WebPage.c_str(),"text/html"); } } // ---------------------------------------------------------------------------- // Serving M0 Board via serial port pe??? // ---------------------------------------------------------------------------- if(os_strcmp(pURL_Param->pParam[0], "M0")==0) { active_svr_rqst = servertype; //-------------- Request = Bertl MOVE + Time in ms --------------------- // http://192.168.1.132:8266/?M0=MV ; pURL_Param->pParam[0] ="M0" // ; pURL_Param->pParVal[0], "MV" if(os_strcmp(pURL_Param->pParVal[0], "MV")==0){ BertlRequest = "MV"; if(os_strcmp(pURL_Param->pParam[1], "value")==0) { BertlRequest = "_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } //Serial.println("MV_500."); } //-------------- Request = Bertl TURNLEFT + Time in ms --------------------- // http://192.168.1.132:8266/?M0=TL ; pURL_Param->pParam[0] ="M0" // ; pURL_Param->pParVal[0], "TL" if(os_strcmp(pURL_Param->pParVal[0], "TL")==0){ BertlRequest = "TL"; if(os_strcmp(pURL_Param->pParam[1], "value")==0) { BertlRequest = "_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } //Serial.println("TL_500."); } //-------------- Request = Bertl TURNRIGHT + Time in ms --------------------- // http://192.168.1.132:8266/?M0=TL ; pURL_Param->pParam[0] ="M0" // ; pURL_Param->pParVal[0], "TR" if(os_strcmp(pURL_Param->pParVal[0], "TR")==0){ BertlRequest = "TR"; if(os_strcmp(pURL_Param->pParam[1], "value")==0) { BertlRequest = "_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } //Serial.println("TL_500."); } //-------------- Request = SetDigital M0 --------------------- if(os_strcmp(pURL_Param->pParVal[0], "SD")==0){ if(os_strcmp(pURL_Param->pParam[1], "chan")==0) { BertlRequest = "M0_SD_"; BertlRequest += pURL_Param->pParVal[1]; BertlRequest += "_"; } else { BertlRequest = "Invalid Request"; } if((os_strcmp(pURL_Param->pParam[2], "state")==0)&&(os_strcmp(BertlRequest.c_str(), "Invalid Request")!=0)) { BertlRequest += pURL_Param->pParVal[2]; } else { BertlRequest = "Invalid Request"; } //Serial.println("M0_SD_04_1."); } //-------------- Request = GetDigital ---------------------- else if(os_strcmp(pURL_Param->pParVal[0], "GD")==0){ if(os_strcmp(pURL_Param->pParam[1], "chan")==0) { BertlRequest = "M0_GD_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } //Serial.println("M0_GD_04."); } //-------------- Request = GetAnalog ---------------------- else if(os_strcmp(pURL_Param->pParVal[0], "GA")==0){ if(os_strcmp(pURL_Param->pParam[1], "chan")==0) { BertlRequest = "M0_GA_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } } //-------------- Request = Hollegha ---------------------- else if(os_strcmp(pURL_Param->pParVal[0], "HL")==0){ if(os_strcmp(pURL_Param->pParam[1], "msg")==0) { BertlRequest = "HL_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } } //-------------- Request = Send MQTT Msg ------------------- else if(os_strcmp(pURL_Param->pParVal[0], "SendMsg")==0){ if(os_strcmp(pURL_Param->pParam[1], "msg")==0) { BertlRequest = "M0_SM_"; BertlRequest += pURL_Param->pParVal[1]; } else { BertlRequest = "Invalid Request"; } } //-------------- Request is not recognized ----------------- else { BertlRequest = "Invalid Request"; } //------------- Send "invalid request" as reply ------------ if(os_strcmp(BertlRequest.c_str(), "Invalid Request")==0) { payld = BertlRequest; Server_SendReply(servertype, REPLY_TEXT, payld); } //------------- Execute valid request --------------------- else { rparam.request = BERTL_REQUEST; rparam.requestval = 0; Server_ExecuteRequest(servertype, rparam, &payld, BertlRequest); } } break; case POST: Serial.print(F("We have a POST request.\n")); break; } strcpy(reply,(char *)payld.c_str()); os_free(pURL_Param); pURL_Param = NULL; payld = ""; BertlRequest = ""; WebPage = ""; } /******************************************************** * SDK API Web Server TCP Connection Closed Callback * Function: SdkWebServer_discon(void *arg) * * Parameter Description * --------- --------------------------------------- * *arg pointer to espconn structure * return no return value ********************************************************/ void SdkWebServer_discon(void *arg) { struct espconn *pesp_conn = ( espconn *)arg; os_printf("webserver's %d.%d.%d.%d:%d disconnect\n", pesp_conn->proto.tcp->remote_ip[0], pesp_conn->proto.tcp->remote_ip[1],pesp_conn->proto.tcp->remote_ip[2], pesp_conn->proto.tcp->remote_ip[3],pesp_conn->proto.tcp->remote_port); } /******************************************************** * SDK API Web Server TCP Disconnect on error Callback * Function: SdkWebServer_recon(void *arg, sint8 err) * * Parameter Description * --------- --------------------------------------- * *arg pointer to espconn structure * err error code * return no return value ********************************************************/ void SdkWebServer_recon(void *arg, sint8 err) { struct espconn *pesp_conn = ( espconn *)arg; os_printf("webserver's %d.%d.%d.%d:%d err %d reconnect\n", pesp_conn->proto.tcp->remote_ip[0], pesp_conn->proto.tcp->remote_ip[1],pesp_conn->proto.tcp->remote_ip[2], pesp_conn->proto.tcp->remote_ip[3],pesp_conn->proto.tcp->remote_port, err); } void SdkWebServer_senddata(void *arg, bool responseOK, char *psend, char* contenttype) { uint16 length = 0; uint16 length_send = 0; uint16 length_sent = 0; char *pbuf = NULL; char httphead[512]; struct espconn *ptrespconn = ( espconn *)arg; os_memset(httphead, 0, 512); String gmt,expire; time_t now = time(nullptr); gmt = ctime(&now); now += 3600 * 24; //Expires in 1 day expire = ctime(&now); gmt = gmt.substring(0,3) + "," + gmt.substring(7,10) + gmt.substring(3,7) + gmt.substring(19,24) + gmt.substring(10,19) + " GMT"; expire = expire.substring(0,3) + "," + expire.substring(7,10) + expire.substring(3,7) + expire.substring(19,24) + expire.substring(10,19) + " GMT"; if (responseOK) { os_sprintf(httphead, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\nAccess-Control-Allow-Origin: *\r\nDate: %s\r\n", psend ? os_strlen(psend) : 0,gmt.c_str()); if (psend) { os_sprintf(httphead + os_strlen(httphead), "Content-type: %s\r\nExpires: %s\r\nPragma: no-cache\r\n\r\n",contenttype,expire.c_str()); //"Content-type: text/html\r\nExpires: %s\r\nPragma: no-cache\r\n\r\n",contenttype,expire.c_str()); length = os_strlen(httphead) + os_strlen(psend); pbuf = (char *)os_zalloc(length + 1); os_memcpy(pbuf, httphead, os_strlen(httphead)); os_memcpy(pbuf + os_strlen(httphead), psend, os_strlen(psend)); } else { os_sprintf(httphead + os_strlen(httphead), "\n"); length = os_strlen(httphead); } } else { os_sprintf(httphead, "HTTP/1.0 400 BadRequest\r\n\ Content-Length: 0\r\nServer: lwIP/1.4.0\r\n\n"); length = os_strlen(httphead); } if (psend) { espconn_send(ptrespconn, (uint8 *)pbuf, length); } else { //httpsend_ready set in SdkWebServer_sent_cb() callback which is called when espconn_send() completes if(httpsend_ready) { httpsend_ready = false; espconn_send(ptrespconn, (uint8 *)httphead, length); } } if (pbuf) { os_free(pbuf); pbuf = NULL; } } /******************************************************** * SDK API Web Server save data from connected client * Function: bool SdkWebServer_savedata(char *precv, * uint16 length) * * Parameter Description * --------- --------------------------------------- * *precv string received * length string length * return true if succes ful save ********************************************************/ bool SdkWebServer_savedata(char *precv, uint16 length) { bool flag = false; char length_buf[10] = {0}; char *ptemp = NULL; char *pdata = NULL; uint16 headlength = 0; static uint32 totallength = 0; ptemp = (char *)os_strstr(precv, "\r\n\r\n"); if (ptemp != NULL) { length -= ptemp - precv; length -= 4; totallength += length; headlength = ptemp - precv + 4; pdata = (char *)os_strstr(precv, "Content-Length: "); if (pdata != NULL) { pdata += 16; precvbuffer = (char *)os_strstr(pdata, "\r\n"); if (precvbuffer != NULL) { os_memcpy(length_buf, pdata, precvbuffer - pdata); dat_sumlength = atoi(length_buf); } } else { if (totallength != 0x00){ totallength = 0; dat_sumlength = 0; return false; } } if ((dat_sumlength + headlength) >= 1024) { precvbuffer = (char *)os_zalloc(headlength + 1); os_memcpy(precvbuffer, precv, headlength + 1); } else { precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1); os_memcpy(precvbuffer, precv, os_strlen(precv)); } } else { if (precvbuffer != NULL) { totallength += length; os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length); } else { totallength = 0; dat_sumlength = 0; return false; } } if (totallength == dat_sumlength) { totallength = 0; dat_sumlength = 0; return true; } else { return false; } } /******************************************************** * SDK API Web Server parse received parameters * Function: void SdkWebServer_ parse_url_params( * char *precv, URL_Param *purl_param) * * Parameter Description * --------- --------------------------------------- * *precv string received * *purl_param parsed parameter structure * return no return value ********************************************************/ void SdkWebServer_parse_url_params(char *precv, URL_Param *purl_param) { char *str = NULL; unsigned int length = 0; char *pbuffer = NULL; char *pbufer = NULL; int ipar=0; if (purl_param == NULL || precv == NULL) { return; } //pbuffer = (char *)os_strstr(precv, "Host:"); //pbuffer = (char *)os_strstr(precv, "Accept:"); pbuffer = (char *)os_strstr(precv, "Connection:"); if (pbuffer != NULL) { length = pbuffer - precv; pbufer = (char *)os_zalloc(length + 1); pbuffer = pbufer; os_memcpy(pbuffer, precv, length); os_memset(purl_param->pParam, 0, URLSize*URLSize); os_memset(purl_param->pParVal, 0, URLSize*URLSize); if (os_strncmp(pbuffer, "GET /favicon.ico", 16) == 0) { purl_param->Type = GET_FAVICON; os_free(pbufer); return; } else if (os_strncmp(pbuffer, "GET ", 4) == 0) { purl_param->Type = GET; pbuffer += 4; } else if (os_strncmp(pbuffer, "POST ", 5) == 0) { purl_param->Type = POST; pbuffer += 5; } pbuffer ++; str = (char *)os_strstr(pbuffer, "?"); if (str != NULL) { str ++; do { pbuffer = (char *)os_strstr(str, "="); length = pbuffer - str; os_memcpy(purl_param->pParam[ipar], str, length); str = (char *)os_strstr(++pbuffer, "&"); if(str != NULL) { length = str - pbuffer; os_memcpy(purl_param->pParVal[ipar++], pbuffer, length); str++; } else { str = (char *)os_strstr(pbuffer, " HTTP"); if(str != NULL) { length = str - pbuffer; os_memcpy(purl_param->pParVal[ipar++], pbuffer, length); str = NULL; } else { //os_memcpy(purl_param->pParVal[ipar++], pbuffer, 16); } } } while (str!=NULL); } else { str = (char *)os_strstr(pbuffer, "/"); if (str != NULL) { str ++; str = (char *)os_strstr(pbuffer, " HTTP"); if(str != NULL) { length = str - pbuffer; os_memcpy(purl_param->pParVal[ipar], "0", 1); os_memcpy(purl_param->pParam[ipar++], pbuffer, length); str = NULL; } else { //os_memcpy(purl_param->pParVal[ipar++], pbuffer, 16); } } } purl_param->nPar = ipar; os_free(pbufer); } else { return; } } /******************************************************** * print status to serial port * Function: util_printStatus(char * status, int s) * * Parameter Description * --------- --------------------------------------- * *status status string * s status code * return no return value ********************************************************/ void util_printStatus(char * status, int s) { Serial.print(system_get_free_heap_size()); delay(100); Serial.print(" "); delay(100); Serial.print(millis()/1000); delay(100); Serial.print(" "); delay(100); if(s>=0) Serial.print(s); else Serial.print(""); delay(100); Serial.print(" "); delay(100); Serial.println(status); // } delay(100); } /******************************************************** * connect to local Wifi * Function: util_startWIFI(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void util_startWIFI(void) { if ((WiFi.status() != WL_CONNECTED)&&(wifi!=0)) { int itimeout=0; String EepromSsid=""; String EepromPass=""; IPAddress ip = WiFi.localIP(); //Get IP, NM, GW from EEPROM const IPAddress ip_eeprom(EEPROM.read(EEPROM_WIFI_IP0),EEPROM.read(EEPROM_WIFI_IP1),EEPROM.read(EEPROM_WIFI_IP2),EEPROM.read(EEPROM_WIFI_IP3)); const IPAddress nm_eeprom(EEPROM.read(EEPROM_WIFI_NM0),EEPROM.read(EEPROM_WIFI_NM1),EEPROM.read(EEPROM_WIFI_NM2),EEPROM.read(EEPROM_WIFI_NM3)); const IPAddress gw_eeprom(EEPROM.read(EEPROM_WIFI_GW0),EEPROM.read(EEPROM_WIFI_GW1),EEPROM.read(EEPROM_WIFI_GW2),EEPROM.read(EEPROM_WIFI_GW3)); const IPAddress ap_eeprom(EEPROM.read(EEPROM_WIFI_AP0),EEPROM.read(EEPROM_WIFI_AP1),EEPROM.read(EEPROM_WIFI_AP2),EEPROM.read(EEPROM_WIFI_AP3)); GetEepromVal(&EepromSsid, EEPROM_WIFISSID, EEPROM_CHR); GetEepromVal(&EepromPass, EEPROM_WIFIPASS, EEPROM_CHR); if(!bertl_server) { Serial.print("\nLocal ESP IP:"); delay(10); Serial.println(ip); Serial.print("From EEPROM IP:"); delay(10); Serial.println(ip_eeprom); delay(10); Serial.print("From EEPROM NM:"); delay(10); Serial.println(nm_eeprom); delay(10); Serial.print("From EEPROM GW:"); delay(10); Serial.println(gw_eeprom); delay(10); Serial.print("From EEPROM AP:"); delay(10); Serial.println(ap_eeprom); delay(10); } if( ip!= ip_eeprom) { //Set IP if current not equal to EEPROM value WiFi.config(ip_eeprom, gw_eeprom, nm_eeprom); if(!bertl_server) { Serial.println(); delay(10); Serial.print("ESP8266 IP:"); delay(10); Serial.println(ip_eeprom); delay(10); Serial.print("Fixed IP:"); delay(10); Serial.println(ip_eeprom); delay(10); Serial.print("IP now set to: "); delay(10); Serial.println(WiFi.localIP()); delay(10); } } // Connect to WiFi network if(os_strlen(EepromSsid.c_str())>0) { strcpy((char *)init_ssid,EepromSsid.c_str()); } if(os_strlen(EepromPass.c_str())>0) { strcpy((char *)init_pass,EepromPass.c_str()); } if(!bertl_server) { Serial.println(); delay(10); Serial.println(); delay(10); Serial.print("Connecting to "); delay(10); Serial.print(init_ssid); delay(10); } Serial.println(""); Serial.print("BAUD RATE: "); Serial.println(serial_baud); Serial.print("SSID: "); Serial.println(init_ssid); Serial.print("PASS: "); Serial.println(init_pass); //strcpy(init_ssid, "cisco"); //strcpy(init_pass, "ciscoclass"); WiFi.begin(init_ssid, init_pass); while ((WiFi.status() != WL_CONNECTED)&&(itimeout++<20)) { //10 sec timeout if(!bertl_server) { Serial.print("."); } delay(500); } if(!bertl_server) { Serial.println(""); } if(itimeout<20) { if(!bertl_server) { Serial.println("WiFi connected"); // Print the IP address Serial.print("ESP8266 IP: "); Serial.println(WiFi.localIP()); Serial.print("ESP8266 WebServer Port: "); Serial.println(http_port); } wifi=1; } else { //unsuccessful connecting to wifi for > 10 sec, initialize AP mode Serial.println("Could not connect to wifi, initializing AP "); strcat((char *)init_ssid,AP_EXT); // PE!!! WiFi.mode(WIFI_AP_STA); WiFi.softAPConfig(ap_eeprom, ap_eeprom, nm_eeprom); WiFi.softAP(init_ssid); // Print the IP address Serial.print("ESP8266 IP: "); Serial.println(WiFi.softAPIP()); wifi=0; } delay(300); } } /******************************************************** * setup local Wifi as AP * Function: setup_wifi_ap_mode(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void setup_wifi_ap_mode(void) { //char ssid[33]; //char password[33]; //wifi_set_opmode(SOFTAP_MODE); wifi_set_opmode(STATIONAP_MODE); wifi_softap_dhcps_stop(); struct softap_config apconfig; if(wifi_softap_get_config(&apconfig)) { os_memset(apconfig.ssid, 0, sizeof(apconfig.ssid)); os_memset(apconfig.password, 0, sizeof(apconfig.password)); strcat((char *)init_ssid,"_AP"); strcpy((char *)apconfig.ssid,init_ssid); apconfig.authmode = AUTH_OPEN; apconfig.ssid_hidden = 0; apconfig.max_connection = 4; if(!wifi_softap_set_config(&apconfig)) { Serial.println("ESP8266 not set ap config!\r\n"); } } //Set WiFi event callback wifi_set_event_handler_cb(wifi_event_cb); LOCAL struct ip_info info; IP4_ADDR(&info.ip, 192, 168, 4, 1); // PE!!! PE??? IP4_ADDR(&info.gw, 192, 168, 4, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(SOFTAP_IF, &info); struct dhcps_lease dhcp_lease; IP4_ADDR(&dhcp_lease.start_ip, 192, 168, 4, 2); IP4_ADDR(&dhcp_lease.end_ip, 192, 168, 4, 5); wifi_softap_set_dhcps_lease(&dhcp_lease); wifi_softap_dhcps_start(); //Startup Complete Status Serial.println("Startup Complete..."); } /******************************************************** * Callback when External Station Connects or Disconnects * Function: void wifi_event_cb(System_Event_t *evt) * * Parameter Description * --------- --------------------------------------- * *evt event structure * return no return value ********************************************************/ void wifi_event_cb(System_Event_t *evt) { struct ip_info ipConfig; static int serverinit=0; Serial.print("Callback from Disconnect"); switch (evt->event) { case EVENT_SOFTAPMODE_STACONNECTED: Serial.print("station: "); Serial.print(MACSTR); Serial.println(" join, AID = "); //Start Web Server (Upon first connection) if(!serverinit) { SdkWebServer_Init(http_port); serverinit=1; } break; case EVENT_SOFTAPMODE_STADISCONNECTED: Serial.print("station: "); Serial.print(MACSTR); Serial.println(" leave, AID = "); break; default: break; } } /******************************************************** * Read 1 sensor each time function is called * Current sensors: ESP8266 ADC with 8-1 MUX input * Function: void ReadSensors(int interval) * * Parameter Description * --------- --------------------------------------- * interval milliseconds (minimum) between reads * return no return value ********************************************************/ void ReadSensors(int interval) { yield(); long now = millis(); if (now - lastMsg > interval) { // Read 1 sensor every "interval" milliseconds or longer lastMsg = now; } else { return; } switch(state++) { case 0: //Set 8-1 amux to position 0 digitalWrite(AMUXSEL0, 0); digitalWrite(AMUXSEL1, 0); digitalWrite(AMUXSEL2, 0); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain0, 2); break; case 1: //Set 8-1 amux to position 1 digitalWrite(AMUXSEL0, 1); digitalWrite(AMUXSEL1, 0); digitalWrite(AMUXSEL2, 0); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain1, 2); break; case 2: //Set 8-1 amux to position 2 digitalWrite(AMUXSEL0, 0); digitalWrite(AMUXSEL1, 1); digitalWrite(AMUXSEL2, 0); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain2, 2); break; case 3: //Set 8-1 amux to position 3 digitalWrite(AMUXSEL0, 1); digitalWrite(AMUXSEL1, 1); digitalWrite(AMUXSEL2, 0); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain3, 2); break; case 4: //Set 8-1 amux to position 4 digitalWrite(AMUXSEL0, 0); digitalWrite(AMUXSEL1, 0); digitalWrite(AMUXSEL2, 1); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain4, 2); break; case 5: //Set 8-1 amux to position 5 digitalWrite(AMUXSEL0, 1); digitalWrite(AMUXSEL1, 0); digitalWrite(AMUXSEL2, 1); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain5, 2); break; case 6: //Set 8-1 amux to position 6 digitalWrite(AMUXSEL0, 0); digitalWrite(AMUXSEL1, 1); digitalWrite(AMUXSEL2, 1); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain6, 2); break; case 7: //Set 8-1 amux to position 7 digitalWrite(AMUXSEL0, 1); digitalWrite(AMUXSEL1, 1); digitalWrite(AMUXSEL2, 1); delay(100); //Read analog input Ain = (float) analogRead(A0); ftoa(Ain,Ain7, 2); state = 0; break; default: break; } ESP.wdtFeed(); yield(); } /******************************************************** * add key/value entry into json string * Function: jsonAdd( * String * s, * String key, * String val) * * Parameter Description * --------- --------------------------------------- * *s pointer to current json string * key this json string key * val this json string value * return no return value ********************************************************/ void jsonAdd(String *s, String key,String val) { *s += '"' + key + '"' + ":" + '"' + val + '"'; } /******************************************************** * encode key/value entry into json string * Function: jsonEncode(int pos, * String * s, * String key, * String val) * * Parameter Description * --------- --------------------------------------- * pos position of this json entry * *s pointer to current json string * key this json string key * val this json string value * return no return value ********************************************************/ void jsonEncode(int pos, String * s, String key, String val) { switch (pos) { case ONEJSON: case FIRSTJSON: *s += "{\r\n"; jsonAdd(s,key,val); *s+= (pos==ONEJSON) ? "\r\n}" : ",\r\n"; break; case NEXTJSON: jsonAdd(s,key,val); *s+= ",\r\n"; break; case LASTJSON: jsonAdd(s,key,val); *s+= "\r\n}"; break; } } /******************************************************** * Create request reply string to request * Function: Server_ExecuteRequest(int servertype, RQST_Param rparam, String* reply, String BertlRequest) * * Parameter Description * --------- --------------------------------------- * servertype server type (SDK or LIB) * RQST_Param structure * request request enumberation * requestval value associated with request - such as value to set * *reply reply string pointer * BertlRequest Bertl request string pointer pe??? ********************************************************/ void Server_ExecuteRequest(int servertype, RQST_Param rparam, String* reply, String BertlRequest) { String v = ""; if(servertype == SVR_HTTP_LIB) { // Prepare Response header *reply = "HTTP/1.1 200 OK\r\n"; *reply += "Access-Control-Allow-Origin: *\r\n"; ESP.wdtFeed(); } switch (rparam.request) { //PE!!! case MV: // Move Serial.println("MV"); //digitalWrite(LED_IND , rparam.request); //serial communication // Prepare the response wait scanf??? *reply += "Roboter moved forward \n"; break; case TL: // TurnLeft Serial.println("TL"); //digitalWrite(LED_IND , rparam.request); //serial communication // Prepare the response wait scanf??? *reply += "Roboter turned left \n"; break; case TR: // TurnLeft Serial.println("TR"); //digitalWrite(LED_IND , rparam.request); //serial communication // Prepare the response wait scanf??? *reply += "Roboter turned right \n"; break; case FL: // TurnLeft Serial.println("FL"); //digitalWrite(LED_IND , rparam.request); //serial communication // Prepare the response wait scanf??? *reply += "Roboter turned right \n"; break; case LED_ON: // Set GPIOn according to the request digitalWrite(LED_IND , HIGH); //LED_ON break; case LED_OFF: // Set GPIOn according to the request digitalWrite(LED_IND , LOW); //LED_OFF break; case SET_LED_OFF: case SET_LED_ON: // Set GPIOn according to the request digitalWrite(LED_IND , rparam.request); //SET_LED_OFF=0.SET_LED_ON=1 // Prepare the response for GPIO state switch(servertype) { case SVR_HTTP_LIB: *reply += "Content-Type: text/html\r\n\r\n"; *reply += "\r\nLED is now "; *reply += (rparam.request)?"ON":"OFF"; *reply += "\n"; break; case SVR_COAP: case SVR_MQTT: case SVR_HTTP_SDK: *reply += "LED is now "; *reply += (rparam.request)?"ON":"OFF"; *reply += "\n"; break; } break; case BLINK_LED: blinkLed(rparam.requestval); //Blink Led requestval times using non-blocking timer // Prepare the response for LED Blinking state switch(servertype) { case SVR_HTTP_LIB: *reply += "Content-Type: text/html\r\n\r\n"; *reply += "\r\nLED is now blinking "; *reply += rparam.requestval; *reply += " times."; *reply += "\n"; break; case SVR_COAP: case SVR_MQTT: case SVR_HTTP_SDK: *reply += "LED is now blinking "; *reply += rparam.requestval; *reply += " times."; *reply += "\n"; break; } break; case Get_SENSORS: //Create JSON return string if(servertype == SVR_HTTP_LIB) { *reply += "Content-Type: application/json\r\n\r\n"; } jsonEncode(FIRSTJSON,reply ,"Ain0", Ain0); jsonEncode(NEXTJSON,reply ,"Ain1", Ain1); jsonEncode(NEXTJSON,reply ,"Ain2", Ain2); jsonEncode(NEXTJSON,reply ,"Ain3", Ain3); jsonEncode(NEXTJSON,reply ,"Ain4", Ain4); jsonEncode(NEXTJSON,reply ,"Ain5", Ain5); jsonEncode(NEXTJSON,reply ,"Ain6", Ain6); jsonEncode(NEXTJSON,reply ,"Ain7", Ain7); v = system_get_free_heap_size(); jsonEncode(NEXTJSON,reply ,"SYS_Heap", v); v = millis()/1000; jsonEncode(LASTJSON,reply ,"SYS_Time", v); break; case BERTL_REQUEST: *reply += BertlSendReceive(BertlRequest); break; case INVALID_REQUEST: default: switch(servertype) { case SVR_HTTP_LIB: //httpClient.stop(); complete=true; busy = false; //httpClient.flush(); break; case SVR_COAP: case SVR_MQTT: case SVR_HTTP_SDK: default: break; } *reply += "Invalid Request\n"; break; } //return s ; } /******************************************************** * Connect to MQTT broker - then subscribe to server topic * Function: MqttServer_reconnect(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void MqttServer_reconnect(void) { int fst=10; bool connected = false; // Loop until we're reconnected (give up after 10 tries) while (!client.connected()&&(fst!=0)) { Serial.print("Attempting MQTT connection..."); // Connect to MQTT Server if(mqtt_pw_enable) { connected = client.connect(mqtt_ci.c_str(),mqtt_un.c_str(),mqtt_pw.c_str()); } else { connected = client.connect(mqtt_ci.c_str()); } if (connected) { // Successful connection message & subscribe Serial.println("connected"); client.subscribe((char *)mqtt_rt.c_str()); fst--; } else { // Failed to connect message Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } /******************************************************** * MQTT server topic callback * Function: MqttServer_callback(char* topic, * byte* payload, * unsigned int length) * * Parameter Description * --------- --------------------------------------- * topic topic string * payload value received * length value length (bytes) * return no return value ********************************************************/ void MqttServer_callback(char* topic, byte* payload, unsigned int length) { String payld = ""; char* pReply = NULL; RQST_Param rparam; pReply = (char *)os_zalloc(512); // Extract payload for (int i = 0; i < length; i++) { payld = payld + String((char)payload[i]); } //Msg rx message if(!bertl_server) { Serial.println(F("-------------------------------------")); Serial.print(F("MQTT Message Rx: topic[")); Serial.print(topic); Serial.print("] \r\nPayload:"); Serial.println(payld); Serial.println(F("-------------------------------------")); } // Ignore if not Server Request if(String(topic) != mqtt_rt) { os_free(pReply); return; } payld += " HTTP\nConnection:"; Server_ProcessRequest(SVR_MQTT, (char*)payld.c_str(),(char*)pReply); os_free(pReply); pReply = NULL; payld = ""; } /******************************************************** * MQTT loop() service * Function: MqttServer_Processor(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void MqttServer_Processor(void) { if(wifi==1) { yield(); if (!client.connected()) { MqttServer_reconnect(); } client.loop(); yield(); } } /******************************************************** * Initialize MQTT Broker Parameters * Function: MqttServer_Init(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void MqttServer_Init(void) { if(wifi==1) { // Start Mqtt server & set callback client.setServer((char *)mqtt_svr.c_str(), mqtt_port); client.setCallback(MqttServer_callback); } } /******************************************************** * Send request to Bertl & wait for reply * Function: BertlSendReceive(String req) * * Parameter Description * --------- --------------------------------------- * req request string to Bertl * return reply string ********************************************************/ String BertlSendReceive(String req) { String fromBertl = ""; req += "."; // pe???: dot added for M0 non blocking serial communication Serial.println(req); long start = millis(); fromBertl = ""; return fromBertl; } void MonitorSerialLine() { if(bertl_server) { while (Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputString: SerialInString += inChar; // if the incoming character is a newline, set a flag // so the following code can process it if (inChar == '\n') { NewSerialLineRx = true; } } //Send Received String as MQTT Message if(NewSerialLineRx) { //If not server request, just forward Bertl Message to MQTT if(active_svr_rqst == SVR_NONE) { active_svr_rqst = SVR_MQTT; } Server_SendReply(active_svr_rqst, REPLY_TEXT, SerialInString); active_svr_rqst = SVR_NONE; SerialInString=""; NewSerialLineRx=false; } //Check for timeout for Bertl Server requests if(active_svr_rqst != SVR_NONE) { if(start_wait==0) start_wait = millis(); if( (millis() - start_wait) >5000 ) { //5 sec timeout SerialInString = "no bertl reply received"; Server_SendReply(active_svr_rqst, REPLY_TEXT, SerialInString); //Reset Request Parameters active_svr_rqst = SVR_NONE; start_wait=0; SerialInString=""; NewSerialLineRx=false; } } } } /******************************************************** * Initialize local Time * Function: init_LocalTime() * * Parameter Description * --------- --------------------------------------- * return none ********************************************************/ void init_GmtTime() { configTime(0, 0, "pool.ntp.org", "time.nist.gov"); Serial.print("\nWaiting for time"); /*while (!time(nullptr)) { Serial.print("."); delay(1000); } Serial.print("\r\nTime has been acquired from internet time service\r\nCurrent GMT: "); PE */ Serial.print("\r\nNO Time has been acquired from internet time service\r\nCurrent GMT: "); time_t now = time(nullptr); Serial.println(ctime(&now)); } /******************************************************** * Initialize Over the Wifi Firmware Updates * Function: init_FOTA() * * Parameter Description * --------- --------------------------------------- * return none ********************************************************/ void init_FOTA() { String buff; int pt; //Hostname defaults to esp8266-[ChipID] (no change to default, which is unique (ChipID = last 3 MAC HEX) //ArduinoOTA.setHostname("myesp8266"); //Set FOTA Network Port GetEepromVal(&buff, EEPROM_MQTT_PT, EEPROM_INT16); pt = atoi(buff.c_str()); ArduinoOTA.setPort(pt); //Set OTA authentication (password) GetEepromVal(&buff, EEPROM_FOTA_PW, EEPROM_CHR); ArduinoOTA.setPassword((char *)buff.c_str()); ArduinoOTA.onStart([]() { Serial.println("Start"); }); ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.print("FOTA Initialized using IP address: "); Serial.println(WiFi.localIP()); } /******************************************************** * Sketch setup() function: Executes 1 time * Function: setup(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void setup() { //Initialize ESP8266 Reset Timer os_timer_disarm(&ResetEspTimer); os_timer_setfn(&ResetEspTimer, (os_timer_func_t *)ResetEspTimerCallback, NULL); EEPROM.begin(512); #if EEPROM_INIT==1 InitEepromValues(); #endif SetSysCfgFromEeprom(); // Set Session Cfg from EEPROM Values Serial.begin(serial_baud); // Initialize serial port util_startWIFI(); // Connect to local Wifi #if SVR_TYPE==SVR_HTTP_SDK SdkWebServer_Init(http_port); // Start SDK based web server #endif #if MQTT_SVR_ENABLE==1 MqttServer_Init(); // Start MQTT Server #endif init_FOTA(); // Start FOTA Service init_GmtTime(); // Get GMT Time pinMode(LED_IND , OUTPUT); // Set Indicator LED as output digitalWrite(LED_IND, 0); // Turn LED off (Setup complete indicator) } /******************************************************** * Sketch loop() function: Executes repeatedly * Function: loop(void) * * Parameter Description * --------- --------------------------------------- * return no return value ********************************************************/ void loop() { util_startWIFI(); // Connect wifi if connection dropped #if MQTT_SVR_ENABLE==1 MqttServer_Processor(); // Service MQTT #endif ReadSensors(2500); // Read 1 sensor every 2.5 seconds or longer MonitorSerialLine(); // Service Bertl Messages ArduinoOTA.handle(); // Service FOTA Requests } /* * ESP Onboard red and blue LEDs * The RED Led is connected to Power, while the BLUE Led is connected to TX. * You can control the blue LED if you do not need the TX function. TX is actually GPIO1 and RX=GPIO3 * * #define LED_PIN 1 // blue led int ledPin = 2; // GPIO2 longLeg void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(ledPin, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } alternativ: int pin = 1;  //GPIO1 blue led- no serial!!! PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); //use pin as GPIO1 instead of UART TXD gpio_output_set(0, 0, 1 << pin, 0); // enable pin as output ... gpio_output_set(1 << pin, 0, 0, 0); // set pin high ... gpio_output_set(0, 1 << pin, 0, 0); // set pin low */