qq_39610896 2024-05-27 23:43 采纳率: 56.3%
浏览 7
已结题

arduino上连sim900a实现连接mqtt服务器

我想通过arduino上连接sim900a模块实现连接onenet物联网平台的mqtt服务器(新版),想用sim900 a提供网络,不想用esp8266模块,应该如何写代码?下面这段代码在修改了对应值之后,创建mqtt客户端处有误,应如何修改?

#include <SoftwareSerial.h>
#include <PubSubClient.h>

// Sim900A配置
SoftwareSerial sim900aSerial(2, 3); // RX, TX
const char apn[] = "your_apn"; // 替换为您的APN
const char user[] = "your_user"; // 替换为您的APN用户名
const char pass[] = "your_pass"; // 替换为您的APN密码

// OneNET云平台配置
const char mqttServer[] = "oneNET_mqtt_broker_address"; // 替换为OneNET MQTT服务器地址
const uint16_t mqttPort = 1883; // MQTT默认端口
const char deviceId[] = "your_device_id"; // 替换为您的设备ID
const char apiKey[] = "your_api_key"; // 替换为您的API密钥

// 创建MQTT客户端实例
PubSubClient mqttClient(sim900aSerial);

void setup() {
  // 初始化串口
  Serial.begin(9600);
  sim900aSerial.begin(19200);

  // 设置Sim900A为GPRS模式
  sim900aSerial.println("AT+CGATT=1");
  delay(1000);
  sim900aSerial.println("AT+CGDCONT=1,\"IP\",\"your_apn\""); // 替换为您的APN
  delay(1000);
  sim900aSerial.println("AT+CIPSHUTDOWN");
  delay(1000);
  sim900aSerial.println("AT+CIPMUX=0");
  delay(1000);
  sim900aSerial.println("AT+CSTT=\"your_apn\""); // 替换为您的APN
  delay(1000);
  sim900aSerial.println("AT+CIICR");
  delay(3000);
}

void reconnect() {
  // 尝试重新连接到MQTT服务器
  while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // 创建一个随机的客户端ID
    String clientId = "ArduinoClient-";
    clientId += String(random(0xffff), HEX);
    // 连接到MQTT服务器
    if (mqttClient.connect(clientId.c_str(), deviceId, apiKey)) {
      Serial.println("Connected to MQTT broker!");
      // 订阅主题
      mqttClient.subscribe("your_topic"); // 替换为您想订阅的主题
    } else {
      Serial.print("Failed with state ");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      // 等待5秒钟再次尝试
      delay(5000);
    }
  }
}

void loop() {
  // 保持MQTT客户端连接
  if (!mqttClient.connected()) {
    reconnect();
  }
  mqttClient.loop();

  // 模拟数据,实际应用中应替换为传感器数据
  float temperature = random(20, 30);
  float humidity = random(40, 60);

  // 构建JSON数据
  String payload = "{\"temperature\":";
  payload += String(temperature);
  payload += ",\"humidity\":";
  payload += String(humidity);
  payload += "}";

  // 发布数据到OneNET云平台
  mqttClient.publish("your_topic", payload.c_str());

  // 延迟一段时间再次发送数据
  delay(10000);
}

  • 写回答

22条回答 默认 最新

  • 阿里嘎多学长 2024-05-27 23:43
    关注
    获得0.30元问题酬金

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    Arduino连接SIM900A模块实现连接到OneNET物联网平台的MQTT服务器,首先需要确保SIM900A模块能够正常工作,并能够建立GPRS连接。然后,需要使用MQTT协议与OneNET平台进行通信。你提供的代码中存在一些问题,我将帮你修改并提供一些指导。

    修改代码

    1. 创建MQTT客户端实例:你的代码中创建了一个PubSubClient实例,但是没有提供网络连接(如WiFi或以太网),因为PubSubClient需要一个网络客户端(如EthernetClientWiFiClient)来建立TCP连接。SIM900A模块不支持直接与PubSubClient通信,你需要使用HTTP或TCP/UDP协议通过SIM900A发送数据。

    2. 建立网络连接:你需要使用SIM900A的AT命令来建立网络连接。

    3. MQTT连接:由于PubSubClient不适用于SIM900A,你需要使用HTTP或TCP/UDP协议来实现MQTT连接。这通常涉及到更复杂的编程,可能需要使用第三方库或自己实现MQTT协议。

    示例代码

    由于SIM900A模块不支持直接与PubSubClient通信,以下是一个简化的示例,展示如何使用SIM900A发送HTTP请求(注意这不是MQTT协议,但可以作为发送数据到服务器的一种方式):

    #include <SoftwareSerial.h>
    
    // SIM900A配置
    SoftwareSerial sim900aSerial(2, 3); // RX, TX
    const char apn[] = "your_apn";
    const char user[] = "your_user";
    const char pass[] = "your_pass";
    
    void setup() {
      Serial.begin(9600);
      sim900aSerial.begin(19200);
    
      // 初始化SIM900A模块
      sendATCommand("AT");
      sendATCommand("AT+CGATT=1");
      sendATCommand("AT+CGDCONT=1,\"IP\",\"" apn "\"");
      sendATCommand("AT+CIPSHUTDOWN");
      sendATCommand("AT+CSTT=\"" apn "\";");
      sendATCommand("AT+CIICR");
      sendATCommand("AT+CIPMUX=1"); // 多连接模式
      delay(10000); // 等待网络连接建立
    }
    
    void loop() {
      // 构建HTTP请求
      String httpRequest = "POST /devices/" deviceId "/datapoints HTTP/1.1\r\n";
      httpRequest += "Host: api.heclouds.com\r\n";
      httpRequest += "api-key: " apiKey "\r\n";
      httpRequest += "Content-Length: 47\r\n\r\n";
      httpRequest += "{\"temperature\":25.5,\"humidity\":55}";
    
      // 发送HTTP请求
      sendATCommand("AT+CIPSTART=\"TCP\",\"" mqttServer "\",80");
      sendATCommand(httpRequest);
      delay(5000); // 等待响应
    }
    
    void sendATCommand(const char* command) {
      sim900aSerial.println(command);
      while (sim900aSerial.available() > 0) {
        char c = sim900aSerial.read();
        Serial.write(c);
      }
    }
    

    注意事项

    • 你需要替换代码中的your_apnyour_useryour_passdeviceIdapiKeymqttServer为实际的值。
    • 上述代码仅为示例,实际应用中需要根据OneNET平台的具体API文档进行调整。
    • SIM900A模块不支持MQTT协议,因此这里使用的是HTTP POST请求来发送数据。

    参考资料

    由于SIM900A模块不支持MQTT协议,你可能需要考虑使用其他支持MQTT的模块,如ESP8266或ESP32,或者寻找支持MQTT的SIM模块。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月4日
  • 创建了问题 5月27日

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