---
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


---
## 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;
}
```

不同時間更新網頁,有不同的值
[使用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/)