前段時間做了一個激光雕刻,玩的不亦樂乎。對Arduino大感興趣,於是又入手一塊20大洋版,配上買學習套件時的諸多零件——紅外發射管、一體化紅外接收頭、DHT11溫濕度傳感器、ESP8266等,以及某寶來的LD3320、GP2Y1014AUOF准備搞一波屌絲智能家居。看了各種教程,感覺自己距離大神只差那么一丟丟了,於是在各種自我感覺良好中,掉下各種坑去……反正我是用一個模塊下一個坑,弄得現在有點不太敢測試顆粒物傳感器了……這個主要還是連接硬件和寫Arduino程序了,與上一個主要是寫上位機代碼不同——沒有那么多准確而深入的教程看的。所以,必要時擼一下官方文檔還是很有必要的。今天先說ESP軟串口通訊這個坑如何爬上來:
1、模塊:某寶買Arduino套件時送的某飛萊,當我敲SoftwareSerial wifi_SoftSerial后面的括號時隱約就看見了坑影憧憧……
2、學習:雖然谷哥死了十幾年了,但是我還是忍不住找不到有用的東西的時候吐槽。賣家給的教程先擼了一遍,發現確實RX,TX需要交換一下——無論是在代碼還是接線上都可以;然后有那么一丟丟連接wifi的代碼……之后各種度娘各種搜,然而各種參差不齊、說法不一的卵用不大的基礎教程並沒有什么真正的幫助,看了幾篇國外網站的問題帖子倒是解決了幾個問題。也許是我搜索時沒有目視正前方,抬頭挺胸,雙肩同高,兩腳與肩同寬,又或者椅子有點不太水平?總之,發過牢騷之后還得自己寫一點不成熟的邏輯,因為沒找到可以用的軟串口HTTP請求的庫,又沒有給軟轉促銷的決心……
所以,讓我們找一個AT命令詳解先打開。擼一遍之后,發現大體分這么幾個部分:
1、初始化這個開發板:並沒有什么其他接口,RX,TX,GND,VCC還是5V,反正我接了5V這么久沒燒。不用刷所以也不用下載什么開發板,修改什么開發環境,還是UNO就可以。命令主要就是這么幾條:
int initESP8266() { int result = 0; String val = ""; if (!DoATCommand("AT+CIPMODE=1", 1000, 10, "OK", val)) { result ++; } if (!DoATCommand("AT+RST", 1000, 100, "OK", val)) { result++; } if (!DoATCommand("AT+CIPMUX=0", 1000, 10, "ready", val)) { result++; } if (!DoATCommand("AT+CWMODE=1", 1000, 10, "OK", val)) { result++; } return result; }
就是客戶端、單鏈接、透傳模式什么的,參考AT文檔吧,這個有順序,注意一下。然后,這個函數返回了錯誤個數,但其實從來沒測試過,這樣過去就可以了,因為有的已經設置過或者各種我不懂的原因不成功也不影響后面。
2、連接WIFI:
bool initWifi(String ssid, String pwd) { String val = ""; //查詢是否連接到了指定的wifi if (DoATCommand("AT+CWJAP?", 1000, 10, ssid, val)) { return true; } //連接到WIFI if (!DoATCommand("AT+CWJAP=\"" + ssid + "\",\"" + pwd + "\"", 20000, 100, "OK", val)) { Serial.println("AT+CWJAP:ERROR:" + val); return false; } return true; }
這個函數也沒有太多內容,只是先判定是否已經連接了,否則就重連。
3、POST請求:
因為自己的主機早就到期,連個域名都不讓申請,所以申請了lewei50.com的服務,用起來比較簡單,免費用戶也沒有多少用到收費功能的地方,所以成本比較低咯:
//連接服務器 if (!DoATCommand("AT+CIPSTART=\"TCP\",\""+ Host + "\"," + HostPort , 10000, 500, "OK", val)) { if (val.indexOf("FAIL") >= 0) { Serial.println("AT+CIPSTART:ERROR:" + val); return false; } } //進入透傳模式 if (!DoATCommand("AT+CIPSEND=" + (String)postRequest.length(), 10000, 500, ">", val)) { Serial.println("AT+CIPSEND:ERROR:" + val); result = false; }else{ //POST請求 wifi_SoftSerial.println(postRequest); result = WaitSoftSerialResult(20000,"SEND OK",val); } //退出透傳模式 wifi_SoftSerial.print("+++"); delay(10); //關閉TCP/UDP連接 wifi_SoftSerial.print("AT+CIPCLOSE"); delay(10);
就是連接服務器,成功之后讓ESP8266進入收什么發什么模式……好吧,透傳模式,然后寫構造的POST請求內容,等待發送完成(當然,也可以等待對方返回正確返回值),之后退出透傳,關閉TCP連接。
關於POST請求構建這塊,各種說法各種都有,貴圈真亂!
//必要信息
struct sensor{
String Name;
String Value;
};
String Crlf = "\r\n";
sensor infos[] = { {"T1","22.33"},{"H1","44.55"} }; //傳感器名,數值 String Host = "www.lewei50.com"; //主機地址
String HostPort = "80";
String HostApiPath = "/api/V1/gateway/Updatesensors/01"; //API地址
String UserKey = "*****************************"; //用戶識別碼
//開始構建 String data = "["; int count = sizeof(infos) / sizeof(infos[0]); //設置發送數據 for (int i = 0; i<count; i++) { data += "{\"Name\":\"" + infos[i].Name + "\",\"Value\":\"" + infos[i].Value + "\"},"; } data = data.substring(0, data.length() - 1); data += "]"; String postRequest = (String)("POST") + " " + HostApiPath + " " + "HTTP/1.1" + Crlf + "userkey:" + UserKey + Crlf + "Accept:*/*" + Crlf + "Host: " + Host + Crlf + "Content-Length: " + data.length() + Crlf + "Connection: close" + Crlf + Crlf + data;
不多說,測試代碼就可以了。下一篇說說這個LD3320模塊,主要說說接線吧,好擼半小時官方文檔…各種教程各種圖片各種不匹配我也很無奈…測試時識別精度確實不高,容量確實不大,但能用代碼解決的就都不叫事兒。