網頁最後修改時間:2017/01/07
ThingSpeak 環境溫濕度記錄圖 |
*********************************************************************************
物聯網,維基百科的解釋
*********************************************************************************
*********************************************************************************
此網頁所用的材料可自行準備,或選用新版本的升級套件
更多 ESP8266 相關商品,請至分類賣場
*********************************************************************************
我所使用的 IoT Server 是由 ThingSpeak 所提供,支援很多微處理器和控制器,也提供相對應的使用範例做為使用上的參考,上手很快也很方便。重點是:ThingSpeak 是開源的,可以下載並安裝在自己的電腦上做 IoT Server。
*********************************************************************************
Internet of Things - ThingSpeak
ThingSpeak 開放原始碼 - GitHub
ThingSpeak is an open source “Internet of Things” application and API to store and retrieve data from things using HTTP over the Internet or via a Local Area Network. With ThingSpeak, you can create sensor logging applications, location tracking applications, and a social network of things with status updates.
ThingSpeak 教學 - Tutorials
參考網頁:
參考網頁:
- ThingSpeak - Using an Arduino + Ethernet Shield to Update a ThingSpeak Channel
- Instructable - ESP8266 Wifi Temperature Logger
網頁主要是參考這篇文章裡的內容,作者給了很大的幫助!但是實際上,照著做並不能成功上傳資料,原因在於:(1) 作者的 ESP8266 韌體有可能是舊版的,或是已事先輸入幾個設定的 AT 指令進入模組,因為沒有出現在程式碼中,直接使用程式碼是無法正常上傳資料的;(2) 作者使用 3V3 的 Arduino 板子和 DS18B20 溫度感測器,線路是不一樣的,程式碼必須重新修改;(3) 作者使用單筆資料而非多筆資料同時上傳,這部分需要上 ThingSpeak 網站上面找一下資料。
- 申請一個 ThingSpeak 帳號
. - 建立一個給 DHT11 使用的 Channel
. - 取得剛剛建立的 ThingSpeak Channel 的( Write ) API KEY,並手動測試
. - HTTP 方法:POST 和 GET
. - 佈線電路圖說明
. - 程式測試說明
電路圖:ESP8266 IoT 入門學習套件 / schematics / Arduino_IoT_Demo
程式碼:ESP8266 IoT 入門學習套件 / codes / Arduino / IoT_demo
申請一個 ThingSpeak 帳號:
ThingSpeak 帳號申請很簡單,直接進入 ThingSpeak.com 主網頁點擊右上角的 Sign Up 連結進入註冊頁面。進入頁面後,依照欄位輸入相對應的資料,如下圖所示。
ThingSpeak 新帳號申請頁面 |
建立一個給 DHT11 使用的 Channel:
完成帳號申請之後,按下 Create Account 按鈕就會跳轉到下面的頁面,這時已經確認產生新的帳號,可以開始設定 Channel
ThingSpeak - My Channels 頁面 |
Channel Settings 的頁面中,要設定的只有三個地方
- Name :Channel 的名稱,這裡請設定為 DHT11
- Field 1:資料欄位的顯示名稱,請設定為 Temperature ( degC )
- Filed 2:資料欄位的顯示名稱,請設定為 Humidity ( % )
ThingSpeak Channel Settings - 欄位名稱設定 |
輸入完畢後按下最下方的 Save Channel 按鈕儲存資料;另外,Clear Channel 按鈕是用來清除所有以記錄的資料,這等一下會用到,要記得清除資料是在這裡清除!
取得剛剛建立的 ThingSpeak Channel 的( Write ) API KEY,並手動測試:
在同樣的頁面,上方有一顆 API Keys 按鈕,按進去就會出現剛剛這個 Channel 的寫入的 API Key,將 Write API Key 先複製或是記下來,等一下測試會用到!
ThingSpeak - Channel's API Key |
http://api.thingspeak.com/update?key=[THINGSPEAK_KEY]&field1=[溫度]&field2=[濕度]
根據我們所設定的溫度,則完整的輸入就會變成
http://api.thingspeak.com/update?key=ALSKUJG6DR5PLODE&field1=25&field2=75
打開瀏覽器,複製上面的資料 ( 記得換上自己的 Write API Key ),按下 Enter,若成功傳入資料到剛剛在 ThingSpeak 新增的 Channel,那麼就會在瀏覽器視窗收到 1
傳送測試的溫溼度資料到 ThingSpeak |
到底資料傳進去了沒有,我們來確認一下!
同樣在 Channels 頁面下,按下 Private View 就會看到兩個趨勢圖 ( 方便顯示起見,我將下方的圖移到右邊 ),而顯示的結果與我們剛剛輸入的資料相同,這也就表示上面的輸入格式與資料都是正確的。
檢視測試輸入資料的結果 |
這段建立的資料格式將會使用到 Arduino 程式碼中,負責將整段格式移交給 ESP8266 無線模組來處理。但是瀏覽器傳送時是使用 HTTP 的方法傳送,類似於我們在網頁輸入表單資料後,需要按下表單按鈕以傳送資料到伺服器去,伺服器再根據資料回傳給我們,所以並不是直接輸入上面的格式就可以。這就是我們下一段要討論的 HTTP Method:GET 和 POST 方法。
HTTP 方法:POST 和 GET
ThingSpeak 提供了使用 Arduino 配合有線網路模組的例子,傳送的 HTTP 方法是 POST,與上面所做測試的方法是不一樣的。因為使用 POST 是看不到傳送的欄位資料出現在瀏覽器的網址列中,所以在上面傳送資料的 HTTP 方法是使用 GET。
這兩種 HTTP 方法主要的不同在於,
GET:查詢字串 ( name / value pairs,名稱 / 值對 ) 是在 GET 請求的 URL 中發送的
- 請求數據長度有限制
- 請求數據長度沒有要求
ThingSpeak 裡面所使用的例子是使用 POST 發送數據,會換成使用 GET 的方式是因為他的傳送格式簡單,只要一行就可以搞定;若是利用 POST 要傳送一堆標頭才能傳送本體 ( 資料放在此 ),有點浪費時間!尤其是在微處理機使用上,盡量簡單就好。等到那一天發現到這方法不適用時,再換成 POST 方式就好。
佈線電路圖說明:
IoT_Demo 電路圖 V0.2 - 包括 UART 除錯 |
上面的電路圖中,USB 轉 TTL 模組是用來做除錯用的。程式執行的過程中會送出除錯的訊息,依但程式出現問題時才抓的到;硬體 UART 用來與 ESP8266 直接通訊用,程式寫起來會輕鬆許多。
所需材料:
- 1 x pcs [ Arduino 板子 ]
- 1 x pcs [ ESP8266, ESP-01 無線模組 ]
- 1 x pcs [ USB 轉 TTL 模組 ]
- 1 x pcs [ DHT11 ( 溫溼度感測器 ) ]
- 1 x pcs [ Level Shifter ( 3V3 / 5V 電壓準位轉換模組 ) ]
- 1 x pcs [ 4.7 K 電阻 ]
- 1 x pcs [ 麵包板 ],哪一種形式都可以,能用就好!
- 杜邦線 ( 母對母,公對公 )
如果需要中間那個電壓轉換模組,可以依照 "使用 N-Channel MOSFET 做 I2C 電壓準位轉換電路" 網頁中的說明自己佈線,或是到下面連結購買
*********************************************************************************
實際接線圖 |
程式測試說明:
*********************************************************************************
2016/12/20 更新:
由於使用的感測器並不一定會與網頁上使用的 ( DHT11 ) 相同,因此並未將所使用的 DHT11 函式庫連結附上,主要是考量到這只是 ESP8266 的應用,但因為常有私信問我要,所以檔案連結在下面,不需要再寫信跟我要了!
DHT11 Arduino Library (最新版)
若上面最新版本使用有問題,可改用下面舊版本函式庫使用
DHT11 Arduino Library (網頁程式使用的舊版本 DHT11 函式庫)
直接複製到 "文件/{Arduino IDE}/libraries " 目錄下,重新開啟 Arduino IDE 即可!
*********************************************************************************
接好線路之後 ( USB 轉 TTL 模組的線路可以不接,除非想要看到實際的輸出情形,或是需要除錯 ),完整的程式碼列在下面 ( 雲端硬碟裡面的程式碼裡面有特別做註解 ),將其複製到 Arduino IDE 中。
Note:請注意使用的 ESP8266 板子的通訊速率是使用多少 ? 若是購買賣場藍色板子,就不需要修改下面的程式碼可以直接使用;但若是使用黑色板子,下面的 #define _baudrate 要改成 115200
#include <SoftwareSerial.h> #include "DHT.h" #define DEBUG #define _ledpin 13 //*-- Hardware Serial #define _baudrate 9600 //*-- Software Serial // #define _rxpin 2 #define _txpin 3 SoftwareSerial debug( _rxpin, _txpin ); // RX, TX //*-- DHT11 #define _dhtpin 8 #define _dhttype DHT11 DHT dht11( _dhtpin, _dhttype ); uint8_t dhtbuf[2]; //*-- IoT Information #define SSID "[無線網路熱點名稱]" #define PASS "[無線網路連線密碼]" #define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149 // 使用 GET 傳送資料的格式 // GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&filed2=[data 2]...; String GET = "GET /update?key=[ThingSpeak_(Write)API_KEY]"; void setup() { Serial.begin( _baudrate ); debug.begin( _baudrate ); sendDebug("AT"); delay(5000); if(Serial.find("OK")) { debug.println("RECEIVED: OK\nData ready to sent!"); connectWiFi(); } // DHT11 dht11.begin(); pinMode( _ledpin, OUTPUT ); digitalWrite( _ledpin, LOW ); } void loop() { dhtbuf[0] = dht11.readHumidity(); dhtbuf[1] = dht11.readTemperature(); // 確認取回的溫溼度數據可用 if( isnan(dhtbuf[0]) || isnan(dhtbuf[1]) ) { debug.println( "Failed to read form DHT11" ); } else { digitalWrite( _ledpin, HIGH ); char buf[3]; String HH, TT; buf[0] = 0x30 + dhtbuf[1] / 10; buf[1] = 0x30 + dhtbuf[1] % 10; TT = (String(buf)).substring( 0, 2 ); buf[0] = 0x30 + dhtbuf[0] / 10; buf[1] = 0x30 + dhtbuf[0] % 10; HH = (String(buf)).substring( 0, 2 ); updateDHT11( TT, HH ); #ifdef DEBUG debug.print("Humidity: "); debug.print( HH ); debug.print(" %\t"); debug.print("Temperature: "); debug.print( TT ); debug.println(" *C\t"); #endif digitalWrite( _ledpin, LOW ); } delay(60000); // 60 second } void updateDHT11( String T, String H ) { // 設定 ESP8266 作為 Client 端 String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += IP; cmd += "\",80"; sendDebug(cmd); delay(2000); if( Serial.find( "Error" ) ) { debug.print( "RECEIVED: Error\nExit1" ); return; } cmd = GET + "&field1=" + T + "&field2=" + H +"\r\n"; Serial.print( "AT+CIPSEND=" ); Serial.println( cmd.length() ); if(Serial.find( ">" ) ) { debug.print(">"); debug.print(cmd); Serial.print(cmd); } else { sendDebug( "AT+CIPCLOSE" ); } if( Serial.find("OK") ) { debug.println( "RECEIVED: OK" ); } else { debug.println( "RECEIVED: Error\nExit2" ); } } void sendDebug(String cmd) { debug.print("SEND: "); debug.println(cmd); Serial.println(cmd); } boolean connectWiFi() { Serial.println("AT+CWMODE=1"); delay(2000); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; sendDebug(cmd); delay(5000); if(Serial.find("OK")) { debug.println("RECEIVED: OK"); return true; } else { debug.println("RECEIVED: Error"); return false; } cmd = "AT+CIPMUX=0"; sendDebug( cmd ); if( Serial.find( "Error") ) { debug.print( "RECEIVED: Error" ); return false; } }
整段程式中最重要的就是剛剛在 ThingSpeak 所得到的結果,還有就是無線網路名稱 (SSID) 與連線密碼 ( PASS ),這幾個重要的設定都在程式開頭 IoT Information 的地方。
不過除了SSID 和 PASS 修改為你的無線網路 AP 之外,其他的不需要做修改!
//*-- IoT Information #define SSID "[無線網路熱點名稱]" #define PASS "[無線網路連線密碼]" #define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149 // 使用 GET 傳送資料的格式 // GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&filed2=[data 2]...; String GET = "GET /update?key=[ThingSpeak_(Write)API_KEY]";
插上 Arduino 板子的線到電腦的 USB 插槽,設定好 Arduino IDE 板子類型 ( 和晶片類型 ) 和通訊埠號碼後,按下 upload 按鈕上傳此 Sketch 到 Arduino 板子上。
如果有裝上 USB 轉 TTL 模組,可以先將其插到 PC,再打開串列埠軟體等待 Arduino 通電之後輸出的數據。
開機之後得到的數據就如下面所示,遮蔽的部分是私有的資料,執行你自己的程式碼之後就會看到完整的輸出
訊息輸出 |
ThingSpeak 環境溫濕度記錄圖 |
完成這個例子之後,應該對於程式碼裡面的ESP8266 AT 指令有點陌生!但是這不要緊,因為這就是一個實際例子,先知道 ESP8266 無線模組可以做些什麼,再來了解 AT 指令的操作會更容易了解!
ESP8266 無線模組,可當作一般串口轉無線模組使用,也可以利用它開放的 SDK 修改或是自己製作它的韌體,開發成一個具有無線網路功能的產品或是項目,相關的資料會持續地發佈在部落格上與大家做分享!
相信使用一段時間的 AT 指令之後,對於使用 Arduino IDE 與 AT 指令的配合或許不是那麼的滿意!那麼可以試試使用 ESP8266 Arduino AT 函式庫,相關的資料可以參考下面這三個網頁中的說明,與此篇網頁程式的加強版
- 自行更新 ESP8266 無線模組韌體至 - AT:1.2.0.0, SDK:1.5.4.1
- 給我一個可操作 AT 指令的 Arduino 函式庫 - 解決 AT 指令處理的蛋疼問題 (親測 AT v1.2.0.0 韌體)
- 初遇 IoT ( Internet of Thing, 物聯網 ) 加強版 - 使用 ESP8266 Arduino AT 函式庫上傳溫溼度資料到 Thingspeak ( AT v1.2.0.0 based on SDK 1.5.4.1)
2017/01/03 更新:
因為很多問與答都是關於無法上傳資料到 Thingspeak 的問題,所以在這邊做個總結回覆,大抵上這個網頁中的問題就是這樣解決。
這個問題除了接線的問題之外,就是在程式執行之前必須確定在網址列手動輸入資料是可以正確成功的,再來就是修改程式碼需要的欄位,基本上就不會出現問題 ! 因為手動可以,程式碼就可以正確地將你的資料網上傳,所以只要出問題,就是檢查剛剛修改的欄位是否出現錯誤,因為這並不是程式出現問題,而是輸入參數設定錯誤造成上傳失敗。在相同的'網路環境之下,只是將手動變成自動而已,出現問題要先檢查這些部分 !
上述的問題都解決之後,另外會出現的問題可能就是上傳一段時間之後會失敗會是回傳 error 的問題。最近一位網友提問了這個問題,並且問到了重點,所以進行了幾封郵件的來回 (原文如附件(若連結失效,請回報),文中遮蔽私人資料),若有相同問題可看裡面的討論 !
"給我一個可操作 AT 指令的 Arduino 函式庫 - 解決 AT 指令處理的蛋疼問題 (親測 AT v1.2.0.0 韌體)" 網頁中,對於程式範例也是採用這個方式解決亂碼或是通訊失敗的問題。
*********************************************************************************
<< 部落格相關文章 >>
- Google Spreadsheet(試算表)之 ESP8266 溫濕度紀錄與趨勢圖
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 07 } - 結合 Arduino + ESP8266 實現 MQTT 主題訂閱與接收
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 06 } - 了解 MQTT 協議,學習如何訂閱 MQTT 主題與接收 MQTT 發佈消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 05 } - 結合 ESP8266 發佈 MQTT 消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 04 } - 了解 MQTT 協議,學習如何發佈 MQTT 消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 03 } - 使用 Arduino + ESP8266 上傳 SHT31 溫溼度數據
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 02 } - 設備感測數據讀取與 (JSON) 解析
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 01 } - 如何使用 ESP8266 利用 AT 指令取回中華電信 IoT 智慧聯網大平台上的設備感測器數據
- 如何使用 MCU 建立與其他 ESP8266 的 UDP 透傳通訊
- ESP8266 AT 指令下的透傳模式
- 如何使用 AT 指令讓同在 AP+STA 模式下的 ESP8266 互相通訊 ?
- 初遇 IoT ( Internet of Thing, 物聯網 ) 加強版 - 使用 ESP8266 Arduino AT 函式庫上傳溫溼度資料到 Thingspeak ( AT v1.2.0.0 based on SDK 1.5.4.1)
- 給我一個可操作 AT 指令的 Arduino 函式庫 - 解決 AT 指令處理的蛋疼問題 (親測 AT v1.2.0.0 韌體)
- 自行更新 ESP8266 無線模組韌體至 - AT:1.2.0.0, SDK:1.5.4.1
- ESP8266 ( ESP-01 ) 無線模組燒錄 NodeMCU 韌體 ( Lua 語法支援 )
- 自行更新 ESP8266 , ESP-01 無線模組韌體至 - AT:0.23, SDK:1.0.1
- 初遇 IoT ( Internet of Thing, 物聯網 ) - 使用 Arduino 控制 ESP8266 無線模組上傳資料到 IoT Server ( ThingSpeak )
- 操控 ESP8266 無線模組 - 經由 AP、STA 和 AP+STA 三種模式,學習 ESP8266 AT 指令
- 如何燒錄 ESP8266 無線模組的韌體 ( 使用一鍵燒錄軟體,燒錄版本:0018000902 )
- 初遇 IoT ( Internet of Thing, 物聯網 ) - 使用 Arduino 控制 ESP8266 無線模組上傳資料到 IoT Server ( ThingSpeak )
- 使用 Arduino IDE 開發 ESP8266 物聯網應用 - ThingSpeak, HTTP GET / POST 資料上傳方法
- 使用 Arduino IDE 開發 ESP8266 物聯網應用 - 取回 ThingSpeak 特定 Channel 和 Field 最後一筆資料
- ESP8266 入門學習套件支援 Arduino IDE 開發環境之安裝、使用說明與範例
Hello, can you help me add the code for the DS18B20 sensor to this please?
回覆刪除Someone already done this!
刪除http://www.instructables.com/id/ESP8266-Wifi-Temperature-Logger/
您好 我在使用esp8226搭配DS18B20時無法傳訊息到thingspeak,能否幫忙解答一下哪裡出錯,以下為我得程式碼
刪除#include
#include
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//esp8266設定
#define SSID "704"
#define PASSWORD "07040377"
#include "uartWIFI.h"
#include
WIFI wifi;
#define IP "184.106.153.149" // thingspeak.com
String GET = "GET /update?key=OABNXN650G0AHNID=";
void setup()
{
sensors.begin(); // Start up the ds18b20 library
wifi.begin();
bool b = wifi.Initialize(STA, SSID, PASSWORD);
if(!b)
{
DebugSerial.println("Init error");
}
delay(8000); //make sure the module can have enough time to get an IP address
String ipstring = wifi.showIP();
DebugSerial.println("My IP address:");
DebugSerial.println(ipstring); //show the ip address of module
String wifistring = wifi.showJAP();
DebugSerial.println(wifistring); //show the name of current wifi access port
}
void loop()
{
//DS18B20讀取
sensors.requestTemperatures();
float sensor_ds18temp = sensors.getTempCByIndex(0);
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
delay(5000);
if(Serial.find("Error")){
return;
}
cmd = GET;
cmd += "&field1=";
cmd += sensor_ds18temp;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if(Serial.find(">")){
Serial.print(cmd);
}else{
Serial.println("AT+CIPCLOSE");
}
delay(6000);
出現的問題為重複出現以片字串AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=47
AT+CIPCLOSE
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=47
AT+CIPCLOSE
sensor_ds18temp 要轉成字元陣列或是字串型態
刪除感謝作者回覆,後來我參考了下一篇AT指令的教學文章後,搞懂了程式碼中的內容,也自己重打了新的程式碼,最後終於順利的成功連線到thingspeak,真是由衷的感謝。
刪除不好意思 如果使用mega 2560的板子的話 會有哪些接腳位置的差異? library會有差嗎?
回覆刪除如果可以有供參考的配線圖嗎?
Arduino 程式碼裡面已經指定了接腳,只要照著接腳號碼接在板子上就可以,使用的板子基本上只是多了接腳與多了其他功能的支援!
刪除線路圖就是網頁提供的那張,著著指定的接腳號碼接在你的 MEGA2560 上相對應的接腳位置上,就可以使用!
我用土壤濕度和DHT11搭配繼電器作控制,但目前遇到沒辦法上傳的狀況,想知道是哪裡寫錯
刪除謝謝!
序列埠監控視窗顯示
DHTxx test!
AT
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=63
AT+CIPCLOSE
Humidity: 50 % Temperature: 48 *C 82 *F Heat index: 82.77 *F
我的程式碼:
刪除#include
#include "DHT.h"
#define DEBUG
#define _ledpin 13
//*-- Hardware Serial
#define _baudrate 9600
//*-- Software Serial
//
#define _rxpin 2
#define _txpin 3
SoftwareSerial debug( _rxpin, _txpin ); // RX, TX
//*-- DHT11
#define _dhtpin 8
#define _dhttype DHT11
DHT dht11( _dhtpin, _dhttype );
uint8_t dhtbuf[2];
//*-- IoT Information
#define SSID "rainbow"
#define PASS "eric33302"
#define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149
String GET = "GET /update?key=E0UT0LYS5UBIZ1O0=";
int sensorPin = 0;
int sensorValue = 0;
const int relay1 = 22;
const int relay2 = 24;
void setup() {
Serial.begin( _baudrate );
Serial.println("DHTxx test!");
pinMode(relay1,OUTPUT);
dht11.begin();
pinMode(relay2,OUTPUT);
debug.begin( _baudrate );
sendDebug("AT");
delay(5000);
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK\nData ready to sent!");
connectWiFi();
}
dht11.begin();
}
void loop()
{
delay(500);
sensorValue = analogRead(sensorPin);
dhtbuf[0] = dht11.readHumidity();
dhtbuf[1] = dht11.readTemperature();
dhtbuf[5] = dht11.readTemperature(true);
if( isnan(dhtbuf[0]) || isnan(dhtbuf[1]))
{
debug.println( "Failed to read form DHT11" );
}
else if (isnan(sensorValue))
{
Serial.println("Failed to read from soil moist sensor!");
return;
}
else
{
digitalWrite( _ledpin, HIGH );
char buf[3], sensorValue;
String HH, TT, SW ;
dhtbuf[0]= 0x30 + dhtbuf[1] / 10;
dhtbuf[1]= 0x30 + dhtbuf[0]% 10;
TT = (String(buf)).substring( 0, 2 );
buf[0] = 0x30 + dhtbuf[0] / 10;
buf[1] = 0x30 + dhtbuf[0] % 10;
HH = (String(buf)).substring( 0, 2 );
SW = String(sensorValue);
updateDHT11( TT, HH, SW);
#ifdef DEBUG
debug.print("Humidity: ");
debug.print( HH );
debug.print(" %\t");
debug.print("Temperature: ");
debug.print( TT );
debug.println(" *C\t");
debug.print("sensorValue");
debug.println( SW );
#endif
digitalWrite( _ledpin, LOW );
}
delay(20000);
// Compute heat index
// Must send in temp in Fahrenheit!
float hi = dht11.computeHeatIndex(dhtbuf[5], dhtbuf[0]);
int openFanT;
int openFanH;
int openPadpump;
int openWaterpump;
int PopenFanT=1;
int PopenFanH=1;
int PopenPadpump=1;
int PopenWaterpump=1;
if(dhtbuf[1]>=35.6){
openFanT = 1;
openPadpump = 1;
PopenFanT = 1;
PopenPadpump = 1;
}else if(dhtbuf[1]<32.6){
openFanT = 0;
openPadpump = 0;
PopenFanT = 0;
PopenPadpump = 0;
}else {openFanT = PopenFanT;}
if(dhtbuf[0]>=90.5){
openFanH = 1;
PopenFanH =1;
}else if(dhtbuf[0]<70.5){
openFanH = 0;
PopenFanH = 0;
}else{openFanH = PopenFanH;}
switch(openFanT+openFanH){
case 0:
digitalWrite(relay1,LOW);
break;
case 1:
digitalWrite(relay1,HIGH);
break;
case 2:
digitalWrite(relay1,HIGH);
break;
default:
break;
}
if(sensorValue<300){
openWaterpump = 1;
PopenWaterpump = 1;
}else if(sensorValue>=700){
openWaterpump = 0;
PopenWaterpump = 0;
}else {openWaterpump = PopenWaterpump;}
Serial.print("Humidity: ");
Serial.print(dhtbuf[0]);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(dhtbuf[1]);
Serial.print(" *C ");
Serial.print(dhtbuf[5]);
Serial.print(" *F\t");
Serial.print("Heat index: ");
Serial.print(hi);
Serial.println(" *F");
Serial.print("soilsenor=");
Serial.println(sensorValue);
}
void updateDHT11( String T, String H, String SW )
刪除{
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
delay(2000);
if( Serial.find( "Error" ) )
{
debug.print( "RECEIVED: Error\nExit1" );
return;
}
cmd = GET + "&field1=" + T + "&field2=" + H +"&field3="+SW+"\r\n";
Serial.print( "AT+CIPSEND=" );
Serial.println( cmd.length() );
if(Serial.find( ">" ) )
{
debug.print(">");
debug.print(cmd);
Serial.print(cmd);
}
else
{
sendDebug( "AT+CIPCLOSE" );
}
if( Serial.find("OK") )
{
debug.println( "RECEIVED: OK" );
}
else
{
debug.println( "RECEIVED: Error\nExit2" );
}
}
void sendDebug(String cmd)
{
debug.print("SEND: ");
debug.println(cmd);
Serial.println(cmd);
}
boolean connectWiFi()
{
Serial.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
sendDebug(cmd);
delay(5000);
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK");
return true;
}
else
{
debug.println("RECEIVED: Error");
return false;
}
cmd = "AT+CIPMUX=0";
sendDebug( cmd );
if( Serial.find( "Error") )
{
debug.print( "RECEIVED: Error" );
return false;
}
}
您好:
刪除當程式正常執行的狀況下,不能上傳資料到 ThingSpeak 可能有下面兩個原因:
1. 取得的數據錯誤。看一下取得的 DHT11 和土壤類比輸入的數值對不對 ?
2. ThingSpeak 的 Channel 裡面的 Field# 設定錯誤
您應該要先手動測試是否可以正確上傳資料到 ThingSpeak ( 資料格式在網頁上面有說到 ),使用所提供的程式碼做測試 (假設程式中所提供的 KEY 是正確的 ),得到的回傳數值是 0
http://api.thingspeak.com/update?key=E0UT0LYS5UBIZ1O0=&field1=30&field2=75&field3=223
所以不管程式是否正常運作,數據還是傳不上去 ThingSpeak
只要手動測試成功,就只是差在輸入到 ESP8266 後,後面要加 "\r\n" 而已。檢查一下 KEY 有沒錯誤,和檢查 Channel 裡面的設定是否正確。
不好意思 DHT library的載點掛掉了 可以麻煩在PO一次嗎?謝謝
回覆刪除剛剛確認過了,已經更新連結,可以再次下載了!
刪除謝謝提醒!
謝謝你這麼快就回我,我使用了程式發現我的esp8266並沒有像你一樣出現recevied:OK,請問這是我的ESP8266要更新嗎?
刪除AT
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=55
AT+CIPCLOSE
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=55
AT+CIPCLOSE
不好意思我剛剛發現我的是黑板要用115200bps,但是我的DHT11要用的是9600bps,請問程式要如何去做更改才能讓兩者的bps同時不一樣
刪除A1:沒有出現 receive:OK,表示 ESP8266 沒有回應給微處理器!網頁中有標明一開始所使用的韌體版本,即便現在是使用新版本的韌體,但沒收到任何舊版本韌體不能使用的訊息!
刪除你應該要先確認板子是否正常可以使用,在檢查線路接線是否正確 ? 若是硬體出現問題,請向你的販售者詢問!
A2:ESP8266 使用的是 UART,DHT11 使用的是單線通訊,兩者通訊是不一樣的,跟程式完全沒有關係!
經過幾次測試之後我已經能夠RECEIVE了,但是
刪除SEND: AT+CIPSTART="TCP","184.106.153.149",80
就直接跳到
SEND: AT+CIPCLOSE
RECEIVED: ErrorExit2
請問這是什麼原因呢?
從程式碼看,會發生這種錯誤是因為沒有取得 ESP8266 的回應符號 ">",在你送出下面兩行程式碼之後
刪除Serial.print( "AT+CIPSEND=" );
Serial.println( cmd.length() );
查一下 CIPSEND 的說明就可以知道
/*-------------------
響應:
發送指定長度的數據。
收到此命令後先換行返回“ > ” ,然後開始接收串口數據,當數據長度滿 length 長時發送數據,回到普通指令模式,等待下一條AT指令。
如果未建立連接或連接被斷開,返回
ERROR
如果數據發送成功,返回
SEND OK
-------------------*/
所以應該是連線沒有建立成功導致!
在此分享一下我如何讓它出現 receive:OK,首先我的ESP8266是最新版程式碼baud率要設置115200,而且SSCOM也要設置到3.2也要設置到115200。
回覆刪除接著如果你照著接線方法上傳卻出現avrdude: stk500_getsync(): not in sync: resp=0x00,那就表示你的程式碼要改成
void setup() {
Serial.begin( _baudrate );
debug.begin( _baudrate );
delay(10000);
sendDebug("AT");
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK\nData ready to sent!");
connectWiFi();
}
並且CH_PD線要先拔掉在上傳如此一來便能成功,之後再十秒內插上去。
應該要這樣解釋:
刪除如果在線路中沒有特別為了 Arduino 的 TX 或是 RX 做佈線的話,只要有在線路中直接使用 Arduino 的硬體 UART,在燒錄時建議拔掉 TX 與 RX 兩隻接腳,因為這會導致 Arduino 燒錄時會出現問題。
我試了很久均沒有改善
刪除SEND: AT+CIPCLOSE
RECEIVED: ErrorExit2還是會一直出現,
但是如果我使用USB轉TTL直接接esp8266照著程式碼裡的指令輸入是能連上thingspeak的。
請問這是因為我沒有使用麵包版電源模組的緣故嗎?
我改了一下程式碼
刪除String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
delay(2000);
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK");
}
else
{
debug.println("RECEIVED: Error");
}
來幫助我是哪部分做錯,結果發現是沒連上thingspeak,SSCOM3.2送出這段訊息
SEND: AT+CIPMUX=0
SEND: AT+CIPSTART="TCP","184.106.153.149",80
RECEIVED: Error
奇怪的是我使用USB轉TTL直接接esp8266並且打出 AT+CIPSTART="TCP","184.106.153.149",80的時候可以直接連上。請問這是原因呢?
我發現我在更早之前的程式並沒有成功,我將它改成OK但是卻也沒有回傳出東西,究竟要怎麼改才能讓cmd = "AT+CIPMUX=0";下達成功,以下是我的程式碼。
刪除cmd = "AT+CIPMUX=0";
sendDebug( cmd );
if( Serial.find( "OK") )
{
debug.print( "RECEIVED: Error" );
return false;
}
這是我從arduino的COM觀看來的
刪除AT
AT+CWMODE=1
AT+CWJAP="[FLOWER-PC_Network]","[401440044]"
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=54
GET /update?key=5O0EN53RYL89LM59&field1=00&field2=00
我發現他似乎少了cmd = "AT+CIPMUX=0";來寫入進去為什麼會這樣呢?
還是同樣的問題:沒有連上有效的網路!
刪除AT+CWJAP="[FLOWER-PC_Network]","[401440044]"
這一行改成下面試試,或許就可以連上網路
AT+CWJAP="FLOWER-PC_Network","401440044"
太神啦!!!沒想到居然是錯在這麼小的一個地方,謝謝你。
刪除但是thingspeak的橫軸沒辦法輸出成以分鐘為單位,他現在是以日期為單位。因此呢同一天的數據全部都會擠在一個點。有辦法把它改為分鐘嗎?
刪除ThingSpeak 的問題,要自己解決!Thingspeak 網站上面有使用說明,自己搞定吧!
刪除請問一下由於ESP8266要用115200的baudrate但是DHT11卻是要用9600的baud,否則的話數值會不正常。請問這要如何去解決呢?
刪除Serial.begin(115200)用在與 ESP8266 的串列通訊上;debig.begin(115200) 用在輸出除錯的字串到 USB轉 TTL 上,跟 DHT11 的通訊上完全沒有關係。DHT11 沒有使用到 UART!
刪除您好,這是我送給ESP8266的AT指令(重覆部分)
回覆刪除AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=58
GET /update?key=QNX742O9CGSTV3YC&field1=26.0&field2=58.0
ThingSpeak按照您教學的做法做的,但我一直無法順利將資料上傳(ThingSpeak沒收到資料)
而且就算不通過Arduino 直接用 USB →TTL 模組寫入ESP8266也沒辦法
想請教可能的原因或己決辦法。
謝謝
1. 有沒使用網址列上傳過資料,結果如何 ?
刪除這一個網址在瀏覽器中會得到數字的回應,但不是 thingspeak 伺服器回應的錯誤號碼
http://api.thingspeak.com/update?key=QNX742O9CGSTV3YC&field1=26.0&field2=58.0
檢查一下是不是已經有資料上傳,我得到的回傳是數字 6,表示資料已經有 6 筆
2. 如果不能使用網址列上傳表示 Thingspeak 設定有問題,檢查一下!
3. USB轉TTL模組寫入有問題
4. 如果不是使用賣場的電源模組,請先確認你的電源是否穩定和電流足夠!
可以的話,進詳細列出你的錯誤訊息與測試過程出來,不然簡單的問題也會搞很久!
您好,謝謝您的回覆
刪除1. 若直接透過瀏覽器可順利寫入 thingspeak
3. 直接使用USB轉TTL模組寫入AT與回應如下
AT
OK
AT+CWMODE=1
OK
AT+CWJAP="Angela","12121212"
OK
AT+CIPMUX=0
OK
AT+CIPSTART="TCP","184.106.153.149",80
CONNECT
OK
AT+CIPSEND=50
OK
> GET /update?key=QNX742O9CGSTV3YC&field1=0&field2=0
busy s...
SEND OK
【沒有資料上傳thingspeak】
4. 我使用的是實驗室電源供應器
因使用的DHT函式庫不同,小弟將您提供的程式稍做更改如下
刪除#include "SoftwareSerial.h"
#include "DHT.h"
#define DEBUG
#define _ledpin 13
#define _SerialBaudrate 115200
#define _DebugBaudrate 9600
//-------*USB 除錯
#define _rxpin 10
#define _txpin 11
SoftwareSerial debug(_rxpin, _txpin); // RX, TX
//-------*DHTXX 溫濕度感測器
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT11 // DHT 11 (AM2302)
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.
//uint8_t dhtbuf[2]; //0~255
//-------*聯網資訊
#define SSID "Angela"
#define PASS "12121212"
#define IP "184.106.153.149" //ThingSpeak 的 IP
//Add data by sending a POST or GET to:
//https://api.thingspeak.com/update
//Please include your write API key and some data, for example:
//https://api.thingspeak.com/update?key=QNX742O9CGSTV3YC&field1=0&field2=0
//GET 傳送格式
String GET = "GET /update?key=QNX742O9CGSTV3YC";
void setup() {
Serial.begin(_SerialBaudrate);
debug.begin(_DebugBaudrate);
//ESP8266 check
sendDebug("AT");
if(Serial.find("OK"))
{
debug.println("Send AT\n\tESP8266 received: ok!(Date read to send)");
connectWifi();
}
//DHTXX 溫濕度感測器
dht.begin();
pinMode(_ledpin, OUTPUT);
digitalWrite(_ledpin, LOW);
}
void loop() {
delay(250);
float h = dht.readHumidity();
float t = dht.readTemperature();
float hic = dht.computeHeatIndex(t, h, false);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t))
{
debug.println("Failed to read from DHT sensor!");
}
else
{
digitalWrite(_ledpin, HIGH);
String HH, TT;
HH +=String(int(h))+ "."+String(getDecimal(h));
TT +=String(int(t))+ "."+String(getDecimal(t));
updataDHT(TT, HH);
#ifdef DEBUG
debug.print("Hum: ");
debug.print(HH);
debug.print(" %\t");
debug.print("Tmp: ");
debug.print(TT);
debug.println(" *C\t");
#endif
digitalWrite(_ledpin, LOW);
}
delay(5000);
}
boolean connectWifi()
刪除{
//將WiFi設為Station: 【AT+CWMODE=1】
Serial.println("AT+CWMODE=1");
delay(5000);
//連線指令: 【AT+CWJAP="SSID","PASS"】
String cmd = "AT+CWJAP=\"";
cmd += SSID;
cmd += "\",\"";
cmd += PASS;
cmd += "\"";
sendDebug(cmd);
if(Serial.find("OK"))
{
debug.println("Send AT+CWJAP=,\n\tESP8266 received: ok!");
return true;
}
else
{
debug.println("Send AT+CWJAP=,\n\tESP8266 received: error!");
return false;
}
//關閉多重連線: 【AT+CIPMUX=0】
cmd = "AT+CIPMUX=0";
sendDebug(cmd);
if(Serial.find("Error"))
{
debug.println("Send AT+CIPMUX=0\n\tESP8266 received: Error...");
return false;
}
}
void sendDebug(String cmd)
{
debug.print("Send: ");
debug.print(cmd);
cmd+="\r\n";
Serial.print(cmd);
//Serial.print("\r\n");
}
long getDecimal(float val)
{
int intPart = int(val);
long decPart = 1000*(val-intPart); //I am multiplying by 1000 assuming that the foat values will have a maximum of 3 decimal places
//Change to match the number of decimal places you need
if(decPart>0)return(decPart); //return the decimal part of float number if it is available
else if(decPart<0)return((-1)*decPart); //if negative, multiply by -1
else if(decPart=0)return(00); //return 0 if decimal part of float number is not available
}
void updataDHT(String T, String H)
{
//讓 ESP8266 扮演 Client: 【AT+CIPSTART=,,】CIPMUX=0
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
if(Serial.find("Error"))
{
debug.println("Send AT+CIPSTART=,,\n\tESP8266 received: Error...");
return;
}
//發送TCP/IP資料: 【AT+CIPSEND=】CIPMUX=0
//https://api.thingspeak.com/update?key=QNX742O9CGSTV3YC&field1=0&field2=0
cmd = GET + "&field1=" + T + "&field2=" + H + "\r\n";
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if(Serial.find(">"))
{
debug.print(">");
sendDebug(cmd);
//Serial.print(cmd);
}
else
{
//關閉TCP/IP: 【AT+CIPCLOSE= or AT+CIPCLOSE】
sendDebug("AT+CIPCLOSE");
}
if(Serial.find("OK"))
{
debug.println("Send AT+CIPCLOSE\n\tESP8266 received: OK!");
}
else
{
debug.println("Send AT+CIPCLOSE\n\tESP8266 received: Error...");
}
}
【Arduino with ESP8266】
刪除AT
AT+CWMODE=1
AT+CWJAP="Angela","12121212"
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=58
AT+CIPCLOSE
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=58
GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=62.0
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=58
GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=63.0
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=58
GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=62.0
【Arduino with USB/TTL】
刪除Send: ATSend AT
ESP8266 received: ok!(Date read to send)
Send: AT+CWJAP="Angela","12121212"Send AT+CWJAP=,
ESP8266 received: ok!
Send: AT+CIPSTART="TCP","184.106.153.149",80Send: AT+CIPCLOSESend AT+CIPCLOSE
ESP8266 received: OK!
Hum: 62.0 % Tmp: 29.0 *C
Send: AT+CIPSTART="TCP","184.106.153.149",80>Send: GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=62.0
Send AT+CIPCLOSE
ESP8266 received: OK!
Hum: 62.0 % Tmp: 29.0 *C
Send: AT+CIPSTART="TCP","184.106.153.149",80>Send: GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=63.0
Send AT+CIPCLOSE
ESP8266 received: OK!
Hum: 63.0 % Tmp: 29.0 *C
不知道你是否直接使用網頁中原始的程式測試過 ? 在出現問題的時候,其實應該要去使用原始可動作的程式做測試,以釐清自己寫的程式是否出現錯誤!
刪除建議與想法:
(A)..........................................................
1. 使用原使網頁中所附的程式做測試,修改程式中的 API KEY
2. 取消 setup() 中的 dht11.begin
// dht11.begin();
3. 修改 loop() 中的 dht 呼叫函式,直接賦值給
dhtbuf[0] = 65.5;
dhtbuf[1] = 28.5;
完成上面三個之後,在線路確認沒問題之後就可以上傳程式做測試!程式沒有出現編譯錯誤的話,就可以直接上傳數據到 ThingSpeak。確認一下 Thingspeak 收到數據沒 ?
(B)..........................................................
(A) 若是成功,比較一下輸出訊息與你自己的輸出訊息有什麼不一樣,就知道問題出在哪裡 !
Send: AT+CIPSTART="TCP","184.106.153.149",80>Send: GET /update?key=QNX742O9CGSTV3YC&field1=29.0&field2=62.0
Send AT+CIPCLOSE <------ "成功傳送出去數據到 ThingSpeak 這一行不應該出現"
ESP8266 received: OK!
------------------------------------------------
自己先測試一下 (A),做完之後若還需要討論,請將 ( A ) 的訊息先 POST 上來!
您好,感謝您的建議,我已於作天測試成功(之前自己弄卡了好幾天)
刪除目前仍有幾個小問題
1. wifi分享器疑似訊號不穩:使用指令【AT+CWJAP="SSID","PASS"】OK,指令【AT+CIPSTART=長度】無反應
2. wifi分享器疑似本身問題:使用第一台無論如何都無法上傳資料至thingspeak,但以同樣的線路、程式換了另一台wifi分享器就成功了
請問 如果沒有 Level Shifter ( 3V3 / 5V 電壓準位轉換模組)是不是就沒辦法傳資料到 ThingSpeak呢?
回覆刪除應該是說:只要微控制器使用的是 3V3 準位的就不需要!但因為我使用的 arduino 是使用 5V 準位,所以必須要加才能安全的傳送命令給 ESP8266。
回覆刪除目前使用 arduino mega 板 有用賣場3v3電源供應器來供應ESP8266
回覆刪除通訊速率:9600
接法是: 【Arduino】TX→【ESP8266】URXD
【Arduino】RX→【ESP8266】UTXD
【穩壓器(電源模組)】3.3v → 【ESP8266】VCC
【穩壓器(電源模組)】3.3v → 【ESP8266】CH_PD
【穩壓器(電源模組)】GND → 【ESP8266】GND
【穩壓器(電源模組)】GND → 【Arduino】GND
USB 轉 TTL 模組的RXD →UTXD
USB 轉 TTL 模組的TXD →URXD
DHT接法跟上述一樣
沒開ESP826的電源
SSCOM3.2的內容為
SEND: AT
SEND: AT+CIPCLOSE
RECEIVED: Error Exit2
Humidity: 43 % Temperature: 25 *C
-----------------------------------
開電源後,重跑 SSCOM內容為空白
是什麼問題??
看起來應該是接線接錯了!
刪除請再確認線路是否與網頁中的電路圖相同。
ESP8266 -> Arduino TX, RX;USB 轉 TTL -> Arduino D2, D3
ESP8266 與 Arduino 相接,至少 ESP8266 URXD 要接 level shifter.
太讚了!
回覆刪除多謝您的支持!
刪除新手發問
回覆刪除ESP8266透過終端機或Arduino的Serial手動下達指令,動作都正常
ThingSpeak也能正確收到資料
但使用範例程式自動完成動作時
就連loop內的第一句AT都無法正確收到"OK"的回應
想請問一下該如何解決這個問題?
電源部分使用電源供應器,沒有電壓/電流不足的疑慮
程式則採用和範例相同,DH11可正確取得溫濕度
麻煩大大求助!!
網頁的範例是早前的通訊速率 9600 bps,確認一下終端機連線時所使用的速率是不是跟下面程式碼中的一樣,不一樣就把程式碼改成你現在ESP8266通訊的速率。
刪除//*-- Hardware Serial
#define _baudrate 9600
我ESP8266是黑色版子
回覆刪除Arduino對ESP8266是設定115200
Arduino對電腦是設定9600(也嘗試過115200)
#include
//*-- Software Serial
//
#define _RX 11
#define _TX 10
SoftwareSerial esp8266( _RX, _TX );
void setup() {
Serial.begin(9600);
Serial.println("Hi!");
esp8266.begin(115200);
SendData("AT");
delay(5000);
if(esp8266.find("OK"))
{
Serial.println("RECEIVED: OK\nData ready to sent!");
}
}
void loop() {
}
void SendData(String cmd)
{
Serial.print("SEND: ");
Serial.println(cmd);
esp8266.println(cmd);
}
這隻程式碼可以正確收到"OK"後回傳訊息
#include
回覆刪除#include "DHT.h"
#define DEBUG
#define _ledpin 13
//*-- Software Serial
//
#define _RX 11
#define _TX 10
SoftwareSerial esp8266( _RX, _TX );
//*-- DHT11
#define _dhtpin 8
#define _dhttype DHT11
DHT dht11( _dhtpin, _dhttype );
uint8_t dhtbuf[2];
//*-- IoT Information
#define SSID "LIU-WiFi"
#define PASS "m0301111"
#define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149
// 使用 GET 傳送資料的格式
// GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&filed2=[data 2]...;
String GET = "GET /update?key=OQU6V72ZTZQG3P4F";
void setup() {
Serial.begin(115200);
esp8266.begin(115200);
Serial.println("Hi!");
Serial.flush();
SendData("AT");
if(esp8266.find("OK"))
{
Serial.println("RECEIVED: OK\nData ready to sent!");
connectWiFi();
}
else
Serial.println("RECEIVED: AT,FAIL");
// DHT11
dht11.begin();
pinMode( _ledpin, OUTPUT );
digitalWrite( _ledpin, LOW );
}
void loop() {
// DHT11 溫濕度讀取時間不要小於 1 秒
// DHT11 溫溼度不需要小數位,也沒有小數位
dhtbuf[0] = dht11.readHumidity();
dhtbuf[1] = dht11.readTemperature();
// 確認取回的溫溼度數據可用
if( isnan(dhtbuf[0]) || isnan(dhtbuf[1]) )
{
Serial.println( "Failed to read form DHT11" );
}
else
{
digitalWrite( _ledpin, HIGH );
char buf[3];
String HH, TT;
// 轉換為 10 進位,並轉換為字串
buf[0] = 0x30 + dhtbuf[1] / 10;
buf[1] = 0x30 + dhtbuf[1] % 10;
TT = (String(buf)).substring( 0, 2 );
buf[0] = 0x30 + dhtbuf[0] / 10;
buf[1] = 0x30 + dhtbuf[0] % 10;
HH = (String(buf)).substring( 0, 2 );
// DHT11 溫度與濕度傳送
updateDHT11( TT, HH );
#ifdef DEBUG
Serial.print("Humidity: ");
Serial.print( HH );
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print( TT );
Serial.println(" *C\t");
#endif
digitalWrite( _ledpin, LOW );
}
// 每隔多久傳送一次資料
delay(5000); // 60 second
}
void SendData(String cmd)
{
Serial.print("SEND: ");
Serial.println(cmd);
esp8266.println(cmd);
}
//----------------------------------------------------------
boolean connectWiFi()
{
esp8266.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
SendData(cmd);
delay(5000);
if(esp8266.find("OK"))
{
Serial.println("RECEIVED: OK");
//return true;
}
else
{
Serial.println("RECEIVED: WiFi connect Error");
//return false;
}
cmd = "AT+CIPMUX=0";
SendData( cmd );
if(esp8266.find("Error"))
{
Serial.println( "RECEIVED: AT+CIPMUX=0 Error" );
//return false;
}
}
//----------------------------------------------------------
void updateDHT11( String T, String H )
{
// 設定 ESP8266 作為 Client 端
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
SendData(cmd);
delay(2000);
if(esp8266.find("Error"))
{
Serial.println( "RECEIVED: Error\nExit1" );
return;
}
cmd = GET + "&field1=" + T + "&field2=" + H +"\r\n";
esp8266.println( "AT+CIPSEND=" );
esp8266.println( cmd.length() );
if(esp8266.find(">"))
{
Serial.print(">");
Serial.println(cmd);
esp8266.println(cmd);
}
else
{
SendData( "AT+CIPCLOSE" );
}
if(esp8266.find("OK"))
{
Serial.println( "RECEIVED: OK" );
}
else
{
Serial.println( "RECEIVED: Error\nExit2" );
}
}
這隻程式DH11可正確取得溫濕度
但第一個"AT"就收不到"OK"
上傳資料也無法正確抵達
麻煩大大幫忙找錯誤,感謝!!
若是連 AT 送出都收不到回應,那錯誤就出現 setup() 函式中。比較一下跟網頁中的程式有什麼不同!
刪除請先使用網頁中的例子試試結果,例子中只要修改應該修改的參數設定就好,試試看是否正常!
一個網友問的,上面名字沒顯示出來,我也不知道是誰! 發佈的時候也不知為什麼就不見了,所以我補在這邊,請自己認領一下 !
回覆刪除-----------------------------------------
編譯時出現以下錯誤:
警告:程式庫'DHT sensor library'裡有偽造資料夾.github
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino: In function 'void setup()':
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:38:24: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if(Serial.find("OK"))
^
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino: In function 'void updateDHT11(String, String)':
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:95:30: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if( Serial.find( "Error" ) )
^
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:104:25: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if(Serial.find( ">" ) )
^
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:114:25: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if( Serial.find("OK") )
^
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino: In function 'boolean connectWiFi()':
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:142:24: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if(Serial.find("OK"))
^
C:\Users\han\Documents\Arduino\DHT11_ThingSpeak\DHT11_ThingSpeak.ino:155:29: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if( Serial.find( "Error") )
回應的指令
AT
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=54
AT+CIPCLOSE
之後就沒有反應了
請問是哪裡出了問題呢
我重新使用 Arduino IDE 1.6.9 編譯了網頁的程式,沒有看到上面的編譯出現的警告! 那些編譯訊息沒什麼關係,可以忽略掉! 若真的受不了這些東西,可以試著改成 Serial.find((static const char*)"OK") 試試 !
刪除你的問題在上面就有討論到,問之前可以先去看看是不是對你有幫助!
若是輸出到 AT+CIPCLOSE 就斷掉,那問題就是出現 updateDHT11() 函式裡面,最大的原因可能是 ESP8266 根本沒有連上你指定的路由器,所以不能連到 thingspeak.
可以在程式執行的時候登入路由器看看是否有正確連接上。
你好是我提出的問題 真是抱歉
刪除我的版子是UNO版 程式上有差異嗎
今天試了一下還是只收到
AT
AT+CWMODE=1
AT+CWJAP="XXX","XXX"
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=54
AT+CIPCLOSE
溫濕度也一直讀不到
如果只有上面輸出,連 SEND: OK 都沒有就是你的接線有問題,因為連不上 ESP8266,它沒有回覆!
刪除另外,要貼 Log 要貼完整的!如果上面不是完整的 Log,請重貼上!
上面是完整的log沒錯喔
刪除問題已解決
只是一定要接USB轉TTL 然後UNO版一定要RESET才能收到SEND: OK
您好,想請問一下
回覆刪除#define SSID "[無線網路熱點名稱]"
#define PASS "[無線網路連線密碼]"
這邊是輸入隨便一個帳號密碼就可以嗎?
例如
HELLOWORLD
helloworld
還是說應該要輸入什麼特定的內容?
[無線網路熱點名稱]:家中無線網路的名稱
刪除[無線網路連線密碼]:家中無線網路的連線密碼
你好,想請問一下
回覆刪除#define SSID "[無線網路熱點名稱]"
#define PASS "[無線網路連線密碼]"
這邊的SSID和PASS是隨意給就好嗎?
例如
SSID HELLOWORLD
PASS helloworld
或是有特定要設定的內容嗎?
謝謝。
SSID 與 PASS 不可以隨便給! 用你手機產生一個一個可攜式無線基地台,點進去設定就可以看到名稱,SSID 就是這個基地台的名稱;再點擊配置進去可以設定連線密碼,這個就是 PASS。沒有這兩個,ESP8266 要連到哪裡去 ? 也不能與外界通訊 !
刪除您好,請問那如果要使用wifi esp8266上傳資料到thingspeak
回覆刪除它的概念是:
Arduino 讀取Sensor數據→傳送到ESP8266→ESP8266連接到路由器(一般筆電連接的wifi)→上傳到thingspeak
是這樣的嗎?
所以這樣的話SSID、PASS是設為路由器的嗎?
但是路由器wifi不只有一台電腦在連接,這樣是怎麼辨識的呢的?
目前使用手機的熱點,是可以連接的,
以上,再麻煩您了,謝謝。
你手機是用 3G 吃到飽的呀 ? 我舉這個例子好像讓你搞混了 !
刪除反正,因為 thingspeak 是位在網路的遠方,要從家裡面傳到那裏去,就需要一個中介的裝置幫忙,讓 ESP8266 可以將資料往網路遠方送;手機上面搜尋一下家裡面或是附近可以連上網的網路,看名稱與密碼是多少設上去就可以了。你只要負責設定這些東西就好,連上去之後它怎麼處理多方連線就不需要去管,因為它會自己處理。
為甚麼我的總是顯示:
回覆刪除AT
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=54
AT+CIPCLOSE
是因為ESP8266沒有回應嗎?該怎麼解決,我用好久喔...
code:
http://paste.ofcode.org/JUPJUQBcwaUmQLuvx7yy3s
Serial Port 是接 ESP-01,所以通訊速度要改成 115200 bps(除非你是使用9600bps 的通訊速度),debug port 接 "USB 轉 TTL模組",資料要從這邊看。
刪除仔細看一下電路圖比對你接的電路,我想你的線路應該裝反了 !
請問,DHT11+DS18B20兩個感測器在ThingSpeak上要顯示數值的話用一個頻道就可以了嗎?
回覆刪除一個頻道 (channel) 可以使用 6 個欄位 (field),DHT11+DS18B20 用一個頻道就夠用 !
刪除我想問一下有辦法利用thingspeak來控制燈泡之類的嗎???還是esp8266就只能用區網來控制家電?
回覆刪除當然可以! 將狀態丟到 thingspeak 去,然後 ESP8266 再去讀取資料集中最後一筆資料來變更燈泡狀態。thingspeak 一般用來儲存與時間有關係的數據,若是要從遠端控制燈泡狀態,可以使用 MQTT,這比較符合你的需要。
刪除若是要使用外部網路與 ESP8266 連線,直接控制 ESP8266 當然也可以,類似在電腦架 WebServer 一樣 ! 使用 ESP8266 它本身就可以是 WebServer,但是為了讓外部網路知道它的連線網址,那麼就需要登記一個網路名稱才能讓人連進來(DNS);再者,由於 ESP8266 是掛在路由器下面的內部網路,所以要在路由器設定轉址,這樣連進到你的路由器 IP,路由器根據傳進來的 PORT 就會轉到你的 ESP8266 去。
大抵上就是這樣 !
版主
回覆刪除上傳成功 IoT_Demo 程式執行 在 COM 視窗反覆出現下列提示 ThingSpeak 毫無動靜 請問 如何修改才對? 謝謝你!!
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=65
AT+CIPCLOSE
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=65
AT+CIPCLOSE
請看上面問與答!
刪除感謝 試好了 現在看到的問題是 TTL-->USB 雖然連上, 但是在 PC 跑 SSCOM3.2,exe 卻抓不到資料. 已經把 TX/RX 交換, 重開機, 切換 COM6/COM7, Baudrate 9600/115200 都試過了, 無效! 不知道漏了什麼步驟? 請指點一下 謝謝!!
回覆刪除先確認裝置管理員有正確安裝 "USB轉 TTL 模組",COM Port 旁邊不能有驚嘆號!
刪除In file included from C:\Users\Administrator\Documents\Arduino\libraries\DHT-sensor-library-master\DHT_U.cpp:22:0:
回覆刪除C:\Users\Administrator\Documents\Arduino\libraries\DHT-sensor-library-master\DHT_U.h:25:29: fatal error: Adafruit_Sensor.h: No such file or directory
#include
不好意思 請問一下這是什麼狀況..
你應該是下載到最新的版本 1.3.0 ! 因為網頁提供的是最新下載版本的連結,我剛剛去查了一下發現現在這個版本有 Bug,而且我下載編譯之後會出現其他的錯誤,詳細可看這個連結的(http://bit.ly/2i66Gy4)中的討論。
刪除為了方便使用者使用最新的版本,所以網頁連結放上最新版的下載連結;不過既然有出現問題,我會在上面網頁再增加一個可用的下載連結,等一下就可以上去下載試試 !
#include
回覆刪除#include 3
#include
LiquidCrystal_I2C lcd(0x27,16,2);
#define red 7
#define green 8
#define blue 9
#define DEBUG
#define _baudrate 9600
// USB TTL 偵錯用
#define _rxpin 0
#define _txpin 1
SoftwareSerial debug( 0,1); // RX, TX
// DHT溫溼度感測器
#include
#define dht_dpin A0
dht DHT;
byte bGlobalErr;
byte dht_dat[5];
// ESP8266 Wifi晶片
#define SSID "ASUS"
#define PASS "38902147"
#define IP "184.106.153.149" // ThingSpeak的IP
// 使用 GET 傳送資料的格式
String GET = "GET /update?key=QOZDLWAW635QA4UK";
void setup() {
InitDHT();
Serial.begin( _baudrate );
debug.begin( _baudrate );
delay(300);
sendDebug("AT");
delay(5000);
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK\nData ready to sent!");
connectWiFi();
}
delay(700);
lcd.init(); // initialize the lcd
//pinMode(FAN,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
// Print a message to the LCD.
lcd.backlight();
Serial.begin(9600);
delay(700);//Wait rest of 1000ms recommended delay before
DHT.read11(dht_dpin); //去library裡面找DHT.read11
int A=DHT.humidity;
lcd.setCursor(0,0);
lcd.print("Hum= ");
lcd.print(A);
lcd.print("% ");
lcd.setCursor(0,1);
lcd.print("tem= ");
int TEMP=DHT.temperature;
lcd.print(DHT.temperature);
lcd.println("C ");
delay(1000); //每1000ms更新一次
if((TEMP<20)){
digitalWrite(blue,HIGH);
digitalWrite(green,LOW);
digitalWrite(red,LOW);
}
else if((TEMP>=21)&&(TEMP<=35)){
digitalWrite(green,HIGH);
digitalWrite(blue,LOW);
digitalWrite(red,LOW);
analogWrite(3, 127);
}
else {
digitalWrite(red,HIGH);
digitalWrite(green,LOW);
digitalWrite(blue,LOW);
analogWrite(3, 255);
}
}
void loop() {
ReadDHT();
String TT,HH;
HH = String(dht_dat[0])+'.'+String(dht_dat[1]);
TT = String(dht_dat[2])+'.'+String(dht_dat[3]);
updateDHT11( TT, HH );
#ifdef DEBUG
debug.print("Humidity: ");
debug.print( HH );
debug.print(" %\t");
debug.print("Temperature: ");
debug.print( TT );
debug.println(" *C\t");
#endif
delay(60000); // 一分鐘一次
}
void updateDHT11( String T, String H )
刪除{
// 使用AT指令上傳
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
delay(2000);
cmd = GET + "&field1=" + T + "&field2=" + H +"\r\n";
Serial.print( "AT+CIPSEND=" );
Serial.println( cmd.length() );
if(Serial.find( ">" ) )
{
debug.print(">");
debug.print(cmd);
Serial.print(cmd);
}
else
{
sendDebug( "AT+CIPCLOSE" );
}
if( Serial.find("OK") )
{
debug.println( "RECEIVED: OK" );
}
else
{
debug.println( "RECEIVED: Error\nExit2" );
}
}
void sendDebug(String cmd)
{
// 傳到 USB TTL
debug.print("SEND: ");
debug.println(cmd);
Serial.println(cmd);
}
boolean connectWiFi()
{
// 連線到Wifi
Serial.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
sendDebug(cmd);
delay(5000);
if(Serial.find("OK"))
{
debug.println("RECEIVED: OK");
return true;
}
else
{
debug.println("RECEIVED: Error");
return false;
}
cmd = "AT+CIPMUX=0";
sendDebug( cmd );
if( Serial.find( "Error") )
{
debug.print( "RECEIVED: Error" );
return false;
}
}
void InitDHT(){
// 初始化DHT
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);
}
void ReadDHT(){
bGlobalErr=0;
byte dht_in;
byte i;
digitalWrite(dht_dpin,LOW);
delay(20);
digitalWrite(dht_dpin,HIGH);
delayMicroseconds(40);
pinMode(dht_dpin,INPUT);
dht_in=digitalRead(dht_dpin);
if(dht_in){
bGlobalErr=1;
return;
}
delayMicroseconds(80);
dht_in=digitalRead(dht_dpin);
if(!dht_in){
bGlobalErr=2;
return;
}
delayMicroseconds(80);
for (i=0; i<5; i++)
dht_dat[i] = read_dht_dat();
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);
byte dht_check_sum =
dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
if(dht_dat[4]!= dht_check_sum)
{bGlobalErr=3;}
};
byte read_dht_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
while(digitalRead(dht_dpin)==LOW);
delayMicroseconds(30);
if (digitalRead(dht_dpin)==HIGH)
result |=(1<<(7-i));
while (digitalRead(dht_dpin)==HIGH);
}
return result;
}
上面兩個是我的程式請問他有什麼衝突嗎??
刪除只能顯示在LCD上,不能上傳溫溼度值
以上兩個是我的程式
刪除他只能顯示到LCD不能上傳thingspeak值
我該如何修改??
上面兩個是我的程式,他只能顯示在LCD不能上傳到thingspeak值
回覆刪除程式有什麼衝突嗎??因為程式沒有顯示在LCD時是可以上傳值
我該如何修改?
要先確認手動連線到 Thingspeak 是否可以手動輸入值。再來就是確認你的網路端連線都是正常的;否則能抓到溫溼度的值,不表示能夠連線到 thingspeak 上傳資料!
刪除版主您好:
回覆刪除我有在賣場購買IOT套件,目前在測試這個網頁的程式碼
我遇到的問題比較奇怪,我有先設定一組SSID與密碼,並且有成功連線
但是我將手機密碼換掉後(程式內有同步更改),卻沒有成功連線,換了2~3組都一樣不行
但再換回一開始設定那組又連成功了
想請問這個問題可能發生的原因,或我該如何解決?
感謝幫忙
如果是將手機設成無線基地台,要開啟"可供搜尋"的選項,不然可能找不到!
刪除但也有可能是你的手機與 ESP8266 都是連線到家中同一台無線 AP 上,所以就需要設定該無線 AP 的 SSID 與密碼,而不是手機的密碼。
這兩個地方要確認一下,應該就沒有問題了!
版主你好! 我想請教關於您所寫的程式
回覆刪除void sendDebug(String cmd)
{
debug.print("SEND: ");
debug.println(cmd);
Serial.println(cmd);
}
可以幫我解釋一下其中的CMD是跟前面的CMD是同一個東西嗎?
還有寫這段的用意為何?
小的我第一次接觸IOT所以還請賜教
debug.println(cmd); // 將 cmd 裡的內容輸出到 bebug 串列埠
刪除Serial.println(cmd); // 將 cmd 裡的內容輸出到與 esp8266
傳送到esp8266不是使用這個?SoftwareSerial debug( _rxpin, _txpin ); // RX, TX
刪除所以應該是 debug.println(cmd); // 將 cmd 裡的內容輸出到 esp8266串列埠 才是吧?
還是說SoftwareSerial debug( _rxpin, _txpin ); // RX, TX這個宣告是做USB轉ttl的監控腳位?
程式要對應電路圖去看,程式中腳位的宣告對應到電路圖上就不難了解! 既然寫 debug 就是作為除錯用,ESP8266 是接到 Arduino 板上面的硬體 TX = D0 跟 RX = D1,一些文字訊息則是由 D2/D3 這個串列埠輸出。
刪除所以esp8266是直接用0、1這兩腳座傳送和接收?
刪除然而debug是用宣告的兩隻腳位做接收盒傳送就對了!
對! 直接接好線燒好程式做測試,就會比較清楚了!
刪除說道測試,版主我一直有個問題,就是我使用AT指令測試的程式碼如下,不管輸入何種指令,都沒有反應,TX RX都確定沒接錯,但是從監控列窗做AT測試,ESP8266完全沒有任何反應和回復,但使用USB轉TTL卻是可以下達AT指令,並且正常回復,不知版主使否遇過這種問題,或是知道該如何解決,我也參考過 操控 ESP8266 無線模組 - 經由 AP、STA 和 AP+STA 三種模式,學習 ESP8266 AT 指令 這篇文章
刪除程式碼 :
#include // 引用程式庫
SoftwareSerial ESP(3, 2); // 接收腳, 傳送腳
void setup() {
Serial.begin(9600); // 與電腦序列埠連線,也能改成115200
ESP.begin(9600); // 與ESP-01模組連線或採用115200
Serial.println("Serial is ready!");
Serial.println("");
}
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到ESP-01模組。
if (Serial.available()) {
ESP.print(Serial.read());
}
// 若收到ESP-01模組的資料,則送到「序列埠監控視窗」。
if (ESP.available()) {
Serial.print(ESP.read());
}
}
如果你有仔細讀過網頁與問與答中的討論,你提出的這個問題應該不論是在網頁中或是問與答中已經有解答與解決方法 !
刪除網頁最下面補充的更新裡有附上這個問題討論與解決方法的討論郵件。
AT+CIPSTART="TCP","184.106.153.149",80
刪除CONNECT
OK
AT+CIPSEND=
OK
> ET /update?key=DUKST8GWAURKK1R0&field1=1
busy s...
Recv 0 bytes
SEND FAIL
CLOSED
是哪裡出錯?我測試了好久,都出現FAILD,我是用USB轉TTL模組測試,也已經連上WIFI
這個輸出好像不對 > ET /update?key=DUKST8GWAURKK1R0&field1=1
刪除如果有修改程式過,檢查一下吧!
我重試了一下 結果如下:
刪除AT+CIPSTART="TCP","184.106.153.149",80
CONNECT
OK
AT+CIPSEND=
OK
> GET/update?key=DUKST8GWAURKK1R0&field2=1
busy s...
Recv 0 bytes
SEND FAIL
一樣usb轉ttl模組測試
以下是我的指令
1 AT+CIPSTART="TCP","184.106.153.149",80
2 AT+CIPSEND=
3 GET/update?key=DUKST8GWAURKK1R0&field2=1
像這種指令的問題,網頁一開始就說的很清楚了! 一定要先確認可以由網址列手動輸入這些數值成功之後,才能確保接下來使用 AT 指令和執行程式時能夠正確!
刪除AT+CIPSEND=## 後面要接要輸入的字元數目,但你後面沒有加,不曉得你是省略還是忘了寫! AT 指令的操作請參考部落格另一個網頁中的說明,上面有實際操作範例;這網頁的問與答也有其他使用者的操作,自己看看吧!
我經過網頁測試都正常
刪除另外字元數我更改之後 指令如下
AT+CIPSEND=40
OK
> 5
busy s...
Recv 40 bytes
SEND OK
+IPD,323:HTTP/1.1 400 Bad Request
Server: nginx/1.7.5
Date: Sat, 11 Mar 2017 15:55:07 GMT
Content-Type: text/html
Content-Length: 172
Connection: close
和一串HTML文字(不接受HTML 這網站)
CLOSED
我上thingspeak發現數值並未改變 跪求教學
GET /update?key=DUKST8GWAURKK1R0&field2=1
刪除^ 空一格
最後面還要加上 \r\n 兩個字元,所以應該是 AT+CIPSEND=43
網址手動輸入如果是正常,那麼最大的問題就是 AT 指令輸入有問題;其實值接使用程式碼測試應該就可以成功!
測試成功!
刪除我應用了版主的程式如下:
if(digitalRead(re1) == 0 && digitalRead(HG_switch) == 1)
{
digitalWrite(LED_R1 ,LOW);
digitalWrite(LED_G1 , HIGH);
String cmd1 = "AT+CIPSTART=\"TCP\",\"";
cmd1 += IP;
cmd1 += "\",80";
sendDebug(cmd1);
delay(1000);
if( Serial.find( "Error" ) )
{
debug.print( "RECEIVED: Error\nExit1" );
return;
}
cmd1 = GET + "&field1=1" +"\r\n";
Serial.print( "AT+CIPSEND=" );
Serial.println( cmd1.length() );
delay(100);
if(Serial.find( ">" ) )
{
debug.print(">");
debug.print(cmd1);
Serial.print(cmd1);
}
else
{
sendDebug( "AT+CIPCLOSE" );
}
delay(100);
if( Serial.find("OK") )
{
debug.println( "RECEIVED: OK" );
}
else
{
debug.println( "RECEIVED: Error\nExit2" );
}
}
if(digitalRead(re2) == 0 && digitalRead(HG_switch) == 1)
{
digitalWrite(LED_R2 ,LOW);
digitalWrite(LED_G2 , HIGH);
String cmd2 = "AT+CIPSTART=\"TCP\",\"";
cmd2 += IP;
cmd2 += "\",80";
sendDebug(cmd2);
delay(1000);
if( Serial.find( "Error" ) )
{
debug.print( "RECEIVED: Error\nExit1" );
return;
}
cmd2 = GET + "&field2=1" +"\r\n";
Serial.print( "AT+CIPSEND=" );
Serial.println( cmd2.length() );
delay(100);
if(Serial.find( ">" ) )
{
debug.print(">");
debug.print(cmd2);
Serial.print(cmd2);
}
else
{
sendDebug( "AT+CIPCLOSE" );
}
delay(100);
if( Serial.find("OK") )
{
debug.println( "RECEIVED: OK" );
}
else
{
debug.println( "RECEIVED: Error\nExit2" );
}
}
我所遇到的問題如下:
我將 re1接地、hg_switch 接HIGH ,並且有成功上傳THINGSPEAK
然後我將 re1、hg_switch復位(re1 high、hg_switch low)
但是我將re2接地、hg_switch接high,但在監控序列卻傳回
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=43
AT+CIPCLOSE
這是怎麼回事?要如何解決?
他們是 輸入角位
回覆刪除我是要讓他們達到我所設定的狀態才做上傳動作
所以簡單來說我做了一次的上傳,做第二次時卻會失敗出現
AT+CIPSTART="TCP","184.106.153.149",80
AT+CIPSEND=43
AT+CIPCLOSE
可以反過來試一下先做第二個條件是再做第一個,看看是不是一樣的情況!
刪除一樣的情況
刪除那跟我猜測的結果一樣!最大的可能是因為資料上傳間隔的問題造成,其實可以試一下拉長切換的時間試試,應該就不會,但也有可能時好時壞 !
刪除那兩個 if 判斷式可以整合成一個副程式來用,應該就可以解決這個問題 ! 如果不行,就要看一下程式是不是在時間間隔未到之前就重復上傳資料到 thingspeak, 這會造成錯誤的!
謝謝版主指導,已經解決了這個問題,但問題一波未平一波起
刪除我現在做上傳的動作,在VOID SETUP的區塊做以下指令:
String cmd0 = "AT+CIPSTART=\"TCP\",\"";
cmd0 += IP;
cmd0 += "\",80";
sendDebug(cmd0);
delay(200);
if( Serial.find( "Error" ) )
{
debug.print( "RECEIVED: Error\nExit1" );
return;
}
cmd0 = GET + "&field1=0&field2=0&field3=0&field4=0" + "r/n";
Serial.print( "AT+CIPSEND=" );
Serial.println( cmd0.length() );
delay(100);
if(Serial.find( ">" ) )
{
debug.print(">");
debug.print(cmd0);
Serial.print(cmd0);
}
else
{
sendDebug( "AT+CIPCLOSE" );
}
if( Serial.find("OK") )
{
debug.println( "RECEIVED: OK" );
}
else
{
debug.println( "RECEIVED: Error\nExit2" );
}
但是我從thingspeak中看field4的狀態卻出現field4:0r
這是怎麼回事?
cmd0 = GET + "&field1=0&field2=0&field3=0&field4=0" + "r/n";
刪除仔細看一下上面這一行,對照一下,就不難發現哪邊寫錯了!
恩....我發現了....
刪除實在是演殘...
版主您好
回覆刪除以下是我用 Realterm 叫 esp8266 傳給 Thingspeak 的情況
但 Thingspeak 卻回傳 400 Bad Request
之前試過一樣的步驟似乎沒問題 但是之後卻不行了
是不是有遺失字元或其他原因
麻煩版主指導 ((一個小新手看網頁做的實驗
OK
> // GET /update?api_key=ZKANMZVA3YINU7L9&field1=5&field2=7
Recv 56 bytes
SEND OK
+IPD,172:
400 Bad Request
400 Bad Request
nginx/1.7.5
CLOSED
http://api.thingspeak.com/update?api_key=ZKANMZVA3YINU7L9&field1=10&field2=15
刪除這個的格式是對的,剩餘的就是指令下的問題,這參照上面的問與答,有相關的例子可以參考!
版主你好
回覆刪除請問如果想要自己寫一個asp.net的網站,接收arduino的資料
有相關的資訊嗎? 謝謝
沒有!
回覆刪除若是單純要用電腦架 web server 來接收 Arduino 的資料,主要就是要看怎麼去收 Arduino 傳過來的資料,可以是直接由 Serial 接收,也可以經由網路的方式。
前者應該就是寫 PC 端的 RS232 程式接收資料再反應到網站上;後者的處理就是使用 CGI 的方式去處理後台,也就是處理傳送過來 Get 或是 post 資料,可以用 PHP 或是 JavaScript 去處理或是其他可用的程式語言。
以上,提供作參考 !
版主,你好
回覆刪除我想請問,我手機可以連的wifi和密碼,套用到這裡的SSID、PASS 是可以的嗎??
UART 我的畫面都沒有AT+CWJAP
UART指令畫面如下:
SEND: AT
OK
SEND: AT+CIPSTART="TCP","184.106.153.149",80
OK
Linked
SEND: AT+CIPCLOSE
OK
Unlink
RECEIVED: Error
Error
Exit2
Error
Humidity: 48 % Temperature: 24 *C
若照著網頁中的步驟做,且確定手動輸入沒有問題,但輸出與網頁不一樣時,就是與 ESP8266 間的接線出現問題!
刪除相關檢查的步驟請自行參閱問與答中的說明。
您好 我最近收集了一批資料,之前可以從DATA import/export處進行下載
回覆刪除不過今日卻發現他無法直接下載,而且還需要寄信給到他們的信箱
我剛剛計過去後系統告訴我他們的信箱已經滿了
想請問一下您對這問題有解答嗎 感恩
即使不能直接下載,但是在 "DATA import / export" 網頁頁面下的右半部說明了可以使用 HTTP GET 的方式來取得 Channel 上面的部分或是全部的數據,例如使用下面網頁中所提及的方法
刪除https://www.mathworks.com/help/thingspeak/readdata.html
假設 channel 號碼是 14725,要取得所有 Fields 的數據 (假設數據點共有 350 點),並以 CSV 的方式回傳,可在網址列輸入:
https://api.thingspeak.com/channels/14725/feeds.csv?results=350
可得到類似下面的 CSV 數據資料
-------------------------------------
created_at,entry_id,field1,field2
2017-01-04 09:10:31 UTC,1,23,60
2017-01-04 09:11:32 UTC,2,23,61
2017-01-04 09:12:32 UTC,3,23,61
...
2017-01-04 15:02:11 UTC,348,28,44
2017-01-04 15:03:10 UTC,349,28,44
2017-01-04 15:04:11 UTC,350,29,43
-------------------------------------
若要限定時間點(2018/08/20 10:01:02 ~ 2018/08/26 15:04:05,則輸入
https://api.thingspeak.com/channels/14725/feeds.csv?start=2018-08-20%2010:01:02&end=2018-08-26%2015:04:05
使用這樣的方式就可取得 Channel 裡面的資料,更詳細的資料請自行參考上述網頁裡面的說明。
老師您好~ 我想請教老師為什麼資料上傳一段時間之後會失敗會是回傳 error 的問題,硬體的部分,有接電源模組以及電壓準位轉換器,所以排除電源不足的問題,還是說會是esp8266模組韌體的問題,我有用AT v1.2.0.0 SDK v1.5.4.1版本是過也一樣,會是程式上的問題嗎?我不太清楚什麼原因造成的,這問題我卡很久了,希望老師能幫我解答,該如何解決 謝謝~
回覆刪除SSID跟PASS就略過,上傳的資料是簡單的電阻分壓,再透過MCU去讀取它的AD值
----------------------------------------------------------------------------------------------------------------
#include
#include
#define _baudrate 9600
#define _rxpin 3
#define _txpin 2
SoftwareSerial debug( _rxpin, _txpin ); // RX, TX
//*-- IoT Information
#define SSID "帳" //WIFI的AP Name
#define PASS "密" //WIFI的AP pwsd
#define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149
// 使用 GET 傳送資料的格式
// GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&filed2=[data 2]...;
String GET = "GET /update?key=WZB4X9K5GDIOBLUH";
float deg=0;
float rad=deg*PI/180;
byte i=0;
void setup() {
Serial.begin( _baudrate );
debug.begin( _baudrate );
sendDebug("AT");
Loding("sent AT");
connectWiFi();
}
void loop() {
delay(5000); // 60 second 5000 , 2500 =30sec
SentOnCloud( String(analogRead(15)), String(analogRead(15)) ); //SEND DATA 5 AND 9
//delay(2500); // 60 second 5000 ,, 2500 =30sec
//SentOnCloud( String(-5), String(-9) ); //SEND DATA 5 AND 9
/*
for (i=100;i<=200;i=i+5) {
randomSeed(i);
deg==random(180);
rad=deg*PI/180;
SentOnCloud( String(10*sin(rad)), String(-10*cos(rad))); //SEND DATA sin(rad) AND cos(rad)
delay(2500); // 60 second 5000 ,, 2500 =30sec
} */
}
boolean connectWiFi()
{
debug.println("AT+CWMODE=1");
Wifi_connect();
}
void SentOnCloud( String T, String H )
{
// 設定 ESP8266 作為 Client 端
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
if( debug.find( "Error" ) )
{
Serial.print( "RECEIVED: Error\nExit1" );
return;
}
cmd = GET + "&field1=" + T + "&field2=" + H +"\r\n";
debug.print( "AT+CIPSEND=" );
debug.println( cmd.length() );
if(debug.find( ">" ) )
{
Serial.print(">");
Serial.print(cmd);
debug.print(cmd);
}
else
{
debug.print( "AT+CIPCLOSE" );
}
if( debug.find("OK") )
{
Serial.println( "RECEIVED: OK" );
}
else
{
Serial.println( "RECEIVED: Error\nExit2" );
}
}
void Wifi_connect()
{
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
sendDebug(cmd);
Loding("Wifi_connect");
}
void Loding(String state){
for (int timeout=0 ; timeout<10 ; timeout++)
{
if(debug.find("OK"))
{
Serial.println("RECEIVED: OK");
break;
}
else if(timeout==9){
Serial.print( state );
Serial.println(" fail...\nExit2");
}
else
{
Serial.print("Wifi Loading...");
delay(500);
}
}
}
void sendDebug(String cmd)
{
Serial.print("SEND: ");
Serial.println(cmd);
debug.println(cmd);
}
有輸出的 LOG 嗎?
刪除抱歉 我不懂老師意思,什麼是LOG?
刪除就是程式執行時候的輸出!
刪除請先花時間看一下上面的問與答,或許就會有你要的答案。
老師你好 我想問一下
回覆刪除目前我先把WIFI 燒到ESP-01s裡面了
那我上傳THINGSPEAK的語法是要打在UNO上嗎?
還是ESP裡面??
謝老師
這網頁裡面的程式碼式是上傳到 Arduino UNO 開發板的,ESP-01S 是被 AT 指令控制的受控端,不需要對它上傳任何程式。
刪除您好,我本身不會寫程式...但看了您的文章學Arduino之後,我用ESP32抓取JSON資料和溫溼度上傳hingSpeak,目前想結合2個程式碼,抓取雨量資料的JSON然後上傳hingSpeak,但怎樣編譯都失敗請問可以教我該怎麼弄嗎? 以下是我改的
回覆刪除#include
#include
#include
#include
#include
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
//請修改以下參數--------------------------------------------
char ssid[] = "a310";//
char password[] = "01919803";//
char url[] = "https://data.wra.gov.tw/Service/OpenData.aspx?format=json&id=F7C0788D-F513-472D-A80E-1C6372C2FBA5"; //讀取的網址
String url = "http://api.thingspeak.com/update?api_key=H8KG3DK1IT0ETUXA&field1=0";//請修改為自己的API Key,並將https改為http
//---------------------------------------------------------
void setup()
{
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED))
{
Serial.println("Connected...");
HTTPClient http;//啟動http client物件
Serial.println("開始讀取資料");
http.begin(url); //HTTP取得網頁內容
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();//了解連線狀態
// httpCode will be negative on error
if (httpCode > 0)
{
Serial.println(httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK)
{
String payload = http.getString();//讀取網頁內容到payload
Serial.print("payload=");
//payload=payload.substring(0,200);//只擷取前面兩百個字
Serial.println(payload);
}
}
else //讀取失敗
{
Serial.println("[HTTP] GET... failed");
}
http.end();
}
delay(20000);
}
{
Serial.begin(115200);
lcd.init(); // initialize the lcd
lcd.backlight();//open light
Serial.print("開始連線到無線網路SSID:");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println("連線完成");
}
void loop()
{
Serial.print("使用核心編號:");
Serial.println(xPortGetCoreID());
//嘗試讀取雨量內容
byte HourlyRain = 0;
byte EffectiveWaterStorageCapacity = 0;
int err = SimpleDHTErrSuccess;
Serial.print("雨量讀取失敗,錯誤碼="); Serial.println(err); delay(1000);
return;
}
//讀取成功,將溫濕度顯示在序列視窗
Serial.print("雨量讀取成功: ");
Serial.print((int)HourlyRain); Serial.print(" *C, ");
Serial.print((int)EffectiveWaterStorageCapacity); Serial.println(" H");
lcd.init();
lcd.setCursor(0, 0);
lcd.print("HourlyRain:");
lcd.setCursor(12, 0);
lcd.print((int)EffectiveWaterStorageCapacity);
lcd.setCursor(14, 0);
lcd.print("\xDF""C");
lcd.setCursor(0, 1);
lcd.print("HourlyRain:");
lcd.setCursor(12, 1);
lcd.print((int)EffectiveWaterStorageCapacity);
lcd.setCursor(14, 1);
lcd.print("%");
//開始傳送到thingspeak
Serial.println("啟動網頁連線");
HTTPClient http;
//將溫度及濕度以http get參數方式補入網址後方
String url1 = url + "&field1=" + (int)HourlyRain + "&field2=" + (int)EffectiveWaterStorageCapacity;//請修改為你自己想上傳的參數
//http client取得網頁內容
http.begin(url1);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
//讀取網頁內容到payload
String payload = http.getString();
//將內容顯示出來
Serial.print("網頁內容=");
Serial.println(payload);
} else {
//讀取失敗
Serial.println("網路傳送失敗");
}
http.end();
delay(20000);//休息20秒
}
我重新整理了一下上面的程式碼,發現這程式基本上的架構已經不對,應該連編譯都過不了!
刪除如果是初學者,建議直接使用部落格上的程式碼下去改,去了解整個流程後再試著自己去做內部修改才會比較不容易出錯!