【问题标题】:Can't connect or publish to MQTT broker with Arduino and SIM900无法使用 Arduino 和 SIM900 连接或发布到 MQTT 代理
【发布时间】:2020-01-15 12:54:19
【问题描述】:

我写了一个简单的草图来发送一个连接和发布数据包到 cloudMQTT 服务器。我没有从 SIM900 返回任何错误,但 cloudMQTT 仪表板上没有任何显示。

#include <SoftwareSerial.h>
SoftwareSerial SoftSerial( 9, 10 );

// These varaibles are passed to functionality that generates the connect and publish packets. This code was taken from a sketch written by Ravi Pujar
unsigned int Counter = 0;
unsigned long datalength, CheckSum, RLength;
unsigned short topiclength;
unsigned char topic[30];
char str[250];
unsigned char encodedByte;
int X;
unsigned short MQTTProtocolNameLength;
unsigned short MQTTClientIDLength;
unsigned short MQTTUsernameLength;
unsigned short MQTTPasswordLength;
const char MQTTHost[30] = "hairdresser.cloudmqtt.com";
const char MQTTPort[10] = "18958";
const char MQTTClientID[20] = "ABCDEF";
const char MQTTTopic[30] = "valetron";
const char MQTTProtocolName[10] = "MQIsdp";
const char MQTTLVL = 0x03;
const char MQTTFlags = 0xC2;
const unsigned int MQTTKeepAlive = 60;
const char MQTTUsername[30] = "uroxeeil";
const char MQTTPassword[35] = "ifG3xIxaf5gT";
const char MQTTQOS = 0x00;
const char MQTTPacketID = 0x0001;

unsigned char buffer[ 64 ];
int counter = 0;

void setup() 
{
    // Set the babud rate of both the software serial and hardware serial
    Serial.begin( 19200 );
    SoftSerial.begin( 19200 );

    delay(2000);

    // This section of code sends AT commands to initialize the SIM900
    //-------------- AT INITIALIZATION - This is working fine--------------//
    SoftSerial.write( "\r\nAT\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CIPSHUT\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CIPMUX=0\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CGATT=1\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CSTT=\"myMTN\", \"\", \"\"\r\n" );    

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CIICR\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CIFSR\r\n" );

    delay(3000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);
//-----
    SoftSerial.write( "\r\nAT+CIPSTART=\"TCP\", \"hairdresser.cloudmqtt.com\", \"18958\"\r\n" );

    delay(10000);

    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;

delay(2000);

    //-------------- END OF AT INITIALIZATION --------------//
    //This is where the issue lies

    // Send the connect packet. This code was written by Ravi Pujar

    SoftSerial.write( "\r\nAT+CIPSEND\r\n" );

    delay(3000);
    SoftSerial.write(0x10);
    MQTTProtocolNameLength = strlen(MQTTProtocolName);
    MQTTClientIDLength = strlen(MQTTClientID);
    MQTTUsernameLength = strlen(MQTTUsername);
    MQTTPasswordLength = strlen(MQTTPassword);
    datalength = MQTTProtocolNameLength + 2 + 4 + MQTTClientIDLength + 2 + MQTTUsernameLength + 2 + MQTTPasswordLength + 2;
    X = datalength;
    do {
    encodedByte = X % 128;
    X = X / 128;
    if (X > 0) {
      encodedByte |= 128;
    }
    SoftSerial.write(encodedByte);
    }
    while (X > 0);
    SoftSerial.write(MQTTProtocolNameLength >> 8);
    SoftSerial.write(MQTTProtocolNameLength & 0xFF);
    SoftSerial.print(MQTTProtocolName);
    SoftSerial.write(MQTTLVL); // LVL
    SoftSerial.write(MQTTFlags); // Flags
    SoftSerial.write(MQTTKeepAlive >> 8);
    SoftSerial.write(MQTTKeepAlive & 0xFF);
    SoftSerial.write(MQTTClientIDLength >> 8);
    SoftSerial.write(MQTTClientIDLength & 0xFF);
    SoftSerial.print(MQTTClientID);
    SoftSerial.write(MQTTUsernameLength >> 8);
    SoftSerial.write(MQTTUsernameLength & 0xFF);
    SoftSerial.print(MQTTUsername);
    SoftSerial.write(MQTTPasswordLength >> 8);
    SoftSerial.write(MQTTPasswordLength & 0xFF);
    SoftSerial.print(MQTTPassword);
    SoftSerial.write(0x1A);  

    delay( 2000 );

    // Send the publish packet. This code was written by Ravi Pujar

    SoftSerial.print("\r\nAT+CIPSEND\r\n");
    delay(3000);
    memset(str, 0, 250);
    topiclength = sprintf((char * ) topic, MQTTTopic);
    datalength = sprintf((char * ) str, "%s%u", topic, Counter);
    delay(1000);
    Serial.write(0x30);
    X = datalength + 2;
    do {
    encodedByte = X % 128;
    X = X / 128;
    if (X > 0) {
    encodedByte |= 128;
    }
    SoftSerial.write(encodedByte);
    }
    while (X > 0);
    SoftSerial.write(topiclength >> 8);
    SoftSerial.write(topiclength & 0xFF);
    SoftSerial.print(str);
    SoftSerial.write(0x1A);    
}

