You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带SIM卡和天线的MKR GSM 1400通过HTTP POST向Kaa云发送数据的Arduino代码问题排查

Fixing HTTP POST to Kaa Cloud with MKR GSM 1400

Let's break down why your Arduino code isn't working, even though the serial monitor says you're connected. I'll walk through the key issues and share a corrected version that matches your working cURL command.

Key Issues in Your Code

1. Missing SSL/TLS Support for HTTPS

Your code uses GSMClient, which is a plain TCP client. Kaa's endpoint uses HTTPS (port 443), so you need to use GSMSSLClient to establish a secure encrypted connection. Without this, your "connection" is just a raw TCP handshake—but the critical HTTPS handshake will fail silently, so no data actually gets transmitted to the cloud.

2. Malformed HTTP Request Format

Your POST request has several formatting errors:

  • You included the full https://connect.cloud.kaaiot.com:443 in the request line, but HTTP standards require only the path here. The server is specified via the Host header instead.
  • You're missing mandatory headers:
    • Content-Type: application/json: Tells Kaa you're sending valid JSON data
    • Host: connect.cloud.kaaiot.com: Required for all HTTP/1.1 requests
  • Your JSON payload doesn't match the working cURL command (yours is a single object, cURL uses an array of objects). While Kaa might accept single objects, aligning with your proven cURL request eliminates unnecessary variables.

3. Unnecessary Reconnection Spam

Your loop calls client.connect(server, port) every iteration, which causes unnecessary connection churn. Instead, check if the client is already connected before attempting to reconnect.

4. No Server Response Debugging

You never read the server's response after sending the request. This means you can't see error codes (like 401 Unauthorized for a bad token, or 400 Bad Request for invalid JSON) that would help you debug exactly what's going wrong.

5. Syntax Error in Unused Code

The line String queryString = String(" \"temperature\": ) + String(temp) "); has unclosed quotes. Even though it's commented out, it's a bug waiting to happen if you uncomment it later.

Corrected Arduino Code

Here's the fixed version that addresses all these issues:

#include <ArduinoHttpClient.h>
#include <MKRGSM.h>
#include <ArduinoJson.h>

const char PINNUMBER[] = "";
const char GPRS_APN[] = "";
const char GPRS_LOGIN[] = "";
const char GPRS_PASSWORD[] = "";
const String TOKEN = ""; // Fill in your endpoint token
const String APP_VERSION = ""; // Fill in your app version name

const unsigned long publishInterval = 5000UL; // 5 seconds
unsigned long lastPublish = 0;

// Use GSMSSLClient for HTTPS connections (critical for port 443)
GSMSSLClient client;
GPRS gprs;
GSM gsmAccess;

const char server[] = "connect.cloud.kaaiot.com";
const int port = 443;
HttpClient httpClient = HttpClient(client, server, port);

void setup() {
  Serial.begin(9600);
  while (!Serial); // Wait for serial monitor to connect (native USB only)

  Serial.println("Initializing GSM connection...");
  boolean connected = false;

  // Connect to GSM and GPRS network
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && 
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
      Serial.println("GSM/GPRS connected successfully!");
    } else {
      Serial.println("Failed to connect. Retrying...");
      delay(1000);
    }
  }
}

void loop() {
  // Reconnect to server if disconnected
  if (!client.connected()) {
    Serial.println("Connecting to Kaa server...");
    if (client.connect(server, port)) {
      Serial.println("Connected to Kaa cloud!");
    } else {
      Serial.println("Server connection failed. Retrying in 3 seconds...");
      delay(3000);
      return; // Skip rest of loop if connection fails
    }
  }

  // Publish data at specified interval
  unsigned long now = millis();
  if (now - lastPublish >= publishInterval) {
    lastPublish = now;

    // Generate sample sensor data
    int temp = random(18, 24); // Range: 18-23 inclusive
    int humidity = random(40, 60);
    Serial.printf("Publishing data: temperature=%d, humidity=%d\n", temp, humidity);

    // Build the exact path from your working cURL command
    String path = "/kp1/" + APP_VERSION + "/dcx/" + TOKEN + "/json";

    // Send properly formatted POST request
    httpClient.beginRequest();
    httpClient.post(path);
    // Add required HTTP headers
    httpClient.sendHeader("Host", server);
    httpClient.sendHeader("Content-Type", "application/json");
    // Send Content-Length header (good practice for JSON payloads)
    String payload = "[{\"temperature\": " + String(temp) + ", \"humidity\": " + String(humidity) + "}]";
    httpClient.sendHeader("Content-Length", payload.length());
    // Finalize headers and send payload
    httpClient.endRequest();
    httpClient.print(payload);

    // Read and print server response for debugging
    Serial.println("\nServer response:");
    int statusCode = httpClient.responseStatusCode();
    Serial.printf("Status code: %d\n", statusCode);
    String responseBody = httpClient.responseBody();
    Serial.println(responseBody);
  }

  // Small delay to prevent loop spam
  delay(100);
}

Additional Tips

  • Fill in your credentials: Make sure you populate PINNUMBER, GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD, TOKEN, and APP_VERSION with your actual values.
  • Use serial output for debugging: The corrected code prints the server's status code and response body. This will immediately tell you if there's an authentication issue, invalid path, or malformed JSON.
  • Power supply: MKR GSM 1400 uses significant power during GPRS/SSL connections. Use a robust power supply (not just USB) if running the device for extended periods.

内容的提问来源于stack exchange,提问作者Timor Bader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:32:48