【发布时间】:2020-07-08 17:20:16
【问题描述】:
我是这方面的菜鸟,所以希望是一个愚蠢的显而易见的人。
我正在尝试创建一个简单的温度/湿度传感器,它从 DHT22 获取读数并使用 ESP8266 将它们 ping 到 Thingspeak 的 API,然后绘制/存储等。
我在下面粘贴了代码 - 它适用于 Arduino Uno,我正在尝试将其缩小到 ESP8266 上,这样我就可以在房子周围生产许多小型温度传感器。
症状
- wifi 连接正常
- 它正在生成正确的 API 字符串(我已经通过手动剪切并将其粘贴到浏览器中进行了测试)
- 温度传感器也生成正确的读数
- 它返回“数据失败!”在串行监视器中,表明这是代码中发生错误的位置
我不知道从 Arduino Uno 迁移到 ESP8266 是否有什么奇怪的地方会导致问题(即需要不同的库,TCP 命令不同等)
非常感谢经验丰富的老手的任何帮助!
这是串行监视器输出的 sn-p 和代码(只是密码/api 等)
22:16:50.266 -> **************
22:16:57.579 -> Wifi Connection Successful
22:16:57.579 -> The IP Address of the Sensor is:192.168.1.211
22:16:57.579 -> Humidity: 41.50
22:16:57.579 -> Temperature: 21.70
22:16:57.579 -> AT+CIPSTART="TCP","api.thingspeak.com",80
22:17:00.574 -> AT+CIPSEND=63
22:17:01.561 -> AT+CIPCLOSE
22:17:02.577 -> Data Fail!
22:17:02.577 -> GET /update?apikey=<REMOVED>&field1=21.70&field2=41.50
#include<stdlib.h>
#include "DHT.h"
#include <ESP8266WiFi.h>
#define SSID "<REMOVED>" //your network name
#define PASS "<REMOVED>" //your network password
#define API "<REMOVED>" //api string
#define IP "api.thingspeak.com" // thingspeak.com
#define DHTPIN 4 // what pin the DHT sensor is connected to
#define DHTTYPE DHT22 // Change to DHT22 if that's what you have
#define Baud_Rate 115200 //Another common value is 9600
#define DELAY_TIME 300000 //time in ms between posting data to ThingSpeak
//Can use a post also
String GET = String("GET /update?apikey=") + API + "&field1=";
String FIELD2 = "&field2=";
//if you want to add more fields this is how
//String FIELD3 = "&field3=";
bool updated;
DHT dht(DHTPIN, DHTTYPE);
//this runs once
void setup()
{
delay(5000);
Serial.begin(Baud_Rate);
// Connect to WIFI
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print("*");
}
Serial.println("");
Serial.println("Wifi Connection Successful");
Serial.print("The IP Address of the Sensor is:");
Serial.println(WiFi.localIP()); //Print the IP Address
//initalize DHT sensor
dht.begin();
}
//this runs over and over
void loop() {
float h = dht.readHumidity();
Serial.print("Humidity: ");
Serial.println(h);
// Read temperature as Fahrenheit (isFahrenheit = true)
float c = dht.readTemperature();
Serial.print("Temperature: ");
Serial.println(c);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(c)) {
Serial.println("Reading DHT22 Failed, exiting");
return;
}
//update ThingSpeak channel with new values
updated = updateTemp(String(c), String(h));
//wait for delay time before attempting to post again
delay(DELAY_TIME);
}
bool updateTemp(String tempC, String humid) {
//initialize your AT command string
String cmd = "AT+CIPSTART=\"TCP\",\"";
//add IP address and port
cmd += IP;
cmd += "\",80";
//connect
Serial.println(cmd);
delay(2000);
if (Serial.find("Error")) {
return false;
}
//build GET command, ThingSpeak takes Post or Get commands for updates, I use a Get
cmd = GET;
cmd += tempC;
cmd += FIELD2;
cmd += humid;
cmd += "\r\n";
//continue to add data here if you have more fields such as a light sensor
//cmd += FIELD3;
//cmd += <field 3 value>
//Serial.println(cmd);
//Use AT commands to send data
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if (Serial.find(">")) {
//send through command to update values
Serial.print(cmd);
} else {
Serial.println("AT+CIPCLOSE");
}
if (Serial.find("OK")) {
//success! Your most recent values should be online.
Serial.println("Data Sent!");
return true;
} else {
Serial.println("Data Fail!");
Serial.println(cmd);
return false;
}
}
boolean connectWiFi() {
//set ESP8266 mode with AT commands
Serial.println("AT+CWMODE=1");
delay(2000);
//build connection command
String cmd = "AT+CWJAP=\"";
cmd += SSID;
cmd += "\",\"";
cmd += PASS;
cmd += "\"";
//connect to WiFi network and wait 5 seconds
Serial.println(cmd);
delay(5000);
//if connected return true, else false
if (Serial.find("OK")) {
Serial.println("WIFI connected");
return true;
} else {
Serial.println("WIFI not connected");
return false;
}
}
【问题讨论】:
-
一个问题和两个评论:我找不到仅通过 WiFi 串行发送数据的部分。在 ESP(以及 Arduinos 顺便说一句)上永远不要使用延迟。这会停止处理(因此所有 wifi/spiffs a.s.o)函数,并且出于稳定性原因,从不使用 String 类。它会破坏你的堆并使 ESP 崩溃 - 使用编译到闪存的固定字符数组并使用 const 字符的指针(即命令序列、文本 aso。)作为测试:从 PC 上的 USB 中删除你的 ESP 并尝试获取数据 OTA(无线)
-
Re wifi - 是的,它应该通过 wifi 上的串行 TCP 连接发送,即这部分://Serial.println(cmd); //使用AT指令发送数据 Serial.print("AT+CIPSEND="); Serial.println(cmd.length()); if (Serial.find(">")) { //通过命令发送更新值 Serial.print(cmd); } else { Serial.println("AT+CIPCLOSE"); }
-
重新延迟 - 有趣,以前从未听说过 - 实际上这都是来自许多教程,他们说您必须使用延迟来确保它不会破坏服务器等?那么我应该如何建立延迟?
-
重新测试 - 将它与 PC 分离,看看会发生什么?
标签: tcp arduino esp8266 esp8266wifi