Main Content

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

使用粒子光子板批量更新 ThingSpeak 通道

此示例演示如何使用连接到 Wi-Fi® 网络的粒子光子板批量更新 ThingSpeak™通道。您可以使用 Bulk-Write JSON Data API 批量收集数据并将其发送到 ThingSpeak 通道。通过使用批量更新,您可以降低设备的功耗。在此示例中,您每 15 秒收集一次数据,并使用粒子光子板每 2 分钟更新一次通道。由于粒子光子带有实时时钟,因此您可以使用绝对时间戳来进行批量更新消息。

设置

1)创建通道,如图Collect Data in a New Channel所示。

代码

1) 定义从粒子云同步时间的一天限制。

#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000) // Define 1 day limit for time synchronization
unsigned long lastSync = millis(); 

2) 初始化data缓冲区来保存数据。

char data[800] = ""; // Initialize the data buffer

3) 初始化TCP客户端库。

TCPClient client; // Initialize the TCP client library

4) 定义 ThingSpeak 服务器、您的通道写入 API 密钥以及您的通道ID。

String server = "api.thingspeak.com"; // ThingSpeak Server.
String WriteAPIKey = "YOUR-CHANNEL-WRITEAPIKEY"; // Replace YOUR-CHANNEL-WRITEAPIKEY with your channel write API key.
String ChannelID = "YOUR-CHANNEL-ID"; // Replace YOUR-CHANNEL-ID with your channel ID.

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.
size_t state = 0; // Keep note of first time the updateData() is called.

6) 不要修改默认的setup方法。

void setup() {
}

7) 使用 loop 方法调用 updateData 方法,每 15 秒更新一次 data 缓冲区的数据。另外,每天向粒子云请求一次时间同步。

void loop() {
    // If update time has reached 15 seconds, then update the data buffer
    if (millis() - lastUpdateTime >= updateInterval) {
      updateData();
  }
    // If last time synchronization is more than one day
    if (millis() - lastSync > ONE_DAY_MILLIS) {
    // Request time synchronization from the Particle Cloud
    Particle.syncTime();
    lastSync = millis();
  }
}

8) 定义 updateData 方法,用数据不断更新 data 缓冲区。由于 Particle Photon 具有内置的实时时钟,因此您可以在 API 调用中使用绝对时间。使用 time_format=absolute 参数定义连续消息之间的绝对时间戳。如果您的设备没有实时时钟,您可以使用相对时间戳。要使用相对时间戳,请将 time_format=absolute 替换为 time_format=relative。将消息格式化为 Bulk-Write JSON Data 中提到的 CSV 格式。调用 httpRequest 方法每两分钟向 ThingSpeak 发送一次数据。

// Update the data buffer
void updateData(){
    /* CSV format to bulk update.
   *  This function uses the absolute timestamp as it uses the "time_format=absolute" parameter. If your device does not have a real-time clock, 
   *  you can also provide the relative timestamp in seconds using the "time_format=relative" parameter.
   */
    if(state==0){
        strcpy(data,"write_api_key="+WriteAPIKey+"&time_format=absolute&updates=");
    }
    strcat(data,String(Time.local())); // Absolute time stamp.
    strcat(data,"%2C"); // URL encoding for ","
    long randNumber = random(1,300);
    strcat(data,String(randNumber)); // Data to post to field 1.
    strcat(data,"%2C");
    randNumber = random(1,300);
    strcat(data,String(randNumber)); // Data to post to field 2.
    strcat(data,"%2C%2C%2C%2C%2C%2C%2C%2C"); //Include commas after fields 2-8 and lattitude for 8 commas.
    randNumber = random(1,300);
    strcat(data,String(randNumber)); // Mock data to post to longitude.
    strcat(data,"%2C%7C"); // URL encoding for ",|". End with | at the end of a message.
    state = 1; 
    // If posting interval time has reached 2 minutes, then update the ThingSpeak channel with your data.
    if (millis() - lastConnectionTime >= postingInterval) {
        state = 0;
        size_t len = strlen(data);
        data[len-3] = '\0'; // Remove the | from the last message.
        httpRequest(data); // Call httpRequest to send the data to ThingSpeak.
        data[0] = '\0'; // Reinitialise the data buffer.
    }
    lastUpdateTime = millis(); // Update the last update time.
}

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

// Update the ThingSpeakchannel with data.
void httpRequest(char* csvBuffer) {
     /* CSV format to bulk update.
      * This function posts the data to ThingSpeak server.
   */
    // Compute the data buffer length.
    String data_length = String(strlen(csvBuffer));
    // Close any connection before sending a new request.
    client.stop();
    // POST data to ThingSpeak
    if (client.connect(server, 80)) {
        client.println("POST /channels/"+ChannelID+"/bulk_update HTTP/1.1");
        client.println("Host: "+server);
        client.println("User-Agent: mw.doc.bulk-update (Particle Photon)");
        client.println("Connection: close");
        client.println("Content-Type: application/x-www-form-urlencoded");
        client.println("Content-Length: "+data_length);
        client.println();
        client.println(csvBuffer);
    }
    else {
        Particle.publish("Failure","Failed to update ThingSpeak channel");
    }
    delay(1000); // Wait to receive the response.
    client.parseFloat();
    String resp = String(client.parseInt());
    Particle.publish("Response code",resp); // Print the response code. 202 indicates that the server has accepted the response.
    lastConnectionTime = millis(); // Update the last conenction time.
}

相关示例

详细信息