IOT测试环境(Arduino UNO + ESP8266 + MQTT)基于AT指令透传(三)

【参考资料】
【1】https://blog.csdn.net/IoT_Club/article/details/85263023
【2】https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.648.3c9b3f86rxCIIf

本文在上一篇博客的基础上接入阿里云IOT平台,仍然采用AT命令透传,不使用其SDK。

一、产品及设备添加
  1. 新增产品,获得产品的ProductKey和ProductSecret;
  2. 新增产品时可以直接选择产品模型,该产品模型将决定MQTT消息中JSON业务包的字段;
  3. 在产品品类里增加设备,获取DeviceName;
二、设备连接
  1. MQTT的域名:

产品key加所在区域的URL,端口仍然是默认MQTT的1883

PRODUCT_KEY".iot-as-mqtt.cn-shanghai.aliyuncs.com"
  1. MQTT用户名
    采用设备名&产品key
DEVICE_NAME "&" PRODUCT_KEY
  1. 连接MQTT的clientId
clientId+"|securemode=3,signmethod=hmacsha1,timestamp=132323232|"

这里clientId阿里平台建议是MAC地址;时间戳可以随便填写;加密方式采用hmacsha1

  1. MQTT的连接密码
    将上述设备名称、产品key按如下拼接后:
    clientIdtestdeviceNamearduinoTestproductKeya1NPVBYVPlMtimestamp123456789,用DeviceSecret进行hmacsha1加密
  1. 此时可以进行MQTT的连接,一旦连接成功,IOT平台会显示设备在线。
    在这里插入图片描述
三、数据上报
  1. 参考平台给出的topic列表:
    在这里插入图片描述
  1. 参考平台给出的功能定义:
    在这里插入图片描述
  1. 采用MQTT工具测试接口如下:
    在这里插入图片描述
    这里也直接可以用平台自带的调试工具调试,实际上就是一个MQTT客户端:)
    本文用的工具是MAC下的mqttlens
四、利用Ardiono+ESP测试Alink接口

源码如下,在上一篇博客代码的基础上做了修改,居然也花了将近3个小时才调通,还是靠着wireshark抓包比对16进制数据。。。。

#include <SoftwareSerial.h>
#include <ArduinoJson.h>

SoftwareSerial sofrserial(13, 12);


#define PRODUCT_KEY       "a1NPVBYVPlM"
#define DEVICE_NAME       "arduinoTest"
#define DEVICE_SECRET     "XXXXX"

#define MQTT_SERVER       PRODUCT_KEY".iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_PORT         1883
#define MQTT_USRNAME      DEVICE_NAME "&" PRODUCT_KEY

// HMACSHA1_SRC  clientIdtestdeviceNamearduinoTestproductKeya1NPVBYVPlMtimestamp123456789
// 加密秘钥为 DEVICE_SECRET

#define CLIENT_ID         "test|securemode=3,timestamp=123456789,signmethod=hmacsha1|"
#define MQTT_PASSWD       "XXXXXXXX"

#define ALINK_BODY_FORMAT         "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP  "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET      "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST    "thing.event.property.post"



void setup()
{
  delay(5000);
  pinMode(0,  INPUT_PULLUP); 
  pinMode(1,  INPUT_PULLUP); 

  Serial.begin(115200); 
  while (!Serial) {}
  Serial.println("serial ok!");
  
  sofrserial.begin(9600);
  while (!sofrserial) {}
  Serial.println("sofrserial ok!");

  
  sofrserial.listen();
  sofrserial.println("AT");
  delay(500);
  if(sofrserial.find("OK")){
    Serial.println("ready to conncet!");
    connect_wifi();

    delay(4000);
    clear_buffer();
    _test_send_mqtt_publish_msg();
  }
}
 
void loop() {
  
}

void connect_wifi(){
  sofrserial.println("AT+RST");
  delay(1000);
  sofrserial.println("AT+CWMODE=1");
  delay(500);
  sofrserial.println("\"XXXX-24G\",\"XXXXX@XX\"");
  sofrserial.listen();
  delay(3000);
  if(sofrserial.find("OK")){
      Serial.println("wifi connected!");
      sofrserial.println("AT+CIPMUX=0");
      delay(1000);
      clear_buffer();
      mqtt_connect();
  }
}

void mqtt_connect(){
    clear_buffer();

    //esp的tcp连接好像直接用域名不行,必须用ip地址
    sofrserial.println("AT+CIPSTART=\"TCP\",\"XXXX\",1883");
    //sofrserial.println("AT+CIPSTART=\"TCP\",\"192.168.1.18\",1883");
    sofrserial.listen();
    delay(3000);
    if(sofrserial.find("OK")){
        Serial.println("tcp connected!");
    }else{
        Serial.println("tcp connect failed!");
    }

    _test_send_mqtt_connect_msg();
}

