当前位置: 首页 > 知识库问答 >
问题:

ESP8266 NodeMCU不能发送TCP命令-同样的代码在Arduino Uno上工作?

刘选
2023-03-14

我在这方面是个新手,所以希望是一个愚蠢的明显的人。

我试图创建一个简单的温度/湿度传感器,从DHT22读取读数,并使用ESP8266将它们ping到ThingSpeak的API,然后绘制/存储等。

我在下面粘贴了代码--它在Arduino Uno上工作,我试图将它缩小到ESP8266上,这样我就可以为房子周围生产很多小温度传感器。

症状

    null

任何帮助,从一个更有经验的老手将非常感谢!

以下是串行监视器输出和代码的片断(只是密码/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;
  }
}


共有1个答案

景嘉实
2023-03-14

首先,在我们讨论您所面临的问题之前,您需要了解使用ESP8266的两种不同方式:

  • 将其用作WiFi调制解调器;
  • 将其作为独立MCU使用。

当使用它作为WiFi调制解调器时,您使用AT-command与它通信,默认情况下,这是大多数ESP8266模块所做的,它附带AT-command固件。

#include <DHT.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.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 PORT 80
#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

DHT dht(DHTPIN, DHTTYPE);

//this runs once
void setup()
{
  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());

  //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
  updateTemp(c, h);

  //wait for delay time before attempting to post again
  delay(DELAY_TIME);
}


bool updateTemp(float tempC, float humid) {

  WiFiClient client;    // Create a WiFiClient to for TCP connection

  if (!client.connect(IP, PORT)) {
   Serial.println("HTTP connection failed");
   return false;
  }

  Serial.println("Sending data to server");
  if (client.connected()) {
    client.print("GET /update?api_key="); client.print(API);
    client.print("&field1="); client.print(String(tempC));
    client.print("&field2="); client.print(String(humid));
    client.println(" HTTP/1.1");
    client.print("Host: "); client.println(IP);
    client.println("Connection: close");
    client.println();    //extra "\r\n" as per HTTP protocol
  }

  // wait for data to be available
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
     Serial.println("HTTP Client Timeout !");
     client.stop();
     return false;
    }
  }

  Serial.println("Receiving HTTP response");
  while (client.available()) {
   char ch = static_cast<char>(client.read());
   Serial.print(ch);
  }
  Serial.println();

  Serial.println("Closing TCP connection");
  client.stop();
  return true;
}
 类似资料:
  • 命令“code”。在这本手册里不起作用? 之前的所有其他步骤都奏效了。如何调用OSX终端中的Visual Studio代码?

  • EasySwoole支持用户进行自定义格式的命令解析与路由。以下我们将以最基础的例子作为讲解。 建立自定义命令解析类 namespace AppSock; use CoreComponentSocketAbstractInterfaceAbstractClient; use CoreComponentSocketAbstractInterfaceAbstractCommandParser; use

  • 问题内容: 我正在尝试执行我的PHP代码,该代码通过mysqli调用两个MySQL查询,并得到错误“命令不同步;您现在不能运行此命令”。 这是我正在使用的代码 我曾尝试阅读此书,但不确定该怎么做。我已经阅读了有关存储结果和免费结果的信息,但是使用它们时并没有什么区别。我不确定此错误的确切原因,并想知道其原因以及如何解决。 按照我的调试语句,由于我的sql语法near附近,甚至没有输入countQu

  • 我在项目后端使用firebase实时数据库,但在制定安全规则时遇到了问题。我使用REST与数据库通信并授权REST请求,我发送一个idToken作为“auth=”参数的查询,如https://firebase.google.com/docs/database/rest/auth. Firebase只检测到我被授权,但当我比较授权时。uid在数据库规则中它们是不同的。我设置了自己的服务器,如果我解码

  • 问题内容: 我已经将注册脚本从mysql转换为mysqli。我作为mysql正常工作,但是现在却给我错误 这是我用来注册用户的功能 电子邮件可以很好地发送来自我的阵列的正确数据。但是,没有数据插入到数据库中,并且出现了上面提到的错误。我以前从未遇到过这个错误。 问题答案: 如果 命令不同步; 您现在无法在客户端代码中运行此命令,您以错误的顺序调用了客户端函数。 例如,如果您使用的是mysql_us