--- tags: Arduino --- # ESP32 NodeMCU-32S Wi-Fi study 不錯的資料: [ESP32教學](https://www.chosemaker.com/board/esp32/lesson-1/) [ESP32 Arduino: Soft AP and Station modes]( https://techtutorialsx.com/2021/01/04/esp32-soft-ap-and-station-modes/) [Create A Web Server w/ ESP32](https://electropeak.com/learn/create-a-web-server-w-esp32/) [Asynchronous HTTP web server](https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/) [ESP32 Basic Over The Air (OTA) Programming In Arduino IDE](https://lastminuteengineers.com/esp32-ota-updates-arduino-ide/) [ESP32 I2C Communication](https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/) [How to use ESP32 Dual Core with Arduino IDE](https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/) 回傳毫秒 ```c= time = millis(); ``` 重開機 ```c= ESP.restart(); ``` --- ## HW ![](https://i.imgur.com/lNWM5EN.png =450x) ![](https://i.imgur.com/QEBUrl2.png =550x) --- ## FW ### R/W flash 有512個位置,每個位置可以放一個byte(0~255) ```= #include <EEPROMh> ``` ```= EEPROM.begin(size); //宣告使用EEPROM size個位置 ``` ```= EEPROM.write(add,data); //全部寫完後: EEPROM.commit();//一次寫入 or EEPROM.end(); ``` ```= EEPROM.read(add); ``` ### I2C ```C= #include <Wire.h> uint8_t slave_address=0x55; uint8_t buffer[0x40]; uint8_t buffer_count; void i2c_ram_cmd_send(uint8_t start_address, uint8_t length) { Wire.beginTransmission(slave_address); Wire.write(start_address); Wire.endTransmission(); Wire.requestFrom(slave_address, length); } void setup() { // put your setup code here, to run once: Wire.begin(); Serial.begin(115200); while(!Serial); pinMode(5,OUTPUT); } void wait_data(uint8_t start_pos, uint8_t len) { buffer_count=0; while (Wire.available()) { buffer[start_pos+buffer_count] = Wire.read(); buffer_count = buffer_count + 1; if(buffer_count>=len) break; } } void loop() { // put your main code here, to run repeatedly: uint8_t cnt; uint16_t val; while(true) { if(digitalRead(5)) digitalWrite(5, LOW); else digitalWrite(5, HIGH); delay(1500); i2c_ram_cmd_send(0x00,0x20); wait_data(0x00,0x20); i2c_ram_cmd_send(0x20,0x20); wait_data(0x20,0x20); delay(500); wait_data(0x00, 0x00); //clear dummy Serial.println("-"); for(cnt=0;cnt<0x20;cnt+=2) { val=buffer[cnt]+buffer[cnt+1]*0x100; Serial.print(cnt/2); Serial.print("==>"); Serial.println(val); } Serial.println("**"); Serial.println(" "); } } ``` ### Dual core work ```c= TaskHandle_t Task1; TaskHandle_t Task2; void Task1code( void * pvParameters ){ Serial.print("Task1 running on core "); Serial.println(xPortGetCoreID()); for(;;){ Serial.println(xPortGetCoreID()); delay(1000); } } void Task2code( void * pvParameters ){ Serial.print("Task2 running on core "); Serial.println(xPortGetCoreID()); for(;;){ Serial.println(xPortGetCoreID()); delay(500); } } void setup() { // put your setup code here, to run once: Serial.begin(115200); xTaskCreatePinnedToCore( Task1code, /* Task Function */ "Task1", /* Name of the task */ 10000, /* Stack size in words */ NULL, /* Task input parameter */ 1, /* Priority of the task */ &Task1, /* Task handle. */ 0); /* Core where the task should run */ delay(500); xTaskCreatePinnedToCore( Task2code, /* Task function. */ "Task2", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ &Task2, /* Task handle */ 1); } void loop() { // put your main code here, to run repeatedly: } ``` ### Client 連接 ESP32的預設WIFI模式是STA模式(Client) ```c= #include "WiFi.h" const char* ssid="your statation"; const char* password="password"; bool check_Wifi_status() { int i=0; while(i++<20) { if(WiFi.status()==WL_CONNECTED) return true; delay(1000); Serial.print("Wifi status:"); Serial.println(WiFi.status()); } return false; } void setup() { // put your setup code here, to run once: Serial.begin(115200); WiFi.begin(ssid,password); if(check_Wifi_status()) { Serial.print("WiFi connect OK,local IP:"); Serial.println(WiFi.localIP()); } else { Serial.println("Wifi NG"); } } void loop() { // put your main code here, to run repeatedly: } ``` WiFi.status() return: - WL_CONNECTED: assigned when connected to a WiFi network ==>3 - WL_NO_SHIELD: assigned when no WiFi shield is present ==>255 - WL_IDLE_STATUS: it is a temporary status assigned when WiFi.begin() is called and remains active until the number of attempts expires (resulting in WL_CONNECT_FAILED) or a connection is established (resulting in WL_CONNECTED) ==>0 - WL_NO_SSID_AVAIL: assigned when no SSID are available ==>1 - WL_SCAN_COMPLETED: assigned when the scan networks is completed ==>2 - WL_CONNECT_FAILED: assigned when the connection fails for all the attempts=>4 - WL_CONNECTION_LOST: assigned when the connection is lost =>5 - WL_DISCONNECTED: assigned when disconnected from a network ==>6 ### Soft AP 相關函式: ```= bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4) ``` channel:WiFi網絡信道,可選值1~13; ssid_hidden是否對外隱藏SSID,0-不隱藏,1-隱藏 max_connection最大可接入數,可選值1~4 ```= bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) ``` ```= bool softAPdisconnect(bool wifioff = false) ``` 關閉當前AP,若wifioff為true則還將還原網絡設置 ### 建立Web Server,讓WiFi連線 ```= #include "WiFi.h" #include <WebServer.h> char *ssid="GGG"; char *password="GGGGGG"; int statuscode; String content; String room_id=""; char htmlstr[700]; int temp=0; int volt=0; //set web server port WebServer server(80); void handle_root() { snprintf(htmlstr,700, "<!DOCTYPE html>\ <html>\ <head>\ <title> GI GI BO BO!</title>\ <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\ </head>\ <body>\ <h1>STATUS:</h1>\ <p>Voltage: %d </p>\ <P>Temperature: %d </p>\ </body>\ </html>",temp,volt); server.send(200,"text/html",htmlstr); } void WebcreateServer() { server.on("/", handle_root); } bool check_Wifi_status() { int i=0; while(i++<20) { if(WiFi.status()==WL_CONNECTED) return true; delay(1000); Serial.print("Wifi status:"); Serial.println(WiFi.status()); } return false; } void setup() { // put your setup code here, to run once: Serial.begin(115200); WiFi.begin(ssid,password); if(check_Wifi_status()) { Serial.print("WiFi connect OK,local IP:"); Serial.println(WiFi.localIP()); //setup webserver WebcreateServer(); server.begin(); Serial.println("Server start"); } else { Serial.println("Wifi NG"); } } void loop() { // put your main code here, to run repeatedly: server.handleClient(); temp++; volt+=2; } ``` ![](https://i.imgur.com/ilYxSUG.png =120x)![](https://i.imgur.com/CeRiZNG.png =120x) 不同時間更新網頁,有不同的值 [使用snprintf()函式轉換動態字串、輸出ESP8266溫濕度網頁](https://swf.com.tw/?p=1159) ### Asynchronous HTTP web server 使用 [Installing the Asynchronous Web Server library](https://reacoda.gitbook.io/molemi-iot/introducing-the-nodemcu/display-the-dht11-sensor-reading-on-a-web-server-using-nodemcu./installing-dht-library-on-the-esp8266/installing-the-asynchronous-web-server-library) ```C= //web server AsyncWebServer server(80); const char root[] PROGMEM = R"rawliteral( <!DOCTYPE html> <html> <head> <title> GI GI BO BO!</title> <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> </head> <body> <h1>STATUS:</h1> <p>%Voltage% </p> <P>%Temperature% </p> </body> </html> )rawliteral"; String processor(const String& var) { String a; Serial.println(var); if(var=="Voltage") a="3200"; else if(var== "Temperature") a=3500; return(a); } void Task2code( void * pvParameters ){ Serial.print("Task2 running on core "); Serial.println(xPortGetCoreID()); server.on("/", HTTP_GET,[](AsyncWebServerRequest *request) { request->send_P(200, "text/html", root,processor); }); server.begin(); Serial.println("Server start"); while(true) { delay(1); } } ``` [ESP32 Arduino Tutorial HTTP server:1. Template processing](https://www.dfrobot.com/blog-1103.html) [IoT 練習 - ESP Web 介面溫溼度記錄器](https://blog.darkthread.net/blog/temp-humd-esp-web/) ### TCP client 連線 ```= #include "WiFi.h" #include <WebServer.h> const char *ssid="XXX"; const char *password="XXXXXX"; const IPAddress serverIP(192,168,0,5); uint16_t serverPort=9876; WiFiClient client; bool communiction_path; void setup() { // put your setup code here, to run once: communiction_path=false; Serial.begin(115200); Serial.print("connect. "); WiFi.begin(ssid,password); while(WiFi.status()!=WL_CONNECTED) { delay(500); Serial.print(". "); } Serial.println(". "); Serial.print("IP:"); Serial.println(WiFi.localIP()); Serial.print("access to server..."); if(!client.connect(serverIP,serverPort)) { Serial.println("fail"); } else { Serial.println("sucess"); client.print("START CONNECT TRANSMIT\r\n"); delay(10); while(client.connected()) { if(client.available()) { String line=client.readStringUntil('\n'); Serial.println(line); if(line=="CONNECT OK") { Serial.println("communication path ok"); communiction_path=true; break; } } } } } void loop() { // put your main code here, to run repeatedly: if(communiction_path) { while(client.connected()) { if(client.available()) { String line=client.readStringUntil('\n'); Serial.println(line); } } Serial.println("discoonct"); client.stop(); } delay(5000); } ``` @@@ **HTML:** ```htmlembedded= <!DOCTYPE html> -> 告訴瀏覽器是 HTML5網頁 <html> -> 表示html文件 <head> -> 標頭(宣告網頁資訊) <!-- 網頁的資訊 --> </head> <body> -->使用者看的內容 <!-- 網頁的內容 --> </body> </html> ``` ```htmlembedded= <head> <title>歡迎來到 GI GI BO BO !</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> ``` 看一下: [Tables Generator 線上製作產生表格 HTML、LaTeX、Markdown 原始碼](https://free.com.tw/tables-generator/)