跳到內容

ESP32教學與討論

許多感測器教學,有相關問題也可發表詢問

22 主題 23 貼文

子版面


  • 3 主題
    3 貼文
    adminA
    4.TDS Sensor-NB-IoT.pdf #include <WiFi.h> #include <Wire.h> #include "MatrixInt.h" //安裝方式:https://www.nmking.io/index.php/2022/12/15/701/ #define TdsSensorPin 33 //TDS感測器接入腳位GPIO 33 #define VREF 3.3 // analog reference voltage(Volt) of the ADC #define SCOUNT 30 // sum of sample point int analogBuffer[SCOUNT]; // store the analog value in the array, read from ADC int analogBufferTemp[SCOUNT]; int analogBufferIndex = 0; int copyIndex = 0; long WNB303Timeout = 10000; //返回0=Timeout int WNB303ResetPIN = 14; // 設定 WNB303 重置腳位為輸出腳位 int WNB303PowerPIN = 15; // 設定 WNB303 電源控制腳位為輸出腳位 float averageVoltage = 0; float tdsValue = 0; float temperature = 25; // 設定當前環境溫度 (計算PPM需使用溫度資訊) // median filtering algorithm int getMedianNum(int bArray[], int iFilterLen){ int bTab[iFilterLen]; for (byte i = 0; i<iFilterLen; i++) bTab[i] = bArray[i]; int i, j, bTemp; for (j = 0; j < iFilterLen - 1; j++) { for (i = 0; i < iFilterLen - j - 1; i++) { if (bTab[i] > bTab[i + 1]) { bTemp = bTab[i]; bTab[i] = bTab[i + 1]; bTab[i + 1] = bTemp; } } } if ((iFilterLen & 1) > 0){ bTemp = bTab[(iFilterLen - 1) / 2]; } else { bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2; } return bTemp; } // ------ 以下修改成你MQTT設定 ------ String MQTTServer = "mqttgo.io";//免註冊MQTT伺服器 String MQTTPort = "1883";//MQTT Port String MQTTUser = "";//不須帳密 String MQTTPassword = "";//不須帳密 //推播主題1:推播PPM(記得改Topic) String MQTTPubTopic = "YourTopic/class/TDSPPM"; long MQTTLastPublishTime = 0;//此變數用來記錄推播時間 long MQTTPublishInterval = 5000;//每5秒推撥一次 void setup() { Serial.begin(115200); // 設定序列埠監控視窗的鮑率 Serial2.begin(115200); // 設定 WNB303 的鮑率 Wire.begin(26, 27); // Matrix I2C for (int i = 0; i <= 7; ++i) MatrixInt(i, 0);//關閉所有燈號 pinMode(TdsSensorPin,INPUT); pinMode(WNB303ResetPIN, OUTPUT); // 設定 WNB303 電源控制腳位為輸出腳位 pinMode(WNB303PowerPIN, OUTPUT); // 設定 WNB303 重置腳位為輸出腳位 delay(1000); Serial.println("\r\n\r\n======================\r\nSystem Starting...."); String result = ""; // 開啟 Modem 的電源,開啟關閉之間須間隔10秒(延時電路) WNB303Restart(10); //檢查網路註冊狀態,5分鐘內無法註冊,則重新啟動WNB303 int tryCount = 0; while (1) { boolean resultb = WNB303CheckReg(); Serial.print("WNB303CheckNetReg result="); Serial.println(resultb); if (resultb == false) { Serial.println("時間內無法註冊網路(" + String(tryCount) + ")"); delay(10000); } else break; if (tryCount++ >= 30) { //無法註冊已經超過5分鐘 tryCount = 0; WNB303Restart(30); } } //檢查網路訊號品質 result = WNB303CheckRSSI(); Serial.print("WNB303CheckRSSI result="); Serial.println(result); delay(10000); } void loop() { ReadPPM(); //檢查時間,傳輸步驟:檢查網路、讀取距離、MQTT連線、推播、關閉 if ((millis() - MQTTLastPublishTime) >= MQTTPublishInterval ) { MatrixInt(7, 1); //沒有網路,則重新啟動WNB303 String result = ""; //檢查網路狀態 if (!(WNB303CheckReg())) { WNB303Restart(60); //60秒後重新檢測網路 return; }else result = WNB303CheckRSSI(); //連線mqtt result = mqttConnect(MQTTServer, MQTTPort, MQTTUser, MQTTPassword); if (result == "OK") Serial.println("MQTT Connected"); ReadPPM(); byte tds1 = 0; tds1 = tdsValue,0; String payload = String((int)tds1); //推播訊息 result = mqttPublish(MQTTPubTopic, "0", "0", "0", payload); if (result == "OK") Serial.println("Data:\"" + payload + "\" Published to " + MQTTPubTopic); //關閉mqtt result = mqttDisconnect(); if (result == "OK") Serial.println("MQTT Disconnected"); MQTTLastPublishTime = millis(); //更新最後傳輸時間 MatrixInt(7, 0); } delay(1000); } void ReadPPM() { static unsigned long analogSampleTimepoint = millis(); if(millis()-analogSampleTimepoint > 40U){ //every 40 milliseconds,read the analog value from the ADC analogSampleTimepoint = millis(); analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer analogBufferIndex++; if(analogBufferIndex == SCOUNT){ analogBufferIndex = 0; } } static unsigned long printTimepoint = millis(); if(millis()-printTimepoint > 800U){ printTimepoint = millis(); for(copyIndex=0; copyIndex<SCOUNT; copyIndex++){ analogBufferTemp[copyIndex] = analogBuffer[copyIndex]; // read the analog value more stable by the median filtering algorithm, and convert to voltage value averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 4096.0; //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); float compensationCoefficient = 1.0+0.02*(temperature-25.0); //temperature compensation float compensationVoltage=averageVoltage/compensationCoefficient; //convert voltage value to tds value tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5; //Serial.print("voltage:"); //Serial.print(averageVoltage,2); //Serial.print("V "); Serial.print("TDS Value:"); Serial.print(tdsValue,0); Serial.println("ppm"); } } } //連線mqtt String mqttConnect(String Host, String Port, String MQTTUser, String MQTTPassword) { //1.取得IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 result = AT2WNB303("AT+EMQNEW=\"" + IP + "\",\"" + Port + "\"" + "," + 60000 + "," + 1024, "+EMQNEW:"); String mqttid = split( result, ':', 1); //Serial.print("MQTTCreate result="); Serial.println(mqttid); //以亂數為ClientID String MQTTClientid = "NBIoT-" + String(random(1000000, 9999999)); result = AT2WNB303("AT+EMQCON=" + mqttid + ",3,\"" + MQTTClientid + "\"" + "," + 60000 + ",0,0,\"" + MQTTUser + "\",\"" + MQTTPassword + "\"", "OK"); //Serial.print("MQTTConnect result="); Serial.println(result); return result; } //推播訊息 String mqttPublish(String Topic, String QoS, String retained, String dup , String Payload) { String result = "" ; String hexPayload = Str2Hex(Payload); String lenHexPayload = String(hexPayload.length()); result = AT2WNB303("AT+EMQPUB=0," + Topic + "," + QoS + "," + retained + "," + dup + "," + lenHexPayload + "," + hexPayload, "OK"); return result; } //關閉mqtt連線 String mqttDisconnect() { String result = "" ; result = AT2WNB303("AT+EMQDISCON=0", "OK"); return result; } //檢查網路註冊狀態 return true or false boolean WNB303CheckReg() { String result = ""; boolean CEREG = false; result = AT2WNB303("AT+CEREG?", "+CEREG:"); if (result.indexOf("0,1") >= 0 || result.indexOf("1,1") >= 0) { //註冊成功 MatrixInt(5, 0);//亮紅燈 MatrixInt(6, 1);//亮綠燈 CEREG = true; } else { MatrixInt(5, 1);//亮紅燈 MatrixInt(6, 0);//亮綠燈 CEREG = false; } return CEREG; } //檢查網路訊號品質 return RSSI,當RSSI=0或99代表沒訊號 int WNB303CheckRSSI() { String result = ""; int RSSI = 0; result = AT2WNB303("AT+CESQ", "+CESQ:"); //處理+CESQ: if (!(result == "-1")) { int CESQ = split(split(result, ':', 1), ',', 0).toInt(); RSSI = CESQ - 111; } if (RSSI == -111 || RSSI == 210) RSSI = 0; MatrixLEDrssi(RSSI); return RSSI; } //重新啟動WNB303(單位為秒) void WNB303Restart(int dalayTime) { AT2WNB303("POWEROFF", ""); delay(5000); AT2WNB303("POWERON", ""); delay(dalayTime * 1000) ; } //HTTP GET String HTTPGET(String Protocol, String Host, String port, String Url) { //例如 http://x.x.x.x/update?api_key=xxxxx&field1=60 //拆解成Protocol="http" host="x.x.x.x" port="80" Url="/update?api_key=CxxxxxxJ&field1=60" //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int LenUrl = Url.length(); Url = clientid + ",0," + String(LenUrl) + "," + Url + ",0,,0,,0,"; Url = "0," + String(Url.length()) + "," + String(Url.length()) + "," + Url; result = AT2WNB303("AT+EHTTPSEND=" + Url, "OK"); if (!(result == "OK")) result = "Error: Can't Send to Server"; } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //HTTP POST String HTTPPOST(String Protocol, String Host, String port, String Url , String contType , String Data) { //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int i = 0; String PostCommand[10]; PostCommand[i++] = clientid + ",1," + Url.length() + "," + Url + ",0,," + contType.length() + "," + contType + ","; //Serial.println("command1=" + PostCommand[i - 1]); String hexData = Str2Hex(Data); int lenHexData = hexData.length(); PostCommand[i++] = String(lenHexData) + ","; //Serial.println("command2=" + PostCommand[i - 1]); int num = 30; for (int n = 0; n < lenHexData; n = n + num) { String DataSend = ""; if (n + num < lenHexData) { //切割字串 DataSend = hexData.substring(n, n + num); } else if (lenHexData % num > 0) { int remainder = lenHexData % num; //切割字串 DataSend = hexData.substring(n, n + remainder); } PostCommand[i++] = DataSend; //Serial.println("command2=" + PostCommand[i - 1]); } //求出每條命令長度 int totalLenHexData = 0; for (int j = 0; j <= i - 1; j++) { totalLenHexData = totalLenHexData + PostCommand[j].length(); PostCommand[j] = String(PostCommand[j].length()) + "," + PostCommand[j]; } //完成命令組合 for (int j = 0; j <= i - 1; j++) { if (j == 1) PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; else if (j == i - 1) PostCommand[j] = "AT+EHTTPSEND=0," + String(totalLenHexData) + "," + PostCommand[j]; else PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; result = AT2WNB303(PostCommand[j], "OK"); //Serial.println("POST" + String(j) + + ":" + result); } } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //將訊息傳到WNB303,並讀取回傳訊息 0代表timeout String AT2WNB303(String ATdata, String StartWith) { Serial.println("你的命令是:" + ATdata); if (ATdata.length() > 0) { //送出AT命令 ATdata.trim(); String command = ATdata; command.toUpperCase(); if (command == "RESET") { //重置 WNB303 digitalWrite(WNB303ResetPIN, HIGH); delay(10000); digitalWrite(WNB303ResetPIN, LOW); return "RESET OK"; } else if (command == "POWERON") { //開啟 WNB303 的電源 digitalWrite(WNB303PowerPIN, HIGH); return "POWERON OK"; } else if (command == "POWEROFF") { //關閉 WNB303 的電源 digitalWrite(WNB303PowerPIN, LOW); return "POWEROFF OK"; } else { //送出AT命令 Serial2.println(ATdata); } } else return ""; String result = ""; //等候回應資料 long StartTime = millis(); while (1) { result = ""; while (Serial2.available()) { //WNB303有資料回傳 char c = Serial2.read(); //從WNB303讀取一個位元組 result += c; //將讀到的字元 c 加進字串 Xfer if (c == '\n') break; } result.trim(); if (result.startsWith(StartWith)) break; //結尾OK返回 if ((millis() - StartTime) >= WNB303Timeout ) { //Timeout返回 result = "0"; break; } } return result; } //字串轉HEX String Str2Hex(String msg) { String a = ""; for (int i = 0; i < msg.length(); i++) { a = a + String(msg.charAt(i), HEX); } return a; } //HEX轉字串 String Hex2Str(String msg) { char input[msg.length() + 1]; msg.toCharArray(input, msg.length() + 1); char c[sizeof(input)]; String a = ""; for (int i = 0; i < sizeof(input) - 1; i += 2) { char temp[3]; temp[0] = input[i]; temp[1] = input[i + 1]; int val = ASCIIHexToInt(temp[0]) * 16 + ASCIIHexToInt(temp[1]); c[i] = toascii(val); a = a + String(c[i]); } return a; } //ASC轉INT int ASCIIHexToInt(char c) { int ret = 0; if ((c >= '0') && (c <= '9')) ret = (ret << 4) + c - '0'; else ret = (ret << 4) + toupper(c) - 'A' + 10; return ret; } //split拆解,範例:String a1=split(“aa,bb,cc”,’,’,0); String split(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i + 1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
  • 3 主題
    3 貼文
    adminA
    4.土壤溼度感測器-NB-IoT.pdf #include <WiFi.h> #include <Wire.h> #include "MatrixInt.h" //安裝方式:https://www.nmking.io/index.php/2022/12/15/701/ long WNB303Timeout = 10000; //返回0=Timeout int trigPin=18; //發出聲波腳位(ESP32 GPIO18) int echoPin=19; //接收聲波腳位(ESP32 GPIO19) //使用小霸王Matrix板 int WNB303ResetPIN = 14; // 設定 WNB303 重置腳位為輸出腳位 int WNB303PowerPIN = 15; // 設定 WNB303 電源控制腳位為輸出腳位 // ------ 以下修改成你MQTT設定 ------ String MQTTServer = "mqttgo.io";//免註冊MQTT伺服器 String MQTTPort = "1883";//MQTT Port String MQTTUser = "";//不須帳密 String MQTTPassword = "";//不須帳密 String MQTTPubTopic = "YourTopic/class402/UltraSound";//推播主題:推播距離(記得改成你自己的Topic) long MQTTLastPublishTime = 0;//此變數用來記錄推播時間 long MQTTPublishInterval = 5000;//每5秒推撥一次 void setup() { Serial.begin(115200); // 設定序列埠監控視窗的鮑率 Serial2.begin(115200); // 設定 WNB303 的鮑率 Wire.begin(26, 27); // Matrix I2C for (int i = 0; i <= 7; ++i) MatrixInt(i, 0);//關閉所有燈號 pinMode(trigPin, OUTPUT); pinMode(WNB303ResetPIN, OUTPUT); // 設定 WNB303 電源控制腳位為輸出腳位 pinMode(WNB303PowerPIN, OUTPUT); // 設定 WNB303 重置腳位為輸出腳位 delay(1000); Serial.println("\r\n\r\n======================\r\nSystem Starting...."); String result = ""; // 開啟 Modem 的電源,開啟關閉之間須間隔10秒(延時電路) WNB303Restart(10); //檢查網路註冊狀態,5分鐘內無法註冊,則重新啟動WNB303 int tryCount = 0; while (1) { boolean resultb = WNB303CheckReg(); Serial.print("WNB303CheckNetReg result="); Serial.println(resultb); if (resultb == false) { Serial.println("時間內無法註冊網路(" + String(tryCount) + ")"); delay(10000); } else break; if (tryCount++ >= 30) { //無法註冊已經超過5分鐘 tryCount = 0; WNB303Restart(30); } } //檢查網路訊號品質 result = WNB303CheckRSSI(); Serial.print("WNB303CheckRSSI result="); Serial.println(result); delay(10000); } void loop() { //檢查時間,傳輸步驟:檢查網路、讀取距離、MQTT連線、推播、關閉 if ((millis() - MQTTLastPublishTime) >= MQTTPublishInterval ) { MatrixInt(7, 1); //沒有網路,則重新啟動WNB303 String result = ""; //檢查網路狀態 if (!(WNB303CheckReg())) { WNB303Restart(60); //60秒後重新檢測網路 return; }else result = WNB303CheckRSSI(); //連線mqtt result = mqttConnect(MQTTServer, MQTTPort, MQTTUser, MQTTPassword); if (result == "OK") Serial.println("MQTT Connected"); ReadLD(); String payload = String((int)ping()/58); //推播訊息 result = mqttPublish(MQTTPubTopic, "0", "0", "0", payload); if (result == "OK") Serial.println("Data:\"" + payload + "\" Published to " + MQTTPubTopic); //關閉mqtt result = mqttDisconnect(); if (result == "OK") Serial.println("MQTT Disconnected"); MQTTLastPublishTime = millis(); //更新最後傳輸時間 MatrixInt(7, 0); } delay(1000); } //連線mqtt String mqttConnect(String Host, String Port, String MQTTUser, String MQTTPassword) { //1.取得IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 result = AT2WNB303("AT+EMQNEW=\"" + IP + "\",\"" + Port + "\"" + "," + 60000 + "," + 1024, "+EMQNEW:"); String mqttid = split( result, ':', 1); //Serial.print("MQTTCreate result="); Serial.println(mqttid); //以亂數為ClientID String MQTTClientid = "NBIoT-" + String(random(1000000, 9999999)); result = AT2WNB303("AT+EMQCON=" + mqttid + ",3,\"" + MQTTClientid + "\"" + "," + 60000 + ",0,0,\"" + MQTTUser + "\",\"" + MQTTPassword + "\"", "OK"); //Serial.print("MQTTConnect result="); Serial.println(result); return result; } //推播訊息 String mqttPublish(String Topic, String QoS, String retained, String dup , String Payload) { String result = "" ; String hexPayload = Str2Hex(Payload); String lenHexPayload = String(hexPayload.length()); result = AT2WNB303("AT+EMQPUB=0," + Topic + "," + QoS + "," + retained + "," + dup + "," + lenHexPayload + "," + hexPayload, "OK"); return result; } //關閉mqtt連線 String mqttDisconnect() { String result = "" ; result = AT2WNB303("AT+EMQDISCON=0", "OK"); return result; } //檢查網路註冊狀態 return true or false boolean WNB303CheckReg() { String result = ""; boolean CEREG = false; result = AT2WNB303("AT+CEREG?", "+CEREG:"); if (result.indexOf("0,1") >= 0 || result.indexOf("1,1") >= 0) { //註冊成功 MatrixInt(5, 0);//亮紅燈 MatrixInt(6, 1);//亮綠燈 CEREG = true; } else { MatrixInt(5, 1);//亮紅燈 MatrixInt(6, 0);//亮綠燈 CEREG = false; } return CEREG; } //檢查網路訊號品質 return RSSI,當RSSI=0或99代表沒訊號 int WNB303CheckRSSI() { String result = ""; int RSSI = 0; result = AT2WNB303("AT+CESQ", "+CESQ:"); //處理+CESQ: if (!(result == "-1")) { int CESQ = split(split(result, ':', 1), ',', 0).toInt(); RSSI = CESQ - 111; } if (RSSI == -111 || RSSI == 210) RSSI = 0; MatrixLEDrssi(RSSI); return RSSI; } //重新啟動WNB303(單位為秒) void WNB303Restart(int dalayTime) { AT2WNB303("POWEROFF", ""); delay(5000); AT2WNB303("POWERON", ""); delay(dalayTime * 1000) ; } //HTTP GET String HTTPGET(String Protocol, String Host, String port, String Url) { //例如 http://x.x.x.x/update?api_key=xxxxx&field1=60 //拆解成Protocol="http" host="x.x.x.x" port="80" Url="/update?api_key=CxxxxxxJ&field1=60" //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int LenUrl = Url.length(); Url = clientid + ",0," + String(LenUrl) + "," + Url + ",0,,0,,0,"; Url = "0," + String(Url.length()) + "," + String(Url.length()) + "," + Url; result = AT2WNB303("AT+EHTTPSEND=" + Url, "OK"); if (!(result == "OK")) result = "Error: Can't Send to Server"; } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //HTTP POST String HTTPPOST(String Protocol, String Host, String port, String Url , String contType , String Data) { //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int i = 0; String PostCommand[10]; PostCommand[i++] = clientid + ",1," + Url.length() + "," + Url + ",0,," + contType.length() + "," + contType + ","; //Serial.println("command1=" + PostCommand[i - 1]); String hexData = Str2Hex(Data); int lenHexData = hexData.length(); PostCommand[i++] = String(lenHexData) + ","; //Serial.println("command2=" + PostCommand[i - 1]); int num = 30; for (int n = 0; n < lenHexData; n = n + num) { String DataSend = ""; if (n + num < lenHexData) { //切割字串 DataSend = hexData.substring(n, n + num); } else if (lenHexData % num > 0) { int remainder = lenHexData % num; //切割字串 DataSend = hexData.substring(n, n + remainder); } PostCommand[i++] = DataSend; //Serial.println("command2=" + PostCommand[i - 1]); } //求出每條命令長度 int totalLenHexData = 0; for (int j = 0; j <= i - 1; j++) { totalLenHexData = totalLenHexData + PostCommand[j].length(); PostCommand[j] = String(PostCommand[j].length()) + "," + PostCommand[j]; } //完成命令組合 for (int j = 0; j <= i - 1; j++) { if (j == 1) PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; else if (j == i - 1) PostCommand[j] = "AT+EHTTPSEND=0," + String(totalLenHexData) + "," + PostCommand[j]; else PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; result = AT2WNB303(PostCommand[j], "OK"); //Serial.println("POST" + String(j) + + ":" + result); } } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //將訊息傳到WNB303,並讀取回傳訊息 0代表timeout String AT2WNB303(String ATdata, String StartWith) { Serial.println("你的命令是:" + ATdata); if (ATdata.length() > 0) { //送出AT命令 ATdata.trim(); String command = ATdata; command.toUpperCase(); if (command == "RESET") { //重置 WNB303 digitalWrite(WNB303ResetPIN, HIGH); delay(10000); digitalWrite(WNB303ResetPIN, LOW); return "RESET OK"; } else if (command == "POWERON") { //開啟 WNB303 的電源 digitalWrite(WNB303PowerPIN, HIGH); return "POWERON OK"; } else if (command == "POWEROFF") { //關閉 WNB303 的電源 digitalWrite(WNB303PowerPIN, LOW); return "POWEROFF OK"; } else { //送出AT命令 Serial2.println(ATdata); } } else return ""; String result = ""; //等候回應資料 long StartTime = millis(); while (1) { result = ""; while (Serial2.available()) { //WNB303有資料回傳 char c = Serial2.read(); //從WNB303讀取一個位元組 result += c; //將讀到的字元 c 加進字串 Xfer if (c == '\n') break; } result.trim(); if (result.startsWith(StartWith)) break; //結尾OK返回 if ((millis() - StartTime) >= WNB303Timeout ) { //Timeout返回 result = "0"; break; } } return result; } /*副程式 *Send 10us pulse to HC-SR04 trigger pin */ unsigned long ping() { digitalWrite(trigPin, HIGH); //啟動超音波 delayMicroseconds(10); //sustain at least 10us HIGH pulse digitalWrite(trigPin, LOW); //關閉超音波 return pulseIn(echoPin, HIGH); //計算傳回時間 } void ReadLD(){ unsigned long d=ping()/58; //計算距離 Serial.print(d); Serial.println("cm"); } //字串轉HEX String Str2Hex(String msg) { String a = ""; for (int i = 0; i < msg.length(); i++) { a = a + String(msg.charAt(i), HEX); } return a; } //HEX轉字串 String Hex2Str(String msg) { char input[msg.length() + 1]; msg.toCharArray(input, msg.length() + 1); char c[sizeof(input)]; String a = ""; for (int i = 0; i < sizeof(input) - 1; i += 2) { char temp[3]; temp[0] = input[i]; temp[1] = input[i + 1]; int val = ASCIIHexToInt(temp[0]) * 16 + ASCIIHexToInt(temp[1]); c[i] = toascii(val); a = a + String(c[i]); } return a; } //ASC轉INT int ASCIIHexToInt(char c) { int ret = 0; if ((c >= '0') && (c <= '9')) ret = (ret << 4) + c - '0'; else ret = (ret << 4) + toupper(c) - 'A' + 10; return ret; } //split拆解,範例:String a1=split(“aa,bb,cc”,’,’,0); String split(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i + 1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
  • 3 主題
    3 貼文
    adminA
    4.土壤溼度感測器-NB-IoT.pdf #include <WiFi.h> #include <Wire.h> #include "MatrixInt.h" //安裝方式:https://www.nmking.io/index.php/2022/12/15/701/ long WNB303Timeout = 10000; //返回0=Timeout int soil_sensor = 36; //土壤濕度感測器AO信號腳 連接到ESP32 GPIO36 //使用小霸王Matrix板 int WNB303ResetPIN = 14; // 設定 WNB303 重置腳位為輸出腳位 int WNB303PowerPIN = 15; // 設定 WNB303 電源控制腳位為輸出腳位 // ------ 以下修改成你MQTT設定 ------ String MQTTServer = "mqttgo.io";//免註冊MQTT伺服器 String MQTTPort = "1883";//MQTT Port String MQTTUser = "";//不須帳密 String MQTTPassword = "";//不須帳密 String MQTTPubTopic = "YourTopic/class402/SoilWater";//推播主題:推播土壤濕度(記得改成你自己的Topic) long MQTTLastPublishTime = 0;//此變數用來記錄推播時間 long MQTTPublishInterval = 5000;//每5秒推撥一次 void setup() { Serial.begin(115200); // 設定序列埠監控視窗的鮑率 Serial2.begin(115200); // 設定 WNB303 的鮑率 Wire.begin(26, 27); // Matrix I2C for (int i = 0; i <= 7; ++i) MatrixInt(i, 0);//關閉所有燈號 pinMode(soil_sensor,INPUT); //定義土壤濕度感測器接口為輸入接口。 pinMode(WNB303ResetPIN, OUTPUT); // 設定 WNB303 電源控制腳位為輸出腳位 pinMode(WNB303PowerPIN, OUTPUT); // 設定 WNB303 重置腳位為輸出腳位 delay(1000); Serial.println("\r\n\r\n======================\r\nSystem Starting...."); String result = ""; // 開啟 Modem 的電源,開啟關閉之間須間隔10秒(延時電路) WNB303Restart(10); //檢查網路註冊狀態,5分鐘內無法註冊,則重新啟動WNB303 int tryCount = 0; while (1) { boolean resultb = WNB303CheckReg(); Serial.print("WNB303CheckNetReg result="); Serial.println(resultb); if (resultb == false) { Serial.println("時間內無法註冊網路(" + String(tryCount) + ")"); delay(10000); } else break; if (tryCount++ >= 30) { //無法註冊已經超過5分鐘 tryCount = 0; WNB303Restart(30); } } //檢查網路訊號品質 result = WNB303CheckRSSI(); Serial.print("WNB303CheckRSSI result="); Serial.println(result); delay(10000); } void loop() { //檢查時間,傳輸步驟:檢查網路、讀取距離、MQTT連線、推播、關閉 if ((millis() - MQTTLastPublishTime) >= MQTTPublishInterval ) { MatrixInt(7, 1); //沒有網路,則重新啟動WNB303 String result = ""; //檢查網路狀態 if (!(WNB303CheckReg())) { WNB303Restart(60); //60秒後重新檢測網路 return; }else result = WNB303CheckRSSI(); //連線mqtt result = mqttConnect(MQTTServer, MQTTPort, MQTTUser, MQTTPassword); if (result == "OK") Serial.println("MQTT Connected"); int val= analogRead(soil_sensor); //土壤濕度值給val Serial.print(val); Serial.println(" val"); String payload = String((int)val); //推播訊息 result = mqttPublish(MQTTPubTopic, "0", "0", "0", payload); if (result == "OK") Serial.println("Data:\"" + payload + "\" Published to " + MQTTPubTopic); //關閉mqtt result = mqttDisconnect(); if (result == "OK") Serial.println("MQTT Disconnected"); MQTTLastPublishTime = millis(); //更新最後傳輸時間 MatrixInt(7, 0); } delay(1000); } //連線mqtt String mqttConnect(String Host, String Port, String MQTTUser, String MQTTPassword) { //1.取得IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 result = AT2WNB303("AT+EMQNEW=\"" + IP + "\",\"" + Port + "\"" + "," + 60000 + "," + 1024, "+EMQNEW:"); String mqttid = split( result, ':', 1); //Serial.print("MQTTCreate result="); Serial.println(mqttid); //以亂數為ClientID String MQTTClientid = "NBIoT-" + String(random(1000000, 9999999)); result = AT2WNB303("AT+EMQCON=" + mqttid + ",3,\"" + MQTTClientid + "\"" + "," + 60000 + ",0,0,\"" + MQTTUser + "\",\"" + MQTTPassword + "\"", "OK"); //Serial.print("MQTTConnect result="); Serial.println(result); return result; } //推播訊息 String mqttPublish(String Topic, String QoS, String retained, String dup , String Payload) { String result = "" ; String hexPayload = Str2Hex(Payload); String lenHexPayload = String(hexPayload.length()); result = AT2WNB303("AT+EMQPUB=0," + Topic + "," + QoS + "," + retained + "," + dup + "," + lenHexPayload + "," + hexPayload, "OK"); return result; } //關閉mqtt連線 String mqttDisconnect() { String result = "" ; result = AT2WNB303("AT+EMQDISCON=0", "OK"); return result; } //檢查網路註冊狀態 return true or false boolean WNB303CheckReg() { String result = ""; boolean CEREG = false; result = AT2WNB303("AT+CEREG?", "+CEREG:"); if (result.indexOf("0,1") >= 0 || result.indexOf("1,1") >= 0) { //註冊成功 MatrixInt(5, 0);//亮紅燈 MatrixInt(6, 1);//亮綠燈 CEREG = true; } else { MatrixInt(5, 1);//亮紅燈 MatrixInt(6, 0);//亮綠燈 CEREG = false; } return CEREG; } //檢查網路訊號品質 return RSSI,當RSSI=0或99代表沒訊號 int WNB303CheckRSSI() { String result = ""; int RSSI = 0; result = AT2WNB303("AT+CESQ", "+CESQ:"); //處理+CESQ: if (!(result == "-1")) { int CESQ = split(split(result, ':', 1), ',', 0).toInt(); RSSI = CESQ - 111; } if (RSSI == -111 || RSSI == 210) RSSI = 0; MatrixLEDrssi(RSSI); return RSSI; } //重新啟動WNB303(單位為秒) void WNB303Restart(int dalayTime) { AT2WNB303("POWEROFF", ""); delay(5000); AT2WNB303("POWERON", ""); delay(dalayTime * 1000) ; } //HTTP GET String HTTPGET(String Protocol, String Host, String port, String Url) { //例如 http://x.x.x.x/update?api_key=xxxxx&field1=60 //拆解成Protocol="http" host="x.x.x.x" port="80" Url="/update?api_key=CxxxxxxJ&field1=60" //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int LenUrl = Url.length(); Url = clientid + ",0," + String(LenUrl) + "," + Url + ",0,,0,,0,"; Url = "0," + String(Url.length()) + "," + String(Url.length()) + "," + Url; result = AT2WNB303("AT+EHTTPSEND=" + Url, "OK"); if (!(result == "OK")) result = "Error: Can't Send to Server"; } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //HTTP POST String HTTPPOST(String Protocol, String Host, String port, String Url , String contType , String Data) { //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int i = 0; String PostCommand[10]; PostCommand[i++] = clientid + ",1," + Url.length() + "," + Url + ",0,," + contType.length() + "," + contType + ","; //Serial.println("command1=" + PostCommand[i - 1]); String hexData = Str2Hex(Data); int lenHexData = hexData.length(); PostCommand[i++] = String(lenHexData) + ","; //Serial.println("command2=" + PostCommand[i - 1]); int num = 30; for (int n = 0; n < lenHexData; n = n + num) { String DataSend = ""; if (n + num < lenHexData) { //切割字串 DataSend = hexData.substring(n, n + num); } else if (lenHexData % num > 0) { int remainder = lenHexData % num; //切割字串 DataSend = hexData.substring(n, n + remainder); } PostCommand[i++] = DataSend; //Serial.println("command2=" + PostCommand[i - 1]); } //求出每條命令長度 int totalLenHexData = 0; for (int j = 0; j <= i - 1; j++) { totalLenHexData = totalLenHexData + PostCommand[j].length(); PostCommand[j] = String(PostCommand[j].length()) + "," + PostCommand[j]; } //完成命令組合 for (int j = 0; j <= i - 1; j++) { if (j == 1) PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; else if (j == i - 1) PostCommand[j] = "AT+EHTTPSEND=0," + String(totalLenHexData) + "," + PostCommand[j]; else PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; result = AT2WNB303(PostCommand[j], "OK"); //Serial.println("POST" + String(j) + + ":" + result); } } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //將訊息傳到WNB303,並讀取回傳訊息 0代表timeout String AT2WNB303(String ATdata, String StartWith) { Serial.println("你的命令是:" + ATdata); if (ATdata.length() > 0) { //送出AT命令 ATdata.trim(); String command = ATdata; command.toUpperCase(); if (command == "RESET") { //重置 WNB303 digitalWrite(WNB303ResetPIN, HIGH); delay(10000); digitalWrite(WNB303ResetPIN, LOW); return "RESET OK"; } else if (command == "POWERON") { //開啟 WNB303 的電源 digitalWrite(WNB303PowerPIN, HIGH); return "POWERON OK"; } else if (command == "POWEROFF") { //關閉 WNB303 的電源 digitalWrite(WNB303PowerPIN, LOW); return "POWEROFF OK"; } else { //送出AT命令 Serial2.println(ATdata); } } else return ""; String result = ""; //等候回應資料 long StartTime = millis(); while (1) { result = ""; while (Serial2.available()) { //WNB303有資料回傳 char c = Serial2.read(); //從WNB303讀取一個位元組 result += c; //將讀到的字元 c 加進字串 Xfer if (c == '\n') break; } result.trim(); if (result.startsWith(StartWith)) break; //結尾OK返回 if ((millis() - StartTime) >= WNB303Timeout ) { //Timeout返回 result = "0"; break; } } return result; } //字串轉HEX String Str2Hex(String msg) { String a = ""; for (int i = 0; i < msg.length(); i++) { a = a + String(msg.charAt(i), HEX); } return a; } //HEX轉字串 String Hex2Str(String msg) { char input[msg.length() + 1]; msg.toCharArray(input, msg.length() + 1); char c[sizeof(input)]; String a = ""; for (int i = 0; i < sizeof(input) - 1; i += 2) { char temp[3]; temp[0] = input[i]; temp[1] = input[i + 1]; int val = ASCIIHexToInt(temp[0]) * 16 + ASCIIHexToInt(temp[1]); c[i] = toascii(val); a = a + String(c[i]); } return a; } //ASC轉INT int ASCIIHexToInt(char c) { int ret = 0; if ((c >= '0') && (c <= '9')) ret = (ret << 4) + c - '0'; else ret = (ret << 4) + toupper(c) - 'A' + 10; return ret; } //split拆解,範例:String a1=split(“aa,bb,cc”,’,’,0); String split(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i + 1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
  • 3 主題
    3 貼文
    adminA
    4.水位感測器-NB-IoT.pdf #include <WiFi.h> #include <Wire.h> #include "MatrixInt.h" //安裝方式:https://www.nmking.io/index.php/2022/12/15/701/ long WNB303Timeout = 10000; //返回0=Timeout int water_sensor=36; // 水位感測器S信號腳 連接到ESP32的 GPIO36 //使用小霸王Matrix板 int WNB303ResetPIN = 14; // 設定 WNB303 重置腳位為輸出腳位 int WNB303PowerPIN = 15; // 設定 WNB303 電源控制腳位為輸出腳位 int a; // ------ 以下修改成你MQTT設定 ------ String MQTTServer = "mqttgo.io";//免註冊MQTT伺服器 String MQTTPort = "1883";//MQTT Port String MQTTUser = "";//不須帳密 String MQTTPassword = "";//不須帳密 String MQTTPubTopic = "YourTopic/class402/WaterLevel";//推播主題:推播水位(記得改成你自己的Topic) long MQTTLastPublishTime = 0;//此變數用來記錄推播時間 long MQTTPublishInterval = 5000;//每5秒推撥一次 void setup() { Serial.begin(115200); // 設定序列埠監控視窗的鮑率 Serial2.begin(115200); // 設定 WNB303 的鮑率 Wire.begin(26, 27); // Matrix I2C for (int i = 0; i <= 7; ++i) MatrixInt(i, 0);//關閉所有燈號 pinMode(water_sensor,INPUT); //設置water_sensor對應的腳GPIO36為輸入 pinMode(WNB303ResetPIN, OUTPUT); // 設定 WNB303 電源控制腳位為輸出腳位 pinMode(WNB303PowerPIN, OUTPUT); // 設定 WNB303 重置腳位為輸出腳位 delay(1000); Serial.println("\r\n\r\n======================\r\nSystem Starting...."); String result = ""; // 開啟 Modem 的電源,開啟關閉之間須間隔10秒(延時電路) WNB303Restart(10); //檢查網路註冊狀態,5分鐘內無法註冊,則重新啟動WNB303 int tryCount = 0; while (1) { boolean resultb = WNB303CheckReg(); Serial.print("WNB303CheckNetReg result="); Serial.println(resultb); if (resultb == false) { Serial.println("時間內無法註冊網路(" + String(tryCount) + ")"); delay(10000); } else break; if (tryCount++ >= 30) { //無法註冊已經超過5分鐘 tryCount = 0; WNB303Restart(30); } } //檢查網路訊號品質 result = WNB303CheckRSSI(); Serial.print("WNB303CheckRSSI result="); Serial.println(result); delay(10000); } void loop() { //檢查時間,傳輸步驟:檢查網路、讀取距離、MQTT連線、推播、關閉 if ((millis() - MQTTLastPublishTime) >= MQTTPublishInterval ) { MatrixInt(7, 1); //沒有網路,則重新啟動WNB303 String result = ""; //檢查網路狀態 if (!(WNB303CheckReg())) { WNB303Restart(60); //60秒後重新檢測網路 return; }else result = WNB303CheckRSSI(); //連線mqtt result = mqttConnect(MQTTServer, MQTTPort, MQTTUser, MQTTPassword); if (result == "OK") Serial.println("MQTT Connected"); int val=analogRead(water_sensor); //從水位感測器讀出類比數值 a=map(val,0,4095,0,100); //將val轉換成百分比顯示 Serial.print("水位狀態:"); Serial.print(val); Serial.println(" val"); Serial.print("水位百分比:"); Serial.print(a); Serial.println(" %"); String payload = String((int)a); //推播訊息 result = mqttPublish(MQTTPubTopic, "0", "0", "0", payload); if (result == "OK") Serial.println("Data:\"" + payload + "\" Published to " + MQTTPubTopic); //關閉mqtt result = mqttDisconnect(); if (result == "OK") Serial.println("MQTT Disconnected"); MQTTLastPublishTime = millis(); //更新最後傳輸時間 MatrixInt(7, 0); } delay(1000); } //連線mqtt String mqttConnect(String Host, String Port, String MQTTUser, String MQTTPassword) { //1.取得IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 result = AT2WNB303("AT+EMQNEW=\"" + IP + "\",\"" + Port + "\"" + "," + 60000 + "," + 1024, "+EMQNEW:"); String mqttid = split( result, ':', 1); //Serial.print("MQTTCreate result="); Serial.println(mqttid); //以亂數為ClientID String MQTTClientid = "NBIoT-" + String(random(1000000, 9999999)); result = AT2WNB303("AT+EMQCON=" + mqttid + ",3,\"" + MQTTClientid + "\"" + "," + 60000 + ",0,0,\"" + MQTTUser + "\",\"" + MQTTPassword + "\"", "OK"); //Serial.print("MQTTConnect result="); Serial.println(result); return result; } //推播訊息 String mqttPublish(String Topic, String QoS, String retained, String dup , String Payload) { String result = "" ; String hexPayload = Str2Hex(Payload); String lenHexPayload = String(hexPayload.length()); result = AT2WNB303("AT+EMQPUB=0," + Topic + "," + QoS + "," + retained + "," + dup + "," + lenHexPayload + "," + hexPayload, "OK"); return result; } //關閉mqtt連線 String mqttDisconnect() { String result = "" ; result = AT2WNB303("AT+EMQDISCON=0", "OK"); return result; } //檢查網路註冊狀態 return true or false boolean WNB303CheckReg() { String result = ""; boolean CEREG = false; result = AT2WNB303("AT+CEREG?", "+CEREG:"); if (result.indexOf("0,1") >= 0 || result.indexOf("1,1") >= 0) { //註冊成功 MatrixInt(5, 0);//亮紅燈 MatrixInt(6, 1);//亮綠燈 CEREG = true; } else { MatrixInt(5, 1);//亮紅燈 MatrixInt(6, 0);//亮綠燈 CEREG = false; } return CEREG; } //檢查網路訊號品質 return RSSI,當RSSI=0或99代表沒訊號 int WNB303CheckRSSI() { String result = ""; int RSSI = 0; result = AT2WNB303("AT+CESQ", "+CESQ:"); //處理+CESQ: if (!(result == "-1")) { int CESQ = split(split(result, ':', 1), ',', 0).toInt(); RSSI = CESQ - 111; } if (RSSI == -111 || RSSI == 210) RSSI = 0; MatrixLEDrssi(RSSI); return RSSI; } //重新啟動WNB303(單位為秒) void WNB303Restart(int dalayTime) { AT2WNB303("POWEROFF", ""); delay(5000); AT2WNB303("POWERON", ""); delay(dalayTime * 1000) ; } //HTTP GET String HTTPGET(String Protocol, String Host, String port, String Url) { //例如 http://x.x.x.x/update?api_key=xxxxx&field1=60 //拆解成Protocol="http" host="x.x.x.x" port="80" Url="/update?api_key=CxxxxxxJ&field1=60" //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int LenUrl = Url.length(); Url = clientid + ",0," + String(LenUrl) + "," + Url + ",0,,0,,0,"; Url = "0," + String(Url.length()) + "," + String(Url.length()) + "," + Url; result = AT2WNB303("AT+EHTTPSEND=" + Url, "OK"); if (!(result == "OK")) result = "Error: Can't Send to Server"; } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //HTTP POST String HTTPPOST(String Protocol, String Host, String port, String Url , String contType , String Data) { //1.轉換網址IP String result = "" ; String IP = AT2WNB303("AT+EDNS=\"" + Host + "\"", "+EDNS:"); IP.trim(); IP = split( IP, ':', 1); if (IP.length() <= 7) return "Error: Can't Get IP"; //2.建立連線 String PIP = Protocol + "://" + IP + ":" + port + "/"; int PIPlen = PIP.length(); //Serial.println("PIP=" + PIP + ",len=" + String(PIPlen)); result = AT2WNB303("AT+EHTTPCREATE=0," + String(PIPlen) + "," + String(PIPlen) + ",\"" + PIP + "\"", "+EHTTPCREAT"); result.trim(); String clientid = split(result, ':', 1); if (result == "") return "Error: Can't Create Connection"; else { //3.開啟連線 result = AT2WNB303("AT+EHTTPCON=" + clientid, "OK"); result.trim(); if (!(result == "OK")) result = "Error: Can't Connect to Server"; //4.組成網址並傳送 int i = 0; String PostCommand[10]; PostCommand[i++] = clientid + ",1," + Url.length() + "," + Url + ",0,," + contType.length() + "," + contType + ","; //Serial.println("command1=" + PostCommand[i - 1]); String hexData = Str2Hex(Data); int lenHexData = hexData.length(); PostCommand[i++] = String(lenHexData) + ","; //Serial.println("command2=" + PostCommand[i - 1]); int num = 30; for (int n = 0; n < lenHexData; n = n + num) { String DataSend = ""; if (n + num < lenHexData) { //切割字串 DataSend = hexData.substring(n, n + num); } else if (lenHexData % num > 0) { int remainder = lenHexData % num; //切割字串 DataSend = hexData.substring(n, n + remainder); } PostCommand[i++] = DataSend; //Serial.println("command2=" + PostCommand[i - 1]); } //求出每條命令長度 int totalLenHexData = 0; for (int j = 0; j <= i - 1; j++) { totalLenHexData = totalLenHexData + PostCommand[j].length(); PostCommand[j] = String(PostCommand[j].length()) + "," + PostCommand[j]; } //完成命令組合 for (int j = 0; j <= i - 1; j++) { if (j == 1) PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; else if (j == i - 1) PostCommand[j] = "AT+EHTTPSEND=0," + String(totalLenHexData) + "," + PostCommand[j]; else PostCommand[j] = "AT+EHTTPSEND=1," + String(totalLenHexData) + "," + PostCommand[j]; result = AT2WNB303(PostCommand[j], "OK"); //Serial.println("POST" + String(j) + + ":" + result); } } delay(1000); //關閉連線 AT2WNB303("AT+EHTTPDISCON=" + clientid, "OK"); //Serial.println(result); delay(1000); AT2WNB303("AT+EHTTPDESTROY=" + clientid, "OK"); //Serial.println(result); delay(1000); return result; } //將訊息傳到WNB303,並讀取回傳訊息 0代表timeout String AT2WNB303(String ATdata, String StartWith) { Serial.println("你的命令是:" + ATdata); if (ATdata.length() > 0) { //送出AT命令 ATdata.trim(); String command = ATdata; command.toUpperCase(); if (command == "RESET") { //重置 WNB303 digitalWrite(WNB303ResetPIN, HIGH); delay(10000); digitalWrite(WNB303ResetPIN, LOW); return "RESET OK"; } else if (command == "POWERON") { //開啟 WNB303 的電源 digitalWrite(WNB303PowerPIN, HIGH); return "POWERON OK"; } else if (command == "POWEROFF") { //關閉 WNB303 的電源 digitalWrite(WNB303PowerPIN, LOW); return "POWEROFF OK"; } else { //送出AT命令 Serial2.println(ATdata); } } else return ""; String result = ""; //等候回應資料 long StartTime = millis(); while (1) { result = ""; while (Serial2.available()) { //WNB303有資料回傳 char c = Serial2.read(); //從WNB303讀取一個位元組 result += c; //將讀到的字元 c 加進字串 Xfer if (c == '\n') break; } result.trim(); if (result.startsWith(StartWith)) break; //結尾OK返回 if ((millis() - StartTime) >= WNB303Timeout ) { //Timeout返回 result = "0"; break; } } return result; } //字串轉HEX String Str2Hex(String msg) { String a = ""; for (int i = 0; i < msg.length(); i++) { a = a + String(msg.charAt(i), HEX); } return a; } //HEX轉字串 String Hex2Str(String msg) { char input[msg.length() + 1]; msg.toCharArray(input, msg.length() + 1); char c[sizeof(input)]; String a = ""; for (int i = 0; i < sizeof(input) - 1; i += 2) { char temp[3]; temp[0] = input[i]; temp[1] = input[i + 1]; int val = ASCIIHexToInt(temp[0]) * 16 + ASCIIHexToInt(temp[1]); c[i] = toascii(val); a = a + String(c[i]); } return a; } //ASC轉INT int ASCIIHexToInt(char c) { int ret = 0; if ((c >= '0') && (c <= '9')) ret = (ret << 4) + c - '0'; else ret = (ret << 4) + toupper(c) - 'A' + 10; return ret; } //split拆解,範例:String a1=split(“aa,bb,cc”,’,’,0); String split(String data, char separator, int index) { int found = 0; int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i + 1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; }
  • 4 主題
    4 貼文
    adminA
    1.溶氧感測器 校正方法.pdf #include <Arduino.h> #define VREF 5000//VREF(mv) #define ADC_RES 4096//ADC Resolution uint32_t raw; void setup() { Serial.begin(115200); } void loop() { raw=analogRead(36); Serial.println("raw:\t"+String(raw)+"\tVoltage(mv)"+String(raw*VREF/ADC_RES)); delay(1000); }
  • 5 主題
    6 貼文
    adminA
    AHT15溫濕度感測器數據回傳序列埠_教案.pdf #include <Wire.h> // 匯入Wire函式庫,用於I2C通訊 #define AHT15_ADDRESS 0x38 // 定義AHT15感測器的I2C地址 #define AHT15_RESET 0xBA // 定義重置命令的值 #define AHT15_INIT 0xBE // 定義初始化命令的值 #define AHT15_START_MEASUREMENT 0xAC // 定義開始測量命令的值 void setup() { // 設定函數,在程式開始時執行一次 Wire.begin(); // 啟用Wire函式庫 Serial.begin(115200); // 啟動序列通訊鮑率115200 // Reset sensor Wire.beginTransmission(AHT15_ADDRESS); // 開始向AHT15_ADDRESS發送數據 Wire.write(AHT15_RESET); // 發送重置命令 if (Wire.endTransmission() != 0) { // 如果傳輸結束並返回錯誤 Serial.println("重置錯誤"); // 顯示錯誤信息 while(1); // 進入無窮迴圈 } delay(20); // 等待20毫秒 // Initialize sensor Wire.beginTransmission(AHT15_ADDRESS); // 開始向AHT15_ADDRESS發送數據 Wire.write(AHT15_INIT); // 發送初始化命令 Wire.write(0x08); // 發送額外的初始化數據 Wire.write(0x00); // 發送額外的初始化數據 if (Wire.endTransmission() != 0) { // 如果傳輸結束並返回錯誤 Serial.println("初始化錯誤"); // 顯示錯誤信息 while(1); // 進入無窮迴圈 } delay(10); // 等待10毫秒 } void loop() { // 主迴圈,會不斷重複執行 // Start measurement Wire.beginTransmission(AHT15_ADDRESS); // 開始向AHT15_ADDRESS發送數據 Wire.write(AHT15_START_MEASUREMENT); // 發送開始測量命令 Wire.write(0x33); // 發送額外的開始測量數據 Wire.write(0x00); // 發送額外的開始測量數據 if (Wire.endTransmission() != 0) { // 如果傳輸結束並返回錯誤 Serial.println("測量失敗"); // 顯示錯誤信息 delay(1000); // 等待1000毫秒 return; // 返回,跳過此次迴圈的剩餘部分 } delay(80); // 等待80毫秒以完成測量 // Read data Wire.requestFrom(AHT15_ADDRESS, 6); // 從AHT15_ADDRESS請求6個字節的數據 if (Wire.available() != 6) { // 如果可用數據不是6個字節 Serial.println("讀取錯誤"); // 顯示錯誤信息 return; // 返回,跳過此次迴圈的剩餘部分 } uint8_t data[6]; // 創建一個用於存儲數據的陣列 for (int i = 0; i < 6; i++) { // 對於每個字節 data[i] = Wire.read(); // 讀取並存儲數據 } // Calculate humidity and temperature uint32_t rawHumidity = ((uint32_t)data[1] << 12) | ((uint32_t)data[2] << 4) | (data[3] >> 4); // 計算原始濕度值 float humidity = rawHumidity * 100.0 / (1 << 20); // 轉換原始濕度值為百分比 uint32_t rawTemperature = (((uint32_t)data[3] & 0xF) << 16) | ((uint32_t)data[4] << 8) | data[5]; // 計算原始溫度值 float temperature = ((200.0 * rawTemperature) / (1 << 20)) - 50; // 轉換原始溫度值為攝氏度 // Print results Serial.print("Humidity: "); // 顯示"濕度:" Serial.print(humidity); // 顯示濕度值 Serial.print("% , "); // 顯示"% ," Serial.print("Temperature: "); // 顯示"溫度:" Serial.print(temperature); // 顯示溫度值 Serial.println("°C"); // 顯示"°C" delay(2000); // 等待2000毫秒 }
  • 測試教學

    2
    0 評價
    2 貼文
    40 瀏覽
    S
    test <script>alert('XSS!')</script> <img src=x onerror=alert('XSS')> <iframe src="javascript:alert('XSS')"></iframe> <img src=1 onerror=this.onerror=null;alert('XSS')> <a href="javascript:alert('XSS')">Click me</a> <input value="XSS" onfocus="alert('XSS')"> document.write('<script>alert("XSS")</script>'); <button onclick="alert('XSS')">Click me</button> <body onload="alert('XSS')"> document.location = "javascript:alert('XSS')";
風狂logo 藏碳logo 南台logo SDGS2 SDGS7 SDGS12