Не удается подключиться или опубликовать sh для брокера MQTT с Arduino и SIM900 - PullRequest
0 голосов
/ 15 января 2020

Я написал простой набросок для отправки пакета подключения и публикации sh на сервер 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;
}

Это последовательный выход: enter image description here

Но на сервере cloudMQTT ничего не отображается, кроме IP-адреса моего устройства после установления соединения tcp.

1 Ответ

0 голосов
/ 16 января 2020

Так что это не работало при попытке подключиться к серверу cloudMQTT, но когда я подключился к своему серверу MQTT или тестовому серверу MQTT, это сработало. Должна быть проблема, связанная с протоколом, который использует облачный mqttServer (MQIsdp), в отличие от стандартного протокола MQTT, который используется обычным сервером MQTT. Я внес изменение в пакет подключения так, чтобы он указывал протокол MQTT и указал TCP-соединение с тестовым сервером (test.mosquitto.org), и теперь я могу успешно подключиться и подключиться sh.

Для тех, кто только начинает пытаться связать Arduino с таким модулем, как SIM900 (модуль GPRS / GSM), с сервером MQTT, я предлагаю вам gr asp полное понимание стандартных AT-команд (Чтобы установить sh a solid TCP-соединение с сервером), как скомпилировать пакеты, которые будут отправлены через модуль GPRS из Arduino, и, наконец, я предлагаю не использовать какой-либо код, который вы не написали для достижения этой цели. Узнайте, как установить sh соединение TCP с AT-командами, затем узнайте, как скомпилировать и отправить пакет подключения, скомпилировав байтовый массив и отправив его. Как только вы поймете пакеты и связь между клиентом и сервером, мир 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;
}
...