/* krutaya doka: http://arduino.esp8266.com/versions/1.6.5-1160-gef26c5f/doc/reference.html curl -F "file=@css/dropdown.css;filename=/css/dropdown.css" 192.168.4.1/update server upload: https://github.com/jpswensen/ESP8266_WebGen/blob/master/AdvancedWebServerHuzzah_SPIFFS/AdvancedWebServerHuzzah_SPIFFS.ino // Функция ESP.deepSleep(microseconds, mode) // Прежим глубокого сна. Для аргумента mode WAKE_RF_DEFAULT, WAKE_RFCAL, WAKE_NO_RFCAL и WAKE_RF_DISABLED. // Контакт GPIO16 должен быть привязан к RST – чтобы вывести чип из режима глубокого сна. // Функция ESP.restart() Перезапускает процессор. // ADC_MODE(ADC_VCC); в самом начале * UPGRADE: https://github.com/julienrat/esp8266_update_from_spiffs/blob/master/update_from_spiffs.ino * * UPDATE: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/WebUpdate/WebUpdate.ino * * if (!f) { Serial.println("file open failed"); } Serial.println("====== Reading from SPIFFS file ======="); // write 10 strings to file for (int i=1; i<=10; i++){ String s=f.readStringUntil('\n'); Serial.print(i); Serial.print(":"); Serial.println(s); } stream.findUntil(char target, terminal) HTTP.on("/list",HTTP_GET, printDirectory); HTTP.on("/edit",HTTP_DELETE, handleDelete); HTTP.on("/edit",HTTP_PUT, handleCreate); HTTP.on("/edit",HTTP_POST, [](){ returnOK(); }, handleFileUpload); HTTP.onNotFound(handleNotFound); */ #include "FS.h" #include #include #include #include #include #include #include #include //Ticker Library const String DefaultConfig="\n" "soft=default\n" "autoupdate=yes\n" "server_update=http://lleo.me/ESP8266/index.php?ip={ip}&chip={chip}&CHIP={CHIP}&soft={soft}\n" "server_ping=http://home.lleo.me/ESP8266/index.php?ip={ip}&chip={chip}&CHIP={CHIP}&soft={soft}\n" "AP_name=ESP8266-{chip}\n" "AP_password="; const String DefaultINDEX="

Connect your WiFi for first time SPIFFS install