void loop() 
{
    // Display any response that has been sent after the first CIPSEND 
    while ( SoftSerial.available() > 0 )
    {
        buffer[ counter++ ] = SoftSerial.read();
        if( counter == 64 ) break;        
    }

    Serial.write( buffer, counter );

    for( int i = 0; i < counter; i++ )
    {
        buffer[ i ] = NULL;
    }
    counter = 0;
}

这是串行输出:

但是建立tcp连接后,除了我设备的IP之外,cloudMQTT服务器上什么都没有显示。

【问题讨论】:

    标签: c++ tcp arduino serial-communication gprs


    【解决方案1】:

    所以尝试连接到 cloudMQTT 服务器时它不起作用,但是当我连接到我的 MQTT 服务器或测试 MQTT 服务器时,它起作用了。与普通 MQTT 服务器使用的标准 MQTT 协议相反,处理云 mqttServer 使用的协议 (MQIsdp) 肯定存在问题。我对连接数据包进行了更改,以便它指定 MQTT 协议并将 TCP 连接指向测试服务器 (test.mosquitto.org),我现在可以成功连接和发布。

    对于刚开始尝试将 Arduino 与 SIM900(GPRS/GSM 模块)等模块连接到 MQTT 服务器的任何人,我建议您全面了解标准 AT 命令(建立可靠的 TCP连接到服务器),如何编译将通过 Arduino 的 GPRS 模块发送的数据包,最后我建议不要使用任何你没有编写的代码来实现这一点。学习如何使用AT命令建立TCP连接,然后通过自己编译字节数组并发送来学习如何编译和发送连接数据包。一旦你了解了数据包以及客户端和服务器之间的通信,MQTT 世界就是你的牡蛎。

    您可以将此代码用作指导,但请尝试尽可能多地编写您自己的代码:

    #include <SoftwareSerial.h>
    SoftwareSerial SoftSerial( 9, 10 );
    
    // Go Look up the structure of MQTT packets and from there you will learn how to compile these
    byte connectPacket[ 19 ] = 
    { 
       0x10, 0x11, 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54, 0x04, 0x02, 0x00, 0x3C, 0x00, 0x05, 0x54, 0x32, 0x54, 0x49, 0x44
    };
    
    byte publishPacket[ 26 ] = 
    {
      0x30, 0x18, 0x00, 0x0E, 0x54, 0x32, 0x54, 0x5F, 0x54, 0x6F, 0x70, 0x69, 0x63, 0x5F, 0x44, 0x65, 0x6D, 0x6F, 0x54, 0x65, 0x6D, 0x70, 0x3A, 0x20, 0x33, 0x30 
    };
    
    unsigned char buffer[ 64 ];
    int counter = 0;
    
    // Simple function to send an AT command and see its response
    void sendAtCommandWithResponse( char message[] )
    {
       SoftSerial.write( message );
    
       delay(3000);
    
       while ( SoftSerial.available() > 0 )
       {
           buffer[ counter++ ] = SoftSerial.read();
           if( counter == 64 ) break;        
       }
    
       Serial.write( buffer, counter );
    
       for( int i = 0; i < counter; i++ )
       {
           buffer[ i ] = NULL;
       }
       counter = 0;
    }
    
    void setup() 
    {
       Serial.begin( 19200 );
       SoftSerial.begin( 19200 );
    
       delay(10000);
    
       // -- Configure the SIM900 and establish the TCP connection to the server
    
       sendAtCommandWithResponse( "\r\nAT\r\n" );
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CIPSHUT\r\n" );
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CIPMUX=0\r\n" );
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CGATT=1\r\n" );    
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CSTT=\"myMTN\", \"\", \"\"\r\n" );    
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CIICR\r\n" );
    
       delay(2000);
       //-----
    
       sendAtCommandWithResponse( "\r\nAT+CIFSR\r\n" );
    
       delay(2000);
       //-----
    
       SoftSerial.write( "\r\nAT+CIPSTART=\"TCP\", \"test.mosquitto.org\", \"1883\"\r\n" );    
    
       delay(10000);
       //-----
    
       while ( SoftSerial.available() > 0 )
       {
           buffer[ counter++ ] = SoftSerial.read();
           if( counter == 64 ) break;        
       }
    
       Serial.write( buffer, counter );
    
       for( int i = 0; i < counter; i++ )
       {
           buffer[ i ] = NULL;
       }
       counter = 0;
    
       delay(2000);
       //-----
    
       // -- Send the connect packet 
       sendAtCommandWithResponse( "\r\nAT+CIPSEND\r\n" );
    
       delay(3000);
    
       SoftSerial.write( connectPacket, sizeof( connectPacket ) );
       // This tells the SIM900 to send the packet
       SoftSerial.write(0x1A); 
    
       delay(3000);
    
       // -- Send the publish packet
       sendAtCommandWithResponse( "\r\nAT+CIPSEND\r\n" );
    
       delay(3000);
    
       SoftSerial.write( publishPacket, sizeof( publishPacket ) );     
       // This tells the SIM900 to send the packet
       SoftSerial.write(0x1A);  
    }
    
    void loop() 
    {
       while ( SoftSerial.available() > 0 )
       {
           buffer[ counter++ ] = SoftSerial.read();
           if( counter == 64 ) break;        
       }
    
       Serial.write( buffer, counter );
    
       for( int i = 0; i < counter; i++ )
       {
           buffer[ i ] = NULL;
       }
       counter = 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-14
      • 1970-01-01
      • 2022-06-19
      • 1970-01-01
      • 2021-12-27
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      相关资源
      最近更新 更多