Main Content

本页采用了机器翻译。点击此处可查看英文原文。

使用 Arduino 或 ESP8266 进行批量更新

此示例演示如何使用连接到 Wi-Fi® 网络的 Arduino® MKR1000 板或 ESP8266 板来持续收集 Wi-Fi 信号强度并批量更新 ThingSpeak™通道。

您可以使用 Bulk-Write JSON Data API 批量收集数据并将其发送到 ThingSpeak 通道。此策略可减少设备的功耗。在此示例中,您使用 Arduino MKR1000 板每 15 秒收集一次数据,每 2 分钟更新一次通道。由于 Arduino MKR1000 和 ESP8266 板没有实时时钟,因此您可以使用相对时间戳来进行批量更新消息。

设置

  1. 创建一个通道,如 在新通道收集数据 所示。

  2. 如果您使用的是 Arduino MKR1000 板,请将库 WiFi101.hSPI.h 包含到您的 Arduino 代码中。如果您使用的是 ESP8266 板,请将库 EthernetClient.hESP8266WiFi.h 添加到您的 Arduino 代码中

代码

1) 首先包含适合您的硬件的库。

// #include<EthernetClient.h> //Uncomment this library to work with ESP8266
// #include<ESP8266WiFi.h> //Uncomment this library to work with ESP8266

#include<SPI.h> // Comment this to work with ESP8266 board
#include<WiFi101.h> // Comment this to work with ESP8266 board

2) 初始化jsonBuffer来保存JSON数据。

char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data

3) 定义 Wi-Fi 凭据以将 Arduino 板连接到网络,并初始化 Wi-Fi 客户端库。

char ssid[] = "YOUR-NETWORK-SSID"; //  Your network SSID (name)
char pass[] = "YOUR-NETWORK-PWD"; // Your network password
WiFiClient client; // Initialize the Wi-Fi client library

4) 定义 ThingSpeak 服务器。

char server[] = "api.thingspeak.com"; // ThingSpeak Server

5) 定义其他全局变量来跟踪上次连接时间和上次更新时间。此外,定义更新数据的时间间隔,并将数据发布到 ThingSpeak。

/* Collect data once every 15 seconds and post data to ThingSpeak channel once every 2 minutes */
unsigned long lastConnectionTime = 0; // Track the last connection time
unsigned long lastUpdateTime = 0; // Track the last update time
const unsigned long postingInterval = 120L * 1000L; // Post data every 2 minutes
const unsigned long updateInterval = 15L * 1000L; // Update once every 15 seconds

6) 使用setup方法初始化串行数据传输并连接到Wi-Fi网络。

void setup() {
  Serial.begin(9600);
  // Attempt to connect to Wi-Fi network
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    WiFi.begin(ssid, pass);  // Connect to WPA/WPA2 network. Change this line if using open or WEP network
    delay(10000);  // Wait 10 seconds to connect
  }
  Serial.println("Connected to Wi-Fi");
  printWiFiStatus(); // Print Wi-Fi connection information
}

7) 在loop方法中,调用updatesJson方法,每秒更新一次jsonBuffer数据。

void loop() {
  // If update time has reached 1 second, then update the jsonBuffer
  if (millis() - lastUpdateTime >=  updateInterval) {
    updatesJson(jsonBuffer);
  }
}

8) 定义updatesJson方法,不断更新jsonBuffer数据。由于 Arduino MKR1000 没有实时时钟,因此您可以使用 'delta_t' 参数来定义连续消息之间的相对时间戳(以秒为单位)。如果您的设备有实时时钟,则可以使用绝对时间戳。将 'delta_t' 参数替换为 'created_at' 参数。将消息格式化为 Bulk-Write JSON Data 中提到的 JSON 格式。调用 httpRequest 方法每 2 分钟向 ThingSpeak 发送一次数据。

// Updates the josnBuffer with data
void updatesJson(char* jsonBuffer){
  /* JSON format for updates parameter in the API
   *  This example uses the relative timestamp as it uses the "delta_t". 
   *  You can also provide the absolute timestamp using the "created_at" parameter instead of "delta_t".
   *  "[{\"delta_t\":0,\"field1\":-70},{\"delta_t\":3,\"field1\":-66}]"
   */
  // Format the jsonBuffer as noted above
  strcat(jsonBuffer,"{\"delta_t\":");
  unsigned long deltaT = (millis() - lastUpdateTime)/1000;
  size_t lengthT = String(deltaT).length();
  char temp[4];
  String(deltaT).toCharArray(temp,lengthT+1);
  strcat(jsonBuffer,temp);
  strcat(jsonBuffer,",");
  long rssi = WiFi.RSSI(); 
  strcat(jsonBuffer, "\"field1\":");
  lengthT = String(rssi).length();
  String(rssi).toCharArray(temp,lengthT+1);
  strcat(jsonBuffer,temp);
  strcat(jsonBuffer,"},");
  // If posting interval time has reached 2 minutes, update the ThingSpeak channel with your data
  if (millis() - lastConnectionTime >=  postingInterval) {
        size_t len = strlen(jsonBuffer);
        jsonBuffer[len-1] = ']';
        httpRequest(jsonBuffer);
  }
  lastUpdateTime = millis(); // Update the last update time
}

9) 定义 httpRequest 方法以将数据发送到 ThingSpeak 并打印来自服务器的响应代码。响应代码 202 表示服务器已接受处理请求。

// Updates the ThingSpeakchannel with data
void httpRequest(char* jsonBuffer) {
  /* JSON format for data buffer in the API
   *  This example uses the relative timestamp as it uses the "delta_t".
   *  You can also provide the absolute timestamp using the "created_at" parameter instead of "delta_t".
   *  "{\"write_api_key\":\"YOUR-CHANNEL-WRITEAPIKEY\",\"updates\":[{\"delta_t\":0,\"field1\":-60},{\"delta_t\":15,\"field1\":200},{\"delta_t\":15,\"field1\":-66}]
   */
  // Format the data buffer as noted above
  char data[500] = "{\"write_api_key\":\"YOUR-CHANNEL-WRITEAPIKEY\",\"updates\":"; // Replace YOUR-CHANNEL-WRITEAPIKEY with your ThingSpeak channel write API key
  strcat(data,jsonBuffer);
  strcat(data,"}");
  // Close any connection before sending a new request
  client.stop();
  String data_length = String(strlen(data)+1); //Compute the data buffer length
  Serial.println(data);
  // POST data to ThingSpeak
  if (client.connect(server, 80)) {
    client.println("POST /channels/YOUR-CHANNEL-ID/bulk_update.json HTTP/1.1"); // Replace YOUR-CHANNEL-ID with your ThingSpeak channel ID
    client.println("Host: api.thingspeak.com");
    client.println("User-Agent: mw.doc.bulk-update (Arduino ESP8266)");
    client.println("Connection: close");
    client.println("Content-Type: application/json");
    client.println("Content-Length: "+data_length);
    client.println();
    client.println(data);
  }
  else {
    Serial.println("Failure: Failed to connect to ThingSpeak");
  }
  delay(250); //Wait to receive the response
  client.parseFloat();
  String resp = String(client.parseInt());
  Serial.println("Response code:"+resp); // Print the response code. 202 indicates that the server has accepted the response
  jsonBuffer[0] = '['; //Reinitialize the jsonBuffer for next batch of data
  jsonBuffer[1] = '\0';
  lastConnectionTime = millis(); //Update the last conenction time
}

10) 定义 printWiFiStatus 方法来打印您的设备 IP 地址和信号强度。

void printWiFiStatus() {
  // Print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // Print your device IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // Print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

相关示例

详细信息