" "" "
Login: " "
Password: " "
"; #define DEFAULTPORT 80 String WIFICONNECT=""; String LOADED_CONFIG="NO"; String LOOPFILE=""; int8_t servopins[]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; Servo servo1,servo2,servo3,servo4,servo5,servo6,servo7,servo8,servo9,servo10,servo11; Ticker tim; unsigned int tim_count=0; unsigned int tim_motor_detach=0; unsigned int tim_LoopDelay=0; // unsigned int tim_PingCounter=0; void tim_engine() { tim_count++; if(tim_LoopDelay) tim_LoopDelay--; // if(tim_PingCounter) tim_PingCounter--; if(tim_motor_detach) { if(! --tim_motor_detach) { // Serial.println("\n --- detach all servo ---"); for(uint8_t i=0;i<11;i++) { if(servopins[i]!=-1) ServoDetach(String(i)); } } } } // ADC_MODE(ADC_VCC); ESP8266WiFiMulti wifiMulti; DNSServer DNS; ESP8266WebServer WEB( DEFAULTPORT ); // CF0("WEB_PORT",DEFAULTPORT); /* void WiFiEvent(WiFiEvent_t event) { Serial.printf("\n\t\t[WiFi-event: %d", event); switch(event) { case WIFI_EVENT_STAMODE_GOT_IP: Serial.println(" Connected IP: "+ WiFi.localIP().toString()+ " ]"); break; case WIFI_EVENT_STAMODE_DISCONNECTED: Serial.println(" Lost connection ]"); break; default: Serial.println(" ]"); break; } } */ void setup() { Serial.begin(115200); Serial.println("\n############### Restart #############"); SPIFFS.begin(); tim.attach(1,tim_engine); // 1 sec Serial.println(FullInfo()); // WiFi.onEvent(WiFiEvent); WIFIinit(); // init.txt start String start=CF("start"); if(start!="") { MOTO(start); } else { start=CF("startfile"); if(start!="") { MOTO(getfile(start)); } } // Serial.println("FILE `wifi_last.txt`:"+getfile("wifi_last.txt")); // Serial.println("MD5 `wifi_last.txt`:"+MD5file("wifi_last.txt")); load_loop("loop.txt"); // ================================================== попытка файла ================================================== if(WIFICONNECT!="") { String s=CF("server_ping"); if(s!="") { String otv=file_get_contents(REPER(s)); Serial.println(" ["+otv+"]"); } if(CF0("autoupdate")) UpgradeALL(); } // ================================================== попытка файла ================================================== WEB.on("/favicon.ico",HTTP_GET,WEBNAH); WEB.on("/generate_204",HTTP_GET,WEBNAH); WEB.on("/fwlink",HTTP_GET,WEBNAH); WEB.on("/v1/public/yql",HTTP_GET,WEBNAH); WEB.on("/gslb/",HTTP_GET,WEBNAH); WEB.on("/chat",HTTP_POST,WEBNAH); WEB.on("/time",HTTP_GET,[](){ idip("Time: "+String(tim_count)); }); WEB.on("/reset",HTTP_GET,[](){ ESP.reset(); }); WEB.on("/restart",HTTP_GET,[](){ ESP.restart(); }); WEB.on("/format",HTTP_GET,[](){ SPIFFS.format(); }); WEB.on("/PIN",HTTP_GET,[](){ String a=RE("a"); // Serial.print("\nPIN a="+a); if(a=="servo") { String n=RE("n"); String mode=RE("mode"); String s=a+n+" "+mode; if(mode=="attach") { String d=RE("d"); if(ServoAttached(n)) { ServoDetach(n); s+=" [detach] "; } s+" #"+d; if(ServoAttach(n,d.toInt())) return idip(s+" OK"); return idip(s+"ERROR"); } if(mode=="detach") { if( ! ServoAttached(n) ) return idip(s+=" [not attached]"); ServoDetach(n); if( ServoAttached(n) ) return idip(s+" OK"); return idip(s+" ERROR"); } if(mode=="go") { String x=RE("x"); ServoWrite(n,x.toInt()); return idip(s+" TO: "+x); } return idip("Error mode"); } if(a=="pinmode") { String d=RE("d"); byte dd=(d=="A0" ? A0 : d.toInt() ); String mode=RE("mode"); String s=a+" #"+d+" ["+String(dd)+"] "+mode; if(mode=="OUTPUT") pinMode(dd,OUTPUT); else if(mode=="INPUT") pinMode(dd,INPUT); else if(mode=="INPUT_PULLUP") pinMode(dd,INPUT_PULLUP); else return idip(s+" ERROR: unknown mode"); return idip(s+" OK"); } if(a=="pin") { String d=RE("d"); String mode=RE("mode"); String s=a+" #"+d+" "+mode; digitalWrite(d.toInt(),mode.toInt()); return idip(s+" OK"); } return idie("PIN error"); }); // File Manager System WEB.on("/FM",HTTP_POST,[]() { String a=RE("a"); if(a=="editsave") { String file=RE("file"); file.replace("..",""); String s=RE("plain"); if(s=="") return idie("Error length 0"); savefile(file,s); return otprav("clean('editor');salert('saved',300);"); } /* Serial.println("\nFM POST a="+a); HTTPUpload& upload = WEB.upload(); if(!WEB.args()) Serial.println("NO ARGS"); else { for(uint8_t i=0;i ["+WEB.argName(i)+"]=("+WEB.arg(i)+")"); } return idie("UPLOAD_FILE_END"); Serial.println("Upload status: "+String(upload.status)); if (upload.status == UPLOAD_FILE_START) { Serial.println("2"); String filename = upload.filename; Serial.printf("UPLOAD_FILE_START: %s\n", filename.c_str()); // if(!filename.startsWith("/")) { filename = "/" + filename; } // DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename); // fsUploadFile = SPIFFS.open(filename, "w"); // filename = String(); return idie("UPLOAD_FILE_START"); } else if (upload.status == UPLOAD_FILE_WRITE) { Serial.println("3"); //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize); // if (fsUploadFile) { fsUploadFile.write(upload.buf, upload.currentSize); } Serial.printf("UPLOAD_FILE_WRITE: %u\n", upload.currentSize); return idie("UPLOAD_FILE_WRITE"); } else if (upload.status == UPLOAD_FILE_END) { Serial.println("4"); // if (fsUploadFile) { fsUploadFile.close(); } // DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize); Serial.printf("UPLOAD_FILE_END: %u\n", upload.totalSize); if(!WEB.args()) Serial.println("NO ARGS"); else { for(uint8_t i=0;i ["+WEB.argName(i)+"]=("+WEB.arg(i)+")"); } return idie("UPLOAD_FILE_END"); } else { Serial.println("5"); Serial.printf("UPLOAD_ZX\n"); return idie("UPLOAD_XZ"); } */ }); WEB.on("/FM",HTTP_GET,[](){ String a=RE("a"); Serial.print("\nFM a="+a); if(a=="WIFIconn1") { savefile("wifi_last.txt",RE("net")+"\n"+RE("pass")); otprav("Reboot..."); ESP.restart(); } if(a=="WIFIconn") { String net=RE("net"); String pass=RE("pass"); String s="clean('wifipass'); idie('Reconnect to "+net+"');"; otprav(s); savefile("wifi_last.txt",net+"\n"+pass); if(WIFItryConnect(net,pass)) { Serial.println("========> CONNECT to `"+net+"`"); Serial.println("========> file `wifi_last.txt` saved: "); Serial.println( getfile("wifi_last.txt") ); return; } Serial.println("========> ERROR connect to `"+net+"`"); WIFItryMyConnect(); return idip("Error: Net: ["+net+"] / ["+pass+"]"); } if(a=="WiFi") { String s=""; int n=WiFi.scanNetworks(); if(n == 0) return otprav("salert('No Networks found',3000);"); for(int i=0; i" )+" 
"+WiFi.SSID(i)+"
("+WiFi.RSSI(i)+")"; } return otprav("idie(toTable('"+String(n)+" networks found',\""+njs(s)+"\"))"); } if(a=="Files") { // список файлов Dir dir = SPIFFS.openDir(""); String s=""; while(dir.next()) { String n=h(String(dir.fileName())); File f=dir.openFile("r"); s+=",'"+n+"':"+String(f.size(),DEC); } if(s=="") return otprav("salert('no files',2000)"); return otprav("TabFiles({"+s.substring(1)+"})"); } if(a=="Info") { return otprav("idie(toTable('System Info',\""+njs(FullInfo())+"\"))"); } if(a=="Restart") { otprav("salert('Reboot... ',10000); setTimeout('document.location.reload(true)',3000);"); return ESP.restart(); } if(a=="Upgrade") { return otprav("salert('Upgrade: "+String(UpgradeALL()?"OK":"ERROR")+"',2000)"); } String file=RE("file"); file.replace("..",""); if(a=="update"||a=="upgrade") { file.replace(".",""); if(file=="") file="firmware"; upgrade_url(CF("server_update")+file+".bin"); return; } if(a=="edit") { String F=file; F.toUpperCase(); if( F.endsWith(".JPG")||F.endsWith(".JPEG")||F.endsWith(".PNG")||F.endsWith(".GIF")||F.endsWith(".ICO")||F.endsWith(".SVG")) return idie("image",""); return otprav("EditFile(\""+njs(file)+"\",\""+njs(getfile(file))+"\")"); } if(a=="save"){ return idie("Save: "+RE("file")); } if(a=="del") { delfile(file); return otprav("clean(\"file_"+h(file)+"\"); salert(\"Delete: "+h(file)+"\",1000);"); } if(a=="upload") { String homeServer=CF("server_update"); file.replace("/",""); String o=""; if(file=="all.list") { Serial.println("========> UPLOAD LIST: ["+homeServer+file+"]"); String s=file_get_contents(homeServer+file); int i; while(i>=0) { i=s.indexOf("\n"); if(i<0) break; String fu=s.substring(0,i); o+="
"+fu+" "; if(fu!="" && ! fu.endsWith(".bin") && fu!="all.list") o+=file_upload_binary_o(homeServer+(homeServer.indexOf("?")>=0 ? "&file=" : "")+fu,fu); s=s.substring(i+1); } } else { Serial.println("========> UPLOAD BINARY: ["+homeServer+file+"]"); o+="
"+file+" "+file_upload_binary_o(homeServer+(homeServer.indexOf("?")>=0 ? "&file=" : "")+file,file); if(file=="loop.txt") load_loop(file); } return otprav("salert(\"Updated:
"+o+"\",2000);"); } return idie("FM error"); }); WEB.on("/AJAX",HTTP_GET,[](){ String a=RE("a"); Serial.print("\na="+a); if(a=="run") { String s=RE("s"); Serial.println(" RUN:"+s); MOTO(s); return otprav(""); } if(a=="read") { uint8_t d=RE0("d"); uint8_t x=digitalRead(d); Serial.println("Read #`"+String(d)+"`: "+x); return otprav(String(x)); } if(a=="aread") { uint8_t d=A0; // RE0("d"); uint16_t x=analogRead(d); Serial.println("Analog Read #`A0`: "+x); return otprav(String(x)); } if(a=="servo") { String id=RE("id"); uint8_t x=RE0("x"); Serial.println("Servo #`"+id+"` to #`"+String(x)+"`"); ServoWrite(id,x); return otprav(""); } if(a=="MOTO") { String file=RE("file"); Serial.println("MOTO: "+file); MOTO(getfile(file)); return otprav(""); } //http://192.168.2.60/AJAX?a=MOTO&file=SVET.txt /* if(a=="text") { String momma = CF("startfile"); return idie("ok: "+momma); } */ idip("Error a="+a); }); WEB.onNotFound([](){ WEBFILE(String(WEB.uri())); }); WEB.begin(); } int Loopi=0,Loopi2=0; void loop() { DNS.processNextRequest(); WEB.handleClient(); // if(PINGURL!="" && tim_PingCounter==0) { tim_PingCounter=10; } if(LOOPFILE!="" && tim_LoopDelay==0) { int loopstep=1; Loopi2=LOOPFILE.indexOf("\n",Loopi); if(Loopi2<0) { Loopi2=0; Loopi=0; } else { String M=LOOPFILE.substring(Loopi,Loopi2); if(M!="") { Serial.println("LOOP: ["+M+"]"); if(ARG(M,0)=="sleep") tim_LoopDelay=ARG(M,1).toInt(); else { loopstep=DOMOTO(M); // если wait или что-то еще ожидает Serial.println("LOOPSTEP == "+String(loopstep)); } } if(loopstep) Loopi=++Loopi2; } } } // ==================================================================== String RE(String n) { if(!WEB.args()) return ""; for(uint8_t i=0;i",">"); return s; } String FullInfo() { return REPER( "\nChip: {CHIP}" "\nSoft: {soft}" "\nServer Update: {server_update}" "\nAutoupdate: {autoupdate}" "\nChipID/FlashID: {chip}/{FlashChipId} {CpuFreq} MHz" "\nPower: {vcc} mV" "\nWiFi: "+(WIFICONNECT==""?"not connected, setup mode":WIFICONNECT)+"" "\n MAC: {macAddress}" "\n IP: {ip}:{WEB_PORT}" "\nServer: " "\n AP_name: {AP_name}" "\n AP_password: {AP_password}" "\n AP_MAC: {softAPmacAddress}" "\n soft_AP_IP: {softAPIP}" // "\n AP_mask: {AP_mask}" // "\n AP_ip: {AP_ip}" "\nSketchSize: {SketchSize} MD5: {getSketchMD5}" "\n FreeSketchSpace: {FreeSketchSpace}" "\n FreeHeap: {FreeHeap}" "\nFlash Size: {FlashChipSize} / {FlashChipRealSize} / {FlashChipSizeByChipId} bytes" "\n Flash mode: {flashmode}" "\n FlashChipSpeed: {FlashChipSpeed}" "\nCoreVersion: {CoreVersion}" "\nFullVersion: {FullVersion}" "\nBootVersion: {BootVersion}" "\nBootMode: {BootMode}" "\nResetReason: {ResetReason}" "\nResetInfo: {ResetInfo}" "\nCycles: {cycles}" "\nserver_ping: {server_ping}" "\nstartfile: {startfile}" "\nloopfile: {loopfile}" "\nFiles {Files_count}: {Files}" "\n" ); } String REPER(String s) { String l; l="{ip}"; if(s.indexOf(l)>=0) s.replace(l, WiFi.localIP().toString() ); l="{macAddress}"; if(s.indexOf(l)>=0) s.replace(l, String(WiFi.macAddress()) ); l="{softAPIP}"; if(s.indexOf(l)>=0) s.replace(l, WiFi.softAPIP().toString() ); l="{softAPmacAddress}"; if(s.indexOf(l)>=0) s.replace(l, String(WiFi.softAPmacAddress()) ); l="{FreeHeap}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFreeHeap(),DEC) ); l="{FreeSketchSpace}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFreeSketchSpace(),DEC) ); l="{SketchSize}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getSketchSize(),DEC) ); l="{chip}"; if(s.indexOf(l)>=0) s.replace(l, get_chip() ); l="{CHIP}"; if(s.indexOf(l)>=0) s.replace(l, get_CHIP() ); l="{FlashChipId}"; if(s.indexOf(l)>=0) { String c=String(ESP.getFlashChipId(),HEX); c.toUpperCase(); s.replace(l,c); } l="{FlashChipSize}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFlashChipSize(),DEC) ); l="{FlashChipRealSize}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFlashChipRealSize(),DEC) ); l="{FlashChipSpeed}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFlashChipSpeed(),DEC) ); l="{cycles}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getCycleCount(),DEC) ); l="{CoreVersion}"; if(s.indexOf(l)>=0) s.replace(l, ESP.getCoreVersion() ); l="{FullVersion}"; if(s.indexOf(l)>=0) s.replace(l, ESP.getFullVersion() ); l="{BootVersion}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getBootMode(),DEC) ); l="{BootMode}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getCycleCount(),DEC) ); l="{CpuFreq}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getCpuFreqMHz(),DEC) ); l="{FlashChipSizeByChipId}"; if(s.indexOf(l)>=0) s.replace(l, String(ESP.getFlashChipSizeByChipId(),DEC) ); l="{getSketchMD5}"; if(s.indexOf(l)>=0) s.replace(l, ESP.getSketchMD5() ); l="{ResetReason}"; if(s.indexOf(l)>=0) s.replace(l, ESP.getResetReason() ); l="{ResetInfo}"; if(s.indexOf(l)>=0) s.replace(l, ESP.getResetInfo() ); l="{flashmode}"; if(s.indexOf(l)>=0) { FlashMode_t m=ESP.getFlashChipMode(); s.replace(l, String(m==FM_QIO?"QIO" : m==FM_QOUT?"QOUT" : m==FM_DIO?"DIO" : m==FM_DOUT ? "DOUT" : "UNKNOWN") ); } l="{vcc}"; if(s.indexOf(l)>=0) { s.replace(l, String(ESP.getVcc(),DEC) ); } l="{Files}"; if(s.indexOf(l)>=0) { Dir dir=SPIFFS.openDir(""); String o=""; while(dir.next()) o+=" "+String(dir.fileName()); o.trim(); s.replace(l,o); } l="{Files_count}"; if(s.indexOf(l)>=0) { int k=0; Dir dir=SPIFFS.openDir(""); while(dir.next()) k++; s.replace(l,String(k)); } int a=0,b; while( 1 ) { a=s.indexOf("{FILE:"); if(a<0) break; b=s.indexOf("}",a+6); if(b<0) break; l=s.substring(a+6,b); l.trim(); s.replace(s.substring(a,b+1),getfile(l)); } a=0; while( 1 ) { a=s.indexOf("{",a); if(a<0) break; b=s.indexOf("}",a+1); if(b<0) break; l=s.substring(a+1,b); String lz=CF(l); s.replace("{"+l+"}",lz); a+=lz.length(); } return s; } bool delfile(String file) { file.replace("/",""); file="/"+file; uint8_t i=SPIFFS.remove(file); Serial.println("Delete file: "+file+" "+(i?"OK":"ERROR")); return i; } String getfile(String file) { file.replace("/",""); file="/"+file; File f=SPIFFS.open(file,"r"); if(!f) return ""; String s=f.readString(); f.close(); return s; } void savefile(String file, String s) { file.replace("/",""); file="/"+file; // https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino File f=SPIFFS.open(file,"w"); if(!f) return; char* data[120]; if(file.endsWith(".jpg") || file.endsWith(".png")) { // void serial_send(int serial_fd, char *data, int size) // f.write(0,40); // f,data, // f.write(0); // f,data, // f.write(0); // f,data, // f.write(0); // f,data, // f.write(0); // f,data, Serial.println("Can't write BINARY file: "+file); return; } else f.print(s); f.close(); } bool WIFItryConnect(String ssid,String pass) { //Serial.printf("Default hostname: %s\n", WiFi.hostname().c_str()); //WiFi.hostname("LLEO-TEST_02"); //Serial.printf("New hostname: %s\n", WiFi.hostname().c_str()); // WiFi.mode(WIFI_STA); // Serial.print("\nWiFi.status: "); Serial.println(WiFi.status()); // Serial.printf("\n Wi-Fi mode set to WIFI_STA %s\n", WiFi.mode(WIFI_STA) ? "" : "Failed!"); // Serial.printf("\n WiFi.getMode(): %d\n", WiFi.getMode()); // WiFi.mode(m): set mode to WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF // WiFi.getMode(): return current Wi-Fi mode (one out of four modes above) // Serial.printf("\n Connection status: %d\n", WiFi.status()); Serial.print("Try connecting to: "+ssid+" "); /* if(WiFi.status() == WL_CONNECTED) { Serial.print("Disconnecting WiFi"); WiFi.disconnect(false); WIFICONNECT=""; WiFi.disconnect(true); delay(2000); } */ WiFi.begin(ssid.c_str(),pass.c_str()); for(uint8_t i=0;i<10;i++) { Serial.print("."); delay(500); if(WiFi.status() == WL_CONNECTED) { Serial.println("Connected \"" +ssid+ "\" IP: " + WiFi.localIP().toString() ); WIFICONNECT=ssid; return 1; } if(WiFi.status() == WL_IDLE_STATUS) Serial.println("\n - - - when Wi-Fi is in process of changing between statuses"); if(WiFi.status() == WL_NO_SSID_AVAIL) Serial.println("\n - - - in case configured SSID cannot be reached"); if(WiFi.status() == WL_CONNECT_FAILED) Serial.println("\n - - - if password is incorrect"); // if(WiFi.status() == WL_DISCONNECTED) Serial.println("\n - - - if module is not configured in station mode"); } Serial.println(" ERROR connect to \"" +ssid+ "\"" ); return 0; } bool WIFItryMyConnect() { String s=getfile("wifi_last.txt"); if(s!="") { int i=s.indexOf("\n"); String ssid = s.substring(0,i++); String pass = s.substring(i); Serial.println("Try to connect last WiFi: "+ssid); if( WIFItryConnect(ssid,pass) ) return 1; } return 0; } bool WIFIinit() { if(WIFItryMyConnect()) return 1; if(WIFItryConnect("LLeoNet","trololo123")) return 1; // резервная сетка // перепробовать все известные нам сети /* String s=getfile("wifi_list.txt"); Serial.println("\nLoad: "+s); if(s!="") { int i=0,i0=0; String wifi_net=""; String wifi_pass=""; while(i>=0) { i=s.indexOf("\n\n",i); if(i<0) break; i0=s.indexOf("\n",i+=2); if(i0<0) break; wifi_net=s.substring(i,i0); wifi_pass=s.substring(i0+=1,s.indexOf("\n",i0)); Serial.println("NETWORK: ["+wifi_net+"] PASSWORD: ["+wifi_pass+"]"); wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); } Serial.println("Connecting Wifi list..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println("\nWiFi network \""+WiFi.SSID()+"\" connected IP: "+WiFi.localIP().toString() ); return 1; } } */ // а иначе - создать точку доступа свою String AP_name=CF("AP_name"); String AP_password=CF("AP_password"); // String AP_mask=CF("AP_mask"); // String AP_ip=CF("AP_ip"); Serial.println("Create WiFi-network '"+AP_name+"' password: '"+AP_password+"'"); // : IP:"+AP_ip+" MASK:"+AP_mask); WiFi.mode(WIFI_AP); // IPAddress ipsmask( ARG(AP_mask,0,".").toInt() , ARG(AP_mask,1,".").toInt() , ARG(AP_mask,2,".").toInt() , ARG(AP_mask,3,".").toInt() ); // IPAddress ips( ARG(AP_ip,0,".").toInt() , ARG(AP_ip,1,".").toInt() , ARG(AP_ip,2,".").toInt() , ARG(AP_ip,3,".").toInt() ); // WiFi.softAPConfig(ips,ips,ipsmask); if(AP_password!="") WiFi.softAP(AP_name.c_str(),AP_password.c_str()); else WiFi.softAP(AP_name.c_str()); delay(500); // Without delay I've seen the IP address blank Serial.println("Connected: "+WiFi.softAPIP().toString() ); DNS.setErrorReplyCode(DNSReplyCode::NoError); DNS.start(53,"*",WiFi.softAPIP()); Serial.println("\n\n"+FullInfo()); return 0; } String get_CHIP() { String l=CF("NAME"); return (l!="" ? l : get_chip() ); } String get_chip() { String l=String(ESP.getChipId(),HEX); l.toUpperCase(); return l; } String file_upload_binary_o(String url,String file) { int i=file_upload_binary(url,file); if(i!=0) return "ERROR #"+String(i)+""; return "OK"; } int8_t file_upload_binary(String url,String file) { if(inStopList(file)) return 0; int8_t res=0; HTTPClient http; http.setTimeout(5000); http.begin(url.c_str()); // Serial.println("File_UPLOAD_BINARY_contents: "+url+" "); int c = http.GET(); if(c == HTTP_CODE_OK) { file.replace("/",""); file="/"+file; // https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino File f=SPIFFS.open(file,"w"); if(!f) res=-3; else { int len = http.getSize(); // create buffer for read uint8_t buff[128] = { 0 }; // get tcp stream WiFiClient * stream = http.getStreamPtr(); // read all data from server while (http.connected() && (len > 0 || len == -1)) { // get available data size size_t size = stream->available(); if(size) { // read up to 128 byte int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); // write it to f f.write(buff, c); if(len > 0) len -= c; } delay(1); } } f.close(); } else { res=-1; Serial.printf("\terror #%d: %s\n", c, http.errorToString(c).c_str()); } http.end(); return res; } String file_get_contents(String url) { HTTPClient http; http.setTimeout(5000); http.begin(url.c_str()); Serial.println("File_get_contents: ["+url+"]"); int c = http.GET(); String s=""; if(c == HTTP_CODE_OK) s=http.getString(); else Serial.printf("\terror #%d: %s\n", c, http.errorToString(c).c_str()); http.end(); return s; } bool ServoDetach(String n) { if(!ServoAttached(n)) return 0; uint8_t ni=servopins[n.toInt()]; if(n=="1") { servo1.detach();/* pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="2") { if(ni!=-1) servo2.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="3") { if(ni!=-1) servo3.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="4") { if(ni!=-1) servo4.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="5") { if(ni!=-1) servo5.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="6") { if(ni!=-1) servo6.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="7") { if(ni!=-1) servo7.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="8") { if(ni!=-1) servo8.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="9") { if(ni!=-1) servo9.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="10") { if(ni!=-1) servo10.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else if(n=="11") { if(ni!=-1) servo11.detach(); /*pinMode(ni,OUTPUT); digitalWrite(ni,0);*/ } else Serial.print(" error N"); return ServoAttached(n); } bool ServoAttach(String n, uint8_t d) { uint8_t i=n.toInt(); if(i<1 || i>6) { Serial.println(" error N"); return -1; } if(ServoAttached(n)) return 1; if(n=="1") servo1.attach(d); else if(n=="2") servo2.attach(d); else if(n=="3") servo3.attach(d); else if(n=="4") servo4.attach(d); else if(n=="5") servo5.attach(d); else if(n=="6") servo6.attach(d); else if(n=="7") servo7.attach(d); else if(n=="8") servo8.attach(d); else if(n=="9") servo9.attach(d); else if(n=="10") servo10.attach(d); else if(n=="11") servo11.attach(d); servopins[i]=d; tim_motor_detach=3; return ServoAttached(n); } void ServoWrite(String n, int x) { int i=n.toInt(); if(i<1 || i>6) { Serial.println(" error N"); return; } tim_motor_detach=2; ServoAttach(n,servopins[i]); Serial.println("... ServoWrite("+n+":"+String(servopins[i])+") = "+String(x)); if(n=="1") servo1.write(x); else if(n=="2") servo2.write(x); else if(n=="3") servo3.write(x); else if(n=="4") servo4.write(x); else if(n=="5") servo5.write(x); else if(n=="6") servo6.write(x); else if(n=="7") servo7.write(x); else if(n=="8") servo8.write(x); else if(n=="9") servo9.write(x); else if(n=="10") servo10.write(x); else if(n=="11") servo11.write(x); } bool ServoAttached(String n) { int i=-1; if(n=="1") i=servo1.attached(); else if(n=="2") i=servo2.attached(); else if(n=="3") i=servo3.attached(); else if(n=="4") i=servo4.attached(); else if(n=="5") i=servo5.attached(); else if(n=="6") i=servo6.attached(); else if(n=="7") i=servo7.attached(); else if(n=="8") i=servo7.attached(); else if(n=="9") i=servo8.attached(); else if(n=="10") i=servo10.attached(); else if(n=="11") i=servo11.attached(); else { Serial.print(" error N"); return 0; } // Serial.println("\n ... ServoAttach("+n+") = "+i); return i; } void MOTO(String s) { if(s=="") return; s.replace(";","\n"); int i; while(i>=0) { i=s.indexOf("\n"); if(i<0) { if(s.length()) DOMOTO(s); break; } DOMOTO(s.substring(0,i)); s=s.substring(i+1); } } bool DOMOTO(String s) { s=nocomments(s); s.trim(); if(s=="") return 1; String cmd=ARG(s,0); if(cmd=="stop") { LOOPFILE=""; Serial.println("STOP LOOP"); return 1; } if(cmd=="loop") { String a=ARG(s,1); if(a=="") a="loop.txt"; Serial.println("START LOOP: "+a); load_loop(a); return 1; } if(cmd=="ping") { String url=REPER(ARG(s,1)); String otv=file_get_contents(url); Serial.println("PING: " + url + " = ["+otv+"]"); MOTO(otv); return 1; } if(cmd=="attach") { ServoAttach( ARG(s,1), ARG(s,2).toInt() ); return 1; } if(cmd=="detach") { ServoDetach( ARG(s,1) ); return 1; } if(cmd=="go") { ServoWrite( ARG(s,1), ARG(s,2).toInt() ); return 1; } if(cmd=="pinmode") { uint8_t d=ARG(s,1).toInt(); String mode=ARG(s,2); if(mode=="INPUT_PULLUP") pinMode(d,INPUT_PULLUP); else if(mode=="INPUT") pinMode(d,INPUT); else pinMode(d,OUTPUT); return 1; } if(cmd=="pin") { digitalWrite(ARG(s,1).toInt(),ARG(s,2).toInt()); return 1; } if(cmd=="delay") { delay(ARG(s,1).toInt()); return 1; } if(cmd=="run") { MOTO(getfile(ARG(s,1))); return 1; } if(cmd=="wait") { // wait 2 < 10 uint8_t port=ARG(s,1).toInt(); String z=ARG(s,2); uint16_t v=ARG(s,3).toInt(); uint16_t x; bool e; if(z == "=") { x=digitalRead(port); e=(x == v ? 0 : 1 ); } else if(z == "!=") { x=digitalRead(port); e=(x != v ? 0 : 1 ); } else { x=analogRead(A0); if(z == ">") e=(x > v ? 0 : 1 ); else if(z == ">=") e=(x >= v ? 0 : 1 ); else if(z == "<") e=(x < v ? 0 : 1 ); else if(z == "<=") e=(x <= v ? 0 : 1 ); else { Serial.println("Error WAIT: "+s); return 1; } } // Serial.println(" . . . . WAIT: port `"+String(1*port)+"` ["+String(x)+"] "+z+" ("+String(v)+") --> "+String(e) ); return e; } MOTO(getfile(cmd)); return 1; } String ARG(String s,int n,String sep) { int i=0;for(int j=0;j=0) { s=s.substring(0,j); s.trim(); } return s; } String CF(String v,String D) { if(LOADED_CONFIG=="NO") { LOADED_CONFIG=getfile("config.txt"); if(LOADED_CONFIG=="") LOADED_CONFIG=DefaultConfig; LOADED_CONFIG.replace("\t"," "); LOADED_CONFIG.replace("\r",""); LOADED_CONFIG=LOADED_CONFIG+"\n"; } int i=0,i2; while(i>=0) { i2=LOADED_CONFIG.indexOf("\n",i); if(i2<0) break; String c=LOADED_CONFIG.substring(i,i2); i=++i2; c=nocomments(c); if(c=="") continue; int r=c.indexOf("="); if(r<0) continue; String n = c.substring(0,r); n.trim(); if(n!=v) continue; c=c.substring(r+1); c.trim(); if(c.indexOf("{")>=0) c=REPER(c); return c; } return D; } int CF0(String v,int D) { String c=CF(v,""); c.toUpperCase(); if(c=="NO"||c=="FALSE") c="0"; else if(c=="YES"||c=="TRUE") c="1"; return (c==""?D:c.toInt()); } String CF(String v) { return CF(v,""); } int CF0(String v) { return CF0(v,0); } void load_loop(String s) { Loopi=0; Loopi2=0; tim_LoopDelay=0; LOOPFILE=CF("loop"); if(LOOPFILE!="") LOOPFILE.replace(";","\n"); else { // String s=CF("loopfile"); if(s!="") LOOPFILE=getfile(s); } if(LOOPFILE!="") LOOPFILE+="\n"; } String StopWebList="NO"; String StopList="NO"; bool inStopWEBList(String file) { if(StopWebList=="NO") StopWebList=getfile("stopweblist.txt"); if(StopWebList=="") return 0; return inStop(StopWebList,file); } bool inStopList(String file) { if(StopList=="NO") StopList=getfile("stoplist.txt"); if(StopList=="") return 0; return inStop(StopList,file); } bool inStop(String s,String file) { file.replace("/",""); file="/"+file; int i=0; while(1) { String l=ARG(s,i++,"\n"); if(l=="") return 0; if(file.startsWith(l)) { Serial.println("Deprecated file: `"+file+"`"); return 1; } } return 0; } bool upgrade_url(String file) { if(inStopList(file)) return 0; t_httpUpdate_return ret; Serial.println("Update new sketch "+file); pinMode(2,OUTPUT);digitalWrite(2,0); // ВКЛЮЧИТЬ ЛАМПУ ESPhttpUpdate.rebootOnUpdate(true); ret = ESPhttpUpdate.update(file); digitalWrite(2,1); // ПОГАСИТЬ ЛАМПУ switch(ret) { case HTTP_UPDATE_FAILED: { String err=ESPhttpUpdate.getLastErrorString(); if(err.indexOf("reset")>=0) { idip("Press RESET and repeat!"); ESP.reset(); break; } idip("UPDATE ERROR ["+file+"]: "+err); break; } case HTTP_UPDATE_NO_UPDATES: idip("HTTP_UPDATE_NO_UPDATES"); break; case HTTP_UPDATE_OK: idip("HTTP_UPDATE_OK"); break; default: idip("OTHER"); break; } } bool UpgradeALL() { String s=CF("server_update"); if(s=="") return 0; String otv=file_get_contents(REPER(s)); // Serial.print(" ["+otv+"]"); if(ARG(otv,0,"\n")!="OK") return 0; String firmware_md5=""; int i=1; while(1) { String s=ARG(otv,i++,"\n"); if(s=="") break; String file=ARG(s,0," "); String md5=ARG(s,1," "); if(file=="firmware.bin") { firmware_md5=md5; continue; } if(MD5file(file)==md5) continue; Serial.print("UPDATE "+file+": "); int i=file_upload_binary(CF("server_update")+"&file="+file,file); if(i==0 && MD5file(file)==md5) Serial.println("OK"); else Serial.println("ERROR #"+String(i)); } if(firmware_md5 != "" && firmware_md5 != ESP.getSketchMD5() ) { Serial.println("firmware.bin need to UPDATE"); upgrade_url(CF("server_update")+"&file=firmware.bin"); } return 1; }