要从OneNet获取命令并控制舵机,可以使用ESP8266的AT指令集和OneNet的HTTP API来实现。

首先,需要在OneNet平台上创建一个数据流,用于接收控制命令。在代码中,可以通过HTTP GET请求获取该数据流的最新数据,并解析其中的命令。

以下是修改后的代码,其中加入了从OneNet获取控制命令的功能:

#include "ESP8266.h"
#include "dht11.h"
#include "SoftwareSerial.h"
#include <WiFi.h>
#include <Servo.h>

//配置ESP8266WIFI设置
#define SSID "HONOR Play4T"    //填写2.4GHz的WIFI名称,不要使用校园网
#define PASSWORD "12345678"   //填写自己的WIFI密码
#define HOST_NAME "api.heclouds.com"  //API主机名称,连接到OneNET平台,无需修改
#define DEVICE_ID "1099655073"       //填写自己的OneNet设备ID
#define HOST_PORT (80)                //API端口,连接到OneNET平台,无需修改
String APIKey = "IiJSs17atNND2C77wumz03w63hw="; //与设备绑定的APIKey

#define INTERVAL_SENSOR 5000 //定义传感器采样及发送时间间隔

//创建dht11示例
dht11 DHT11;
//创建舵机
Servo myservo;
int servoPin = 7;
int light = 0;
int servoPos = 0;
//定义DHT11接入Arduino的管脚
#define DHT11PIN 4

//定义ESP8266所连接的软串口
/*********************
 * 该实验需要使用软串口
 * Arduino上的软串口RX定义为D3,
 * 接ESP8266上的TX口,
 * Arduino上的软串口TX定义为D2,
 * 接ESP8266上的RX口.
 * D3和D2可以自定义,
 * 但接ESP8266时必须恰好相反
 *********************/
SoftwareSerial mySerial(3, 2);
ESP8266 wifi(mySerial);

void handleCommand(String command) {
  Serial.print("Command received: ");
  Serial.println(command);

  if (command == "0") { //控制舵机转到0度位置
    myservo.write(0);
    servoPos = 0;
    Serial.println("Servo position: 0");
  } else if (command == "1") { //控制舵机转到180度位置
    myservo.write(180);
    servoPos = 180;
    Serial.println("Servo position: 180");
  } else {
    Serial.println("Invalid command");
  }
}

