1. Arduino IDE配置ESP8266環境
參考:https://www.jianshu.com/p/cb0274d612b5
首先從 Arduino 官網 下載最新版本的 Arduino IDE 軟件並安裝。
安裝完成以后,進入首選項(Preferences),找到附加開發板管理器地址(Additional Board Manager URLs),並在其后添加如下信息:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
再點擊確定(OK);
之后點擊工具 - 開發板 - 開發板管理器,進入開發板管理器界面:
輸入esp, 找到 esp8266 並安裝;
筆者在安裝過程中發現下載速度太慢,於是去esp8266 arduino的github頁面(https://github.com/esp8266/Arduino/releases)下載了壓縮包(筆者用的2.6.0),再放進C盤就可以了,下面是詳細步驟:
https://github.com/earlephilhower/esp-quick-toolchain/releases?after=3.0.0-gnu5
筆者將這6個壓縮包放至了百度網盤,解壓后放進這個文件夾;
鏈接:https://pan.baidu.com/s/1hX45SsujWOyPKyntA6fDkQ
提取碼:8266
然后在開發板管理器上,輸入esp, 找到 esp8266 即可快速安裝~
2. 燒寫程序方法
參考:http://www.elecfans.com/dianzichangshi/20171123584883.html
將ESP8266與USB-TTL按照下面的接線圖進行連接。最好使用下面這種免冷啟動的(那種冷啟動的下載器可能下載不了程序)。
UTXD—–RXD
URXD—–TXD
CH_PD—-3.3v
VCC——-3.3V
GND——GND
GPIO0—–GND
將連接好ESP8266的USB-TTL插在電腦上,對IDE進行如下設置:
你可以上傳ESP8266WIFI的相關程序了。
注意事項
1.esp8266-01板對電壓的要求很高,燒寫時電源一定要采用3.3V左右。
2.如果代碼無法上傳,並顯示警告,請檢查USB-TTL是否良好(某些USB-TTL燒寫時無法打開串口,導致上傳失敗)。
3.ESP8266與USB-TTL需要RX,TX交叉連接。
4.CH_PD這個引腳無論是燒程序也好,燒完程序應用也好,都要接3.3V。
5.GPIO0這個引腳在燒程序的時候必須接GND(接低電平),燒完程序后想要進行應用的話,必須將這個引腳拉高或者懸空。
3. WiFi控制舵機程序
(1)電路原理圖
(2)Arduino代碼
/*
* nodemcu引腳對應數字:
* 16=D0;
* 4=D2;
* 0=D3;
* 2=D4;
* 14=D5;
* 12=D6;
* 13=D7;
* 15=D8;
* 3=D9;
* 1=D10;
* ESP-01引腳對應數字:
* GPIO2 --2 舵機 -> 模擬量輸出
* GPIO16--16 繼電器 -> 開關量輸出
*/
#include <ESP8266WiFi.h> #include <Servo.h> #ifndef STASSID #define STASSID "填寫你的WiFi名稱" //WiFi名稱 #define STAPSK "填寫你的WiFi密碼" //WiFi密碼 #endif #define ANGLE_ON 76 //開燈時的舵機角度 #define ANGLE_OFF 153 //關燈時的舵機角度 #define ANGLE_NONE 110 //置空時的舵機角度 const char* ssid = STASSID; const char* password = STAPSK; int angle=ANGLE_NONE;//舵機角度 Servo myservo; //創造一個servo結構體 //創建服務器實例,指定要監聽的端口為80端口 WiFiServer server(80); void setup() { Serial.begin(115200); myservo.attach(4); //舵機信號線,接analogIn腳 myservo.write(angle);// 0~180° //連接WiFi Serial.println(); Serial.println(); Serial.print(F("WiFi start connect "));//用F函數將會把字符串放入RAM中,輸出至串口 Serial.println(ssid); WiFi.mode(WIFI_STA);//設置為接收WiFi模式 WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print(F(".")); } Serial.println(); Serial.println(F("WiFi已連接!")); //開啟模塊的服務器 server.begin(); Serial.println(F("模塊服務端已開啟!")); //打印模塊的IP地址 Serial.println(WiFi.localIP()); } void loop() { //監測客戶端是否連接 WiFiClient client = server.available(); if (!client) { return;//如果未連接就重新循環監測 } // Serial.println(F("new client")); client.setTimeout(1000); // default is 1000 //讀取請求內容的第一行 String req = client.readStringUntil('\r'); Serial.println(F("請求: ")); Serial.println(req); //匹配 請求-->信號變量 if (req.indexOf(F("/gpio/0")) != -1) { angle = ANGLE_ON;//如果/gpio/0在請求內容中,發出開燈的信號 myservo.write(angle);// 0~180° delay(1000); myservo.write(ANGLE_NONE);//將舵機重新置空,以免一直受力損壞 } else if (req.indexOf(F("/gpio/1")) != -1) { angle = ANGLE_OFF; myservo.write(angle);// 0~180° delay(1000); myservo.write(ANGLE_NONE);//將舵機重新置空,以免一直受力損壞 } else { Serial.println(F("無效請求")); } //讀取或忽略余下的請求內容 while (client.available()) { client.read(); } //向客戶端發送回答,HTML網頁代碼內容 //nagle算法會將它們分組為一個數據包 client.print(F("<!DOCTYPE html>\r\n<html xmlns='http://www.w3.org/1999/xhtml'>\r\n")); client.print(F("<head>\r\n<meta charset='utf-8'/>\r\n<title>智能卧室燈</title>\r\n")); client.print(F("<style type='text/css'>.state{text-align:center;font-size:80px;}")); client.print(F(".on{text-align:center;font-size:200px;alink='#1a9e5f'}.off{text-align:center;font-size:200px;alink='#da4f43'}")); client.print(F("</style><body><div class='state'>燈狀態:")); client.print((angle>ANGLE_NONE) ? F("關</div>") : F("開</div>")); client.print(F("<br><br><div class='on'><a href='http://"));//<br>換行 client.print(WiFi.localIP()); client.print(F("/gpio/0'>開</a></div><br><br><div class='off'><a href='http://")); client.print(WiFi.localIP()); client.print(F("/gpio/1'>關</a></div></body></html>")); // 客戶端實際上將被“刷新”,然后斷開連接 // 當函數返回並且“客戶端”對象被銷毀時 // 刷新=確保書面數據被服務端接收 Serial.println(F("客戶端已掛起!")); }
4. 繼電器控制
(1)電路原理圖
(2)Arduino程序
/* * nodemcu引腳對應數字: * 16=D0; * 4=D2; * 0=D3; * 2=D4; * 14=D5; * 12=D6; * 13=D7; * 15=D8; * 3=D9; * 1=D10; * ESP-01引腳對應數字: * GPIO2 --2 舵機 ->模擬輸出 * GPIO16--16 開關 */ #include <ESP8266WiFi.h> #ifndef STASSID #define STASSID "填寫你的WiFi名稱" //WiFi名稱 #define STAPSK "填寫你的WiFi密碼" //WiFi密碼 #endif #define SW_Pin 2 //輸出開關腳 #define ON 1 //開關狀態 #define OFF 0 //開關狀態 const char* ssid = STASSID; const char* password = STAPSK; int state = ON; //開關狀態 //創建服務器實例,指定要監聽的端口為80端口 WiFiServer server(80); void setup() { Serial.begin(115200); pinMode(SW_Pin,OUTPUT); digitalWrite(SW_Pin, ON);//先開啟 //連接WiFi Serial.println(); Serial.println(); Serial.print(F("開始連接"));//用F函數將會把字符串放入RAM中,輸出至串口 Serial.println(ssid); WiFi.mode(WIFI_STA);//設置為接收WiFi模式 WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print(F(".")); } Serial.println(); Serial.println(F("WiFi已連接!")); //開啟模塊的服務器 server.begin(); Serial.println(F("模塊服務端已開啟!")); //打印模塊的IP地址 Serial.println(WiFi.localIP()); } void loop() { //監測客戶端是否連接 WiFiClient client = server.available(); if (!client) { return;//如果未連接就重新循環監測 } // Serial.println(F("new client")); client.setTimeout(1000); // default is 1000 //讀取請求內容的第一行 String req = client.readStringUntil('\r'); Serial.println(F("請求: ")); Serial.println(req); //匹配 請求-->信號變量 if (req.indexOf(F("/gpio/0")) != -1) { state = ON;//如果/gpio/0在請求內容中,發出開燈的信號 digitalWrite(SW_Pin,HIGH);//開燈 } else if (req.indexOf(F("/gpio/1")) != -1) { state = OFF;//如果/gpio/1在請求內容中,發出關燈的信號 digitalWrite(SW_Pin,LOW);//關燈 } else { Serial.println(F("無效請求")); } //讀取或忽略余下的請求內容 while (client.available()) { client.read(); } //向客戶端發送回答,HTML網頁代碼內容 //nagle算法會將它們分組為一個數據包 client.print(F("<!DOCTYPE html>\r\n<html xmlns='http://www.w3.org/1999/xhtml'>\r\n")); client.print(F("<head>\r\n<meta charset='utf-8'/>\r\n<title>智能卧室燈</title>\r\n")); client.print(F("<style type='text/css'>.state{text-align:center;font-size:80px;}")); client.print(F(".on{text-align:center;font-size:200px;alink='#1a9e5f'}.off{text-align:center;font-size:200px;alink='#da4f43'}")); client.print(F("</style><body><div class='state'>燈狀態:")); client.print((state==OFF) ? F("關</div>") : F("開</div>")); client.print(F("<br><br><div class='on'><a href='http://"));//<br>換行 client.print(WiFi.localIP()); client.print(F("/gpio/0'>開</a></div><br><br><div class='off'><a href='http://")); client.print(WiFi.localIP()); client.print(F("/gpio/1'>關</a></div></body></html>")); // 客戶端實際上將被“刷新”,然后斷開連接 // 當函數返回並且“客戶端”對象被銷毀時 // 刷新=確保書面數據被服務端接收 Serial.println(F("客戶端已掛起!")); }
5. 手機WiFi控制開關
通過串口監視器(115200波特率)獲取到路由器分配給NodeMCU的IP地址,即可通過訪問網址來控制開/關燈 。
比如筆者這里讀取到的IP為192.168.0.143,那么
開燈時手機上訪問的網址為http://192.168.0.143/gpio/0;
關燈時手機上訪問的網址為http://192.168.0.143/gpio/1。
(手機需要和NodeMCU在同一個路由器下,即連接的是同一個WiFi)
需要注意的是ESP8266可能連不上手機熱點和5GWiFi,WiFi名字也最好不要帶中文。
6. 通過Blinker和小愛同學控制
/* * nodemcu引腳對應數字: * 16=D0; * 4=D2; * 0=D3; * 2=D4; * 14=D5; * 12=D6; * 13=D7; * 15=D8; * 3=D9; * 1=D10; * ESP-01引腳對應數字: * GPIO2 --2 舵機 ->模擬輸出 * GPIO16--16 開關 */ #define BLINKER_WIFI #define BLINKER_MIOT_LIGHT #include <Blinker.h> #define SW_Pin 2 //輸出開關腳 #define ON 1 //開關狀態 #define OFF 0 //開關狀態 char auth[] = "填寫key";// blinker APP申請得到的key char ssid[] = "填寫WiFi名稱";// WiFi名稱 char pswd[] = "填寫WiFi密碼";// WiFi密碼 // 新建組件對象 BlinkerButton Button1("btn-abc"); BlinkerNumber Number1("num-abc"); int counter = 0; // Blinker APP中的按鍵執行函數 void button1_callback(const String & state) { BLINKER_LOG("get button state: ", state); digitalWrite(SW_Pin, !digitalRead(SW_Pin)); } // 小愛同學的指令執行函數,中介選擇阿里雲才能用https://diandeng.tech/doc/xiaoai void miotPowerState(const String & state) { BLINKER_LOG("need set power state: ", state); if (state == BLINKER_CMD_ON) { digitalWrite(SW_Pin, OFF); BlinkerMIOT.powerState("off"); BlinkerMIOT.print(); } else if (state == BLINKER_CMD_OFF) { digitalWrite(SW_Pin, ON);// 將開關引腳置為高電平 BlinkerMIOT.powerState("on");// 反饋電源狀態為ON BlinkerMIOT.print();// 將以上屬性發送出去, 務必最后調用該函數 } } // 如果未綁定的組件被觸發,則會執行其中內容 void dataRead(const String & data) { BLINKER_LOG("Blinker readString: ", data); counter++; Number1.print(counter); } void setup() { // 初始化串口 Serial.begin(115200); BLINKER_DEBUG.stream(Serial); // 初始化LED的IO pinMode(SW_Pin,OUTPUT); digitalWrite(SW_Pin, ON);//先開啟 // 初始化blinker Blinker.begin(auth, ssid, pswd); Blinker.attachData(dataRead); Button1.attach(button1_callback); BlinkerMIOT.attachPowerState(miotPowerState); } void loop() { Blinker.run(); }
參考 https://blog.csdn.net/qq_32299035/article/details/104897710