void _test_send_mqtt_connect_msg(){
   u8 mqtt_message[200]={0};
   u8 packetLen;
   u8 baseIndex = 0;
   u8 client_id_length = strlen(CLIENT_ID);
   u8 username_length  = strlen(MQTT_USRNAME);
   u8 password_length  = strlen(MQTT_PASSWD);
   packetLen = 17 + client_id_length + username_length + 2 + password_length;
   mqtt_message[0] = 16;
   mqtt_message[1] = packetLen - 3;
   mqtt_message[2] = 1;
   mqtt_message[3] = 0; 
   mqtt_message[4] = 4;       // Protocol Name Length LSB    
   mqtt_message[5] = 77;      // ASCII Code for M    
   mqtt_message[6] = 81;      // ASCII Code for Q    
   mqtt_message[7] = 84;      // ASCII Code for T    
   mqtt_message[8] = 84;      // ASCII Code for T    
   mqtt_message[9] = 4;       // MQTT Protocol version = 4    
   mqtt_message[10] = 194;     // conn flags 
   mqtt_message[11] = 0;      // Keep-alive Time Length MSB    
   mqtt_message[12] = 120;    // Keep-alive Time Length LSB 

   mqtt_message[13] = (0xff00&client_id_length)>>8;// Client ID length MSB
   mqtt_message[14] = 0xff&client_id_length; 

   for(u8 i = 0; i < client_id_length; i++){
        mqtt_message[15 + i] = *((u8*)CLIENT_ID + i);    
   }

   baseIndex = 15 + client_id_length;
   
   mqtt_message[baseIndex++] = (0xff00 & username_length)>>8; //username length MSB    
   mqtt_message[baseIndex++] = 0xff & username_length;        //username length LSB 

   for(u8 i = 0; i < username_length ; i++){
      mqtt_message[baseIndex + i] = *((u8*)MQTT_USRNAME + i);    
   }

   baseIndex += username_length;
   
   mqtt_message[baseIndex++] = (0xff00&password_length)>>8;//password length MSB    
   mqtt_message[baseIndex++] = 0xff&password_length; //password length LSB 
   
   for(u8 i = 0; i < password_length ; i++){
      mqtt_message[baseIndex + i] = *((u8*)MQTT_PASSWD + i);    
   }

   
   
   send_tcp_package(mqtt_message, packetLen);
}

void _test_send_mqtt_publish_msg(){
  u8 mqtt_message[200]={0};
  u16 i,index=0;  
  u16 topic_length   = strlen(ALINK_TOPIC_PROP_POST); 

  char param[32];
  char mqtt_data[128]={0};
  
  sprintf(param, "{\"LightSwitch\":%d}", 1);
  sprintf(mqtt_data, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
  String data="";
  for(int i = 0; i < sizeof(mqtt_data); i++){
    if(mqtt_data[i] != 0){
      data += mqtt_data[i];
    }
  }

 
  u16 message_length = data.length();
  
  
  mqtt_message[index++] = 50;// 增加了QOS
  mqtt_message[index++] = 4 + topic_length + message_length;
  mqtt_message[index++] = 1;//长度大于127
  mqtt_message[index++] = (0xff00 & topic_length)>>8;
  mqtt_message[index++] = 0xff & topic_length;
  for(i = 0; i < topic_length; i++)
  {
    mqtt_message[index + i] = *((u8 *)ALINK_TOPIC_PROP_POST + i);
  }
  index += topic_length;

  mqtt_message[index++] = (0xff00&1)>>8;
  mqtt_message[index++] = 0xff&1;
  
  for(i = 0; i < message_length; i++)
  {
    mqtt_message[index + i] = mqtt_data[i];
  }

  send_tcp_package(mqtt_message, 7 + topic_length + message_length);
 
}

void send_tcp_package(u8 *data,u16 len){

   clear_buffer();
   sofrserial.listen();
   sofrserial.print("AT+CIPSEND=");
   sofrserial.println(len);
   
   delay(1000);
   if(sofrserial.find( ">" ) )
   {
      Serial.println("start to send data.....");
      Serial.println(len);
      u16 i;
      for(i=0; i<len; i++)
      {
        sofrserial.write(data[i]);
        Serial.print(data[i]);
      }
        
      sofrserial.listen();
      sofrserial.println();
      delay(500);
    }else{
      Serial.println("send  AT+CIPSEND failed");
    }

    if( sofrserial.find("OK")){
      Serial.println("send succfful!!");
    }else{
      Serial.println("send  wrong");
    }
}


void clear_buffer(){
  while(sofrserial.read()>= 0){}
  while(Serial.read()>= 0){}
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值