void setup() {
  mySerial.begin(115200); //初始化软串口
  Serial.begin(9600);     //初始化串口
  Serial.print("setup begin\r\n");

  myservo.attach(servoPin);
  myservo.write(0);

  //以下为ESP8266初始化的代码
  Serial.print("FW Version: ");
  Serial.println(wifi.getVersion().c_str());

  if (wifi.setOprToStation()) {
    Serial.print("to station ok\r\n");
  } else {
    Serial.print("to station err\r\n");
  }

  //ESP8266接入WIFI
  if (wifi.joinAP(SSID, PASSWORD)) {
    Serial.print("Join AP success\r\n");
    Serial.print("IP: ");
    Serial.println(wifi.getLocalIP().c_str());
  } else {
    Serial.print("Join AP failure\r\n");
  }
  Serial.println("");
  Serial.print("DHT11 LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);

  mySerial.println("AT+UART_CUR=9600,8,1,0,0");
  mySerial.begin(9600);
  Serial.println("setup end\r\n");
}

unsigned long net_time1 = millis(); //数据上传服务器时间
unsigned long net_time2 = millis(); //获取命令时间
void loop() {

  if (net_time1 > millis())
    net_time1 = millis();

  if (millis() - net_time2 > INTERVAL_SENSOR) //获取命令时间间隔
  {
    //拼接GET请求字符串
    String getString = "GET /devices/";
    getString += DEVICE_ID;
    getString += "/datastreams/command/latest?type=2 HTTP/1.1";
    getString += "\r\n";
    getString += "api-key:";
    getString += APIKey;
    getString += "\r\n";
    getString += "Host:api.heclouds.com\r\n";
    getString += "Connection:close\r\n";
    getString += "\r\n";
    getString += "\r\n";
    getString += "\r\n";

    const char *getArray = getString.c_str(); //将str转化为char数组

    if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接,如果失败,不能发送该数据
      Serial.print("create tcp ok\r\n");
      wifi.send((const uint8_t *)getArray, strlen(getArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
      Serial.println("send success");

      char buf[1024];
      int len = wifi.recv((uint8_t *)buf, sizeof(buf), 10000); //接收返回数据,10s超时
      if (len > 0) {
        buf[len] = '\0';
        Serial.println(buf);

        //解析返回的JSON数据,获取命令
        String command = "";
        char *pos = strstr(buf, "\"value\":");
        if (pos != NULL) {
          pos += 8;
          while (*pos != '"') {
            command += *pos;
            pos++;
          }
          handleCommand(command);
        }
      }

      if (wifi.releaseTCP()) { //释放TCP连接
        Serial.print("release tcp ok\r\n");
      } else {
        Serial.print("release tcp err\r\n");
      }
      getArray = NULL; //清空数组,等待下次获取命令
    } else {
      Serial.print("create tcp err\r\n");
    }

    Serial.println("");

    net_time2 = millis();
  }

  if (millis() - net_time1 > INTERVAL_SENSOR) //发送数据时间间隔
  {

    int chk = DHT11.read(DHT11PIN);

    Serial.print("Read sensor: ");
    switch (chk) {
    case DHTLIB_OK:
      Serial.println("OK");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.println("Checksum error");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.println("Time out error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }

    float sensor_hum = (float)DHT11.humidity;
    float sensor_tem = (float)DHT11.temperature;
    Serial.print("Humidity (%): ");
    Serial.println(sensor_hum, 2);

    Serial.print("Temperature (oC): ");
    Serial.println(sensor_tem, 2);
    Serial.println("");

    if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接,如果失败,不能发送该数据
      Serial.print("create tcp ok\r\n");
      char buf[10];

      //拼接发送data字段字符串
      String jsonToSend = "{\"Temperature\":";
      dtostrf(sensor_tem, 1, 2, buf);
      jsonToSend += "\"" + String(buf) + "\"";
      jsonToSend += ",\"Humidity\":";
      dtostrf(sensor_hum, 1, 2, buf);
      jsonToSend += "\"" + String(buf) + "\"";
      jsonToSend += ",\"light\":";
      jsonToSend += "\"" + String(light) + "\"";
      jsonToSend += "}";

      //拼接POST请求字符串
      String postString = "POST /devices/";
      postString += DEVICE_ID;
      postString += "/datapoints?type=3 HTTP/1.1";
      postString += "\r\n";
      postString += "api-key:";
      postString += APIKey;
      postString += "\r\n";
      postString += "Host:api.heclouds.com\r\n";
      postString += "Connection:close\r\n";
      postString += "Content-Length:";
      postString += jsonToSend.length();
      postString += "\r\n";
      postString += "\r\n";
      postString += jsonToSend;
      postString += "\r\n";
      postString += "\r\n";
      postString += "\r\n";

      const char *postArray = postString.c_str(); //将str转化为char数组

      Serial.println(postArray);
      wifi.send((const uint8_t *)postArray, strlen(postArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
      Serial.println("send success");

      if (wifi.releaseTCP()) { //释放TCP连接
        Serial.print("release tcp ok\r\n");
      } else {
        Serial.print("release tcp err\r\n");
      }
      postArray = NULL; //清空数组,等待下次传输数据
    } else {
      Serial.print("create tcp err\r\n");
    }

    Serial.println("");

    net_time1 = millis();
  }
}

其中,handleCommand()函数用于解析控制命令并控制舵机转动。在loop()函数中,首先获取控制命令,然后发送传感器数据,最后等待下一次循环。注意,获取命令和发送数据的时间间隔应该不同,否则会影响程序运行的稳定性。

需要注意的是,该代码中的获取命令部分只能获取最新的一条命令,如果有多条未读取的命令,则会丢失。如果需要获取所有未读取的命令,可以使用OneNet的HTTP API中的数据点查询接口来实现

#include ESP8266h#include dht11h#include SoftwareSerialh#includeWiFih#includeServoh配置ESP8266WIFI设置#define SSID HONOR Play4T 填写24GHz的WIFI名称不要使用校园网#define PASSWORD 12345678填写自己的WIFI密码#define HOST_NAM

原文地址: https://www.cveoy.top/t/topic/hhMm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录