Interfacing STM32F4 with SIM800 for IOT based project using MQTT protocol

firmware
sim800
mqtt

#1

I am using STM32F4 discovery board using USART2 interface with SIM800 GSM module. Target is to send 500KB of data via this modem using MQTT. To start with i tried what explained in this video ttp://www.raviyp.com/embedded/226-mqtt-protocol-tutorial-using-sim900-sim800-modules-mqtt-over-tcp. i send the command via serial port checked on PC and observe that I am getting connect ok for m10,cloudmqtt,com. When I send CONNECT MQTT and PUBLISH packet using CIPSEND i get SEND OK as response but no data sent to the topic. I tried valetron topic as explained in the video.

AT
OK

AT+CIPSHUT
SHUT OK

AT+CIPMUX=0
OK

AT+CIPMODE=0
OK

AT+CGATT=1
OK

AT+CREG?
+CREG: 0,1
OK

AT+CSTT=“airtelgprs.com”,"",""
OK

AT+CIICR
OK

AT+CIFSR
100.78.111.142

AT+CIPSPRT=1
OK

AT+CIPSTART=“TCP”,“m10.cloudmqtt.com”,“17434”
OK
CONNECT OK

AT+CIPSTATUS
OK
STATE: CONNECT OK

CIPSEND

102C00064D514973647003C2003C000641424344454600086478786B676B7070000C7141555A4264615349554C783013000876616C6574726F6E68656C6C6F726176691A
SEND OK

But i dont see any message in subscribed terminal.
What could be the reason please explain.
Also it will helpful if you suggest me any MQTT client C library to start with this implementation.
Please also share XML file for MQTT packet creation.


#2

I have also created account in CloudMQTT and tried with own accout i see below logs while i connect no message is getting transfered to broker.
Below is the detail and logs from CloudMQTT.com

broker: m12.cloudmqtt.com
port : 15488
Logs:
2018-04-13 05:23:25: New connection from 106.210.238.122 on port 15488.
2018-04-13 05:24:18: Socket error on client , disconnecting.

When i try to connect via CIPSTART command i get first line of above log and when send MQTT packet i get seconf line and TCP connect automatically get closed AT module side.

What could be the possible issue.


#3

Hi ,

All details are present here.

You can download the files and copy the code. I think you can modify this Arduino code to work for STM32 easily.

Don’t for get to Share & Subscribe :slight_smile:

Regards,
Ravi


#4

Thanks for the quick response ravi. Very informative videos i have subscribed already.
Keep sharing your knowledge to new comer like us.

In my case TCP connection with broker itself is getting closed automatically without sending any packet. This is the case with cmd line interface. What could be the reason? And when i tried with my current code there also no result. I will update my code with your sample and will try once again.

But module should not closed the tcp connection right? because if this is the case then after CIPSTART and delay the TCP will be closed and no communication will happen.

Anyway i will update and try first then get back to you again.

Thanks again


#6

Is it possible to send 500KB?

From the MQTT Standard I was just reading:

1.5.3 UTF-8 encoded strings
Text fields in the Control Packets described later are encoded as UTF-8 strings. UTF-8 [RFC3629] is an
efficient encoding of Unicode [Unicode] characters that optimizes the encoding of ASCII characters in
support of text-based communications.

Each of these strings is prefixed with a two byte length field that gives the number of bytes in a UTF-8
encoded string itself, as illustrated in Figure 1.1 Structure of UTF-8 encoded strings below. Consequently
there is a limit on the size of a string that can be passed in one of these UTF-8 encoded string
components; you cannot use a string that would encode to more than 65535 bytes.

65KB Max?


#7

I found more limitations while working on a similar project.

From the SIMCOM 5300E TCPIP Application Guide:

User can use the command “AT+CIPSEND?” to query the current maximum data length available to be sent, which is determined by the network. In fact, the maximum data length is variable, depending on the actual network. The maximum data length can be up to 1460 bytes. In multi connection, the command “AT+CIPSEND?” will tell current available maximum data length for all active connections.

You may have a similar limitation,


#8

Hi Patrick thanks for pointing out the limitation. I have read that max 236 MB can be transfer using MQTT as datalength can go upto 4 byte length. Just wanted to confirm with the team.


#9

also i have tested the code after updating but i did not get any successful result.
Direct cmdline: CIPSEND response is SEND OK but no message received at broker only new sokect connect and getting closed after 70 seceond approx.
STM32 MCU getting stuck at CIPSEND and no response received. Checked with looping back RX TX of UART but only 2 characters are transfered in loopback others i am not able receive/send. Then i tried send all values in HEX but then also no MQTT message appears in broker.

I hope i have explained my problem statement.
What could be the possible issue. Please explain.


#10

Check and recheck the construction of the packet using the excel sheet. Its easy to make a mistake.


#11

Construction of packet is correct as i have verified the code in Ubuntu by creating a socket and send the constructed packet. Successfuly publised the message. But same construction is not working in SIM800A :

Below is the hyperterminal AT response:

at
OK

+CPIN: READY
at
OK

Call Ready

SMS Ready
AT+CREG?
+CREG: 0,1

OK
AT+CIPMUX=0
OK
AT+CIPRXGET=1
OK
AT+CIPMODE=0
OK
AT+CIPSRIP=0
OK
AT+CGATT?
+CGATT: 1

OK
AT+CIPSTATUS
OK

STATE: IP INITIAL
AT+CSTT=“AIRTELGPRS.COM”,"",""
OK
AT+CIICR
OK
AT+CIFSR
100.69.35.104
AT+CIPSTATUS
OK

STATE: IP STATUS

AT+CIPSTART=“TCP”,“ec2-54-214-95-94.us-west-2.compute.amazonaws.com”,“1883”
OK

CONNECT OK

AT+CIPSEND

102300064d514973647003c2003c0006414243444546000464617665000731323364656c6c1a
SEND OK

CLOSED

AT+CIPSTART=“TCP”,“ec2-54-214-95-94.us-west-2.compute.amazonaws.com”,“1883”
OK

CONNECT OK
AT+CIPSEND

102300064d514973647003c2003c0006414243444546000464617665000731323364656c6c301300047465737448657920426861677761616e211a
SEND OK

CLOSED

Above packets are for CONNECT and CONNECT+PUBLISH are HEX string constructed using XML file, Right after CIPSEND, SEND OK Received and then TCP get closed. Though we get SEND ok here but no message received at the broker end and to SUBSCRIBER terminal. Only log i see at broker end is new connection is
1524061477: New connection from 106.193.174.139 on port 1883.
1524061490: Socket error on client , disconnecting.

when i send from Ubuntu Client in the log is my clientid instead of unknown.

I doubt any of the packet from SIM800A is getting transmitted to broker. I really feel helpless here. How to debug this issue any suggestion folks.


#12

The packet should be sent in binary mode. Are you using binary or hex mode of terminal software to send it?


#13

I am using sending HEX values and I am using Teraterm Terminal software.
102300064d514973647003c2003c0006414243444546000464617665000731323364656c6c1a

Above is the connect packet with
protocol : MQIspd
user : dave
pw: 123dell

I hope i am sending it correct


#14

Hi
My SIM800 had problem it seems. I switched to our target 4G LTE modem from u-blox(LARA-R280). Now i am able to send packet to MQTT broker. But i am not able to send from code. How to send data in HEX or Binary from C code. I tried number of ways to construct the packet but no result.

int MQTTConnect(void)
{
int i= 0, j=0;
uint8_t status = 0;
uint32_t addr = 0;
uint8_t temp_str[250];
uint8_t mqtt_str[250];

memset(temp_str, 0, 250);
memset(mqtt_str, 0, 250);

//this is working fine //sendATcommand2(“AT+USOWR=0,59,“102300064d514973647003c2003c0006414243444546000464617665000731323364656c6c301300047465737448657920426861677761616e211a”\r”, “OK”, “ERROR”, 1000);

// from here i tried to construct the array exact same as above but not able to recieve packet at broker side.
temp_str[addr++] = ‘\’;
temp_str[addr++] = ‘"’;
temp_str[addr++] = 1;
temp_str[addr++] = 0;
temp_str[addr++] = 2;
temp_str[addr++] = 3;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 6;
temp_str[addr++] = 4;
temp_str[addr++] = ‘d’;
temp_str[addr++] = 5;
temp_str[addr++] = 1;
temp_str[addr++] = 4;
temp_str[addr++] = 9;
temp_str[addr++] = 7;
temp_str[addr++] = 3;
temp_str[addr++] = 6;
temp_str[addr++] = 4;
temp_str[addr++] = 7;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 3;
temp_str[addr++] = ‘c’;
temp_str[addr++] = 2;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 3;
temp_str[addr++] = ‘c’;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 6;
temp_str[addr++] = 4;
temp_str[addr++] = 1;
temp_str[addr++] = 4;
temp_str[addr++] = 2;
temp_str[addr++] = 4;
temp_str[addr++] = 3;
temp_str[addr++] = 4;
temp_str[addr++] = 4;
temp_str[addr++] = 4;
temp_str[addr++] = 5;
temp_str[addr++] = 4;
temp_str[addr++] = 6;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 4;
temp_str[addr++] = 6;
temp_str[addr++] = 4;
temp_str[addr++] = 6;
temp_str[addr++] = 1;
temp_str[addr++] = 7;
temp_str[addr++] = 6;
temp_str[addr++] = 6;
temp_str[addr++] = 5;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 7;
temp_str[addr++] = 3;
temp_str[addr++] = 1;
temp_str[addr++] = 3;
temp_str[addr++] = 2;
temp_str[addr++] = 3;
temp_str[addr++] = 3;
temp_str[addr++] = 6;
temp_str[addr++] = 4;
temp_str[addr++] = 6;
temp_str[addr++] = 5;
temp_str[addr++] = 6;
temp_str[addr++] = ‘c’;
temp_str[addr++] = 6;
temp_str[addr++] = ‘c’;
temp_str[addr++] = 3;
temp_str[addr++] = 0;
temp_str[addr++] = 1;
temp_str[addr++] = 3;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 0;
temp_str[addr++] = 4;
temp_str[addr++] = 7;
temp_str[addr++] = 4;
temp_str[addr++] = 6;
temp_str[addr++] = 5;
temp_str[addr++] = 7;
temp_str[addr++] = 3;
temp_str[addr++] = 7;
temp_str[addr++] = 4;
temp_str[addr++] = 4;
temp_str[addr++] = 8;
temp_str[addr++] = 6;
temp_str[addr++] = 5;
temp_str[addr++] = 7;
temp_str[addr++] = 9;
temp_str[addr++] = 2;
temp_str[addr++] = 0;
temp_str[addr++] = 4;
temp_str[addr++] = 2;
temp_str[addr++] = 6;
temp_str[addr++] = 8;
temp_str[addr++] = 6;
temp_str[addr++] = 1;
temp_str[addr++] = 6;
temp_str[addr++] = 7;
temp_str[addr++] = 7;
temp_str[addr++] = 7;
temp_str[addr++] = 6;
temp_str[addr++] = 1;
temp_str[addr++] = 6;
temp_str[addr++] = 1;
temp_str[addr++] = 6;
temp_str[addr++] = ‘e’;
temp_str[addr++] = 2;
temp_str[addr++] = 1;
temp_str[addr++] = 1;
temp_str[addr++] = ‘a’;
temp_str[addr++] = ‘\’;
temp_str[addr++] = ‘"’;
temp_str[addr++] = ‘\’;
temp_str[addr] = ‘r’;

// temp_str[addr++] = 0x10;
// temp_str[addr++] = 0x23;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x06;
// temp_str[addr++] = 0x4d;
// temp_str[addr++] = 0x51;
// temp_str[addr++] = 0x49;
// temp_str[addr++] = 0x73;
// temp_str[addr++] = 0x64;
// temp_str[addr++] = 0x70;
// temp_str[addr++] = 0x03;
// temp_str[addr++] = 0xc2;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x3c;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x06;
// temp_str[addr++] = 0x41;
// temp_str[addr++] = 0x42;
// temp_str[addr++] = 0x43;
// temp_str[addr++] = 0x44;
// temp_str[addr++] = 0x45;
// temp_str[addr++] = 0x46;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x04;
// temp_str[addr++] = 0x64;
// temp_str[addr++] = 0x61;
// temp_str[addr++] = 0x76;
// temp_str[addr++] = 0x65;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x07;
// temp_str[addr++] = 0x31;
// temp_str[addr++] = 0x32;
// temp_str[addr++] = 0x33;
// temp_str[addr++] = 0x64;
// temp_str[addr++] = 0x65;
// temp_str[addr++] = 0x6c;
// temp_str[addr++] = 0x6c;
// temp_str[addr++] = 0x30;
// temp_str[addr++] = 0x13;
// temp_str[addr++] = 0x00;
// temp_str[addr++] = 0x04;
// temp_str[addr++] = 0x74;
// temp_str[addr++] = 0x65;
// temp_str[addr++] = 0x73;
// temp_str[addr++] = 0x74;
// temp_str[addr++] = 0x48;
// temp_str[addr++] = 0x65;
// temp_str[addr++] = 0x79;
// temp_str[addr++] = 0x20;
// temp_str[addr++] = 0x42;
// temp_str[addr++] = 0x68;
// temp_str[addr++] = 0x61;
// temp_str[addr++] = 0x67;
// temp_str[addr++] = 0x77;
// temp_str[addr++] = 0x61;
// temp_str[addr++] = 0x61;
// temp_str[addr++] = 0x6e;
// temp_str[addr++] = 0x21;
// temp_str[addr] = 0x1a;

HAL_Delay(50);
printf(“addr–>%d\n”, addr);
sprintf((char*)mqtt_str, “AT+USOWR=0,%d,”, (addr-5)/2);

for( i = 15, j = 0; j <= addr; i++, j++)
mqtt_str[i] = temp_str[j];

for( j = 0; j < i; j++)
{
printf(“mqtt_str[%d] --> %x\n”, j, mqtt_str[j]);
//USART_TxChar(mqtt_str[j]);
}

printf("addr-->%d\n", j);
if (sendATcommand2(mqtt_str, j, "OK", "ERROR", 5000)) 
{
 printf("PACKET SEND SUCCESS");
 status = 1;

}
else
status = 0;

return status;

}

above is the function where connect and publish packet are sent together.

May be i am not able to construct HEX format packet. Please suggest!!


#15

You should use 0x for hex values. You are sending decimal and ascii values. The second part where you commented seems to be correct. Did you try using the second part?


#16

Yes i tried with second part also but no success. I have modified the code and its working but only for connect packet is getting sent after that i am sending publish but no msg appears in broker. Though sending connect+publish packet i get msg in broker. In short single packet is getting sent. I have to send 500kb + data in future but i am stuuck here. I changed modem mode from binary to HEX as non printing ASCII characters were not getting sent in earlier mode.

modified code:
void writeChar(unsigned char** pptr, char c)
{
**pptr = c;
(*pptr)++;
}

void writeInt(unsigned char** pptr, int anInt)
{
**pptr = (unsigned char)(anInt / 256);
(*pptr)++;
**pptr = (unsigned char)(anInt % 256);
(*pptr)++;
}

void writeCString(unsigned char** pptr, const char* string)
{
int len = strlen(string);
writeInt(pptr, len);
memcpy(*pptr, string, len);
*pptr += len;
}

void binary_to_hex(const char *input_buff, unsigned int length, char *output_buff)
{
char hex[] = “0123456789ABCDEF”;

*output_buff = '\0';

for (; length > 0; --length)
{
    unsigned char byte = *input_buff++;

    *output_buff++ = hex[(byte >> 4) & 0x0F];
    *output_buff++ = hex[byte & 0x0F];
}

*output_buff++ = '\0';

}
int MQTTConnect(void)
{
uint8_t status = 0;
uint8_t temp_str[250];
uint8_t *mqtt_str, *buff;

memset(temp_str, 0, 250);
mqtt_str = malloc(250);
buff = mqtt_str;

writeChar(&buff, 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 there are more data to encode, set the top bit of this byte
if ( X > 0 ) { encodedByte |= 128; }

	writeChar(&buff, encodedByte);
}	while ( X > 0 );

writeCString(&buff, MQTTProtocolName);

writeChar(&buff, MQTTLVL);
writeChar(&buff, MQTTFlags);
writeInt(&buff, MQTTKeepAlive);

writeCString(&buff, MQTTClientID);

writeCString(&buff, MQTTUsername);

writeCString(&buff, MQTTPassword);

writeChar(&buff, 0x1A);

bin_to_hex(mqtt_str, encodedByte+3, temp_str);

sprintf(mqtt_str, "AT+USOWR=0,38,\"%s\"\r",temp_str);

status = sendATcommand2(mqtt_str, strlen(mqtt_str), "OK", "ERROR", 5000);

if(status == 1)
{
printf(“PACKET SEND SUCCESS”);
status = 1;
}
else if(status == 2)
{
printf(“PACKET SEND ERROR”);
status = 0;
}
else
{
printf(“PACKET SEND TIMEOUT”);
status = 0;
}

free(mqtt_str);

return status;

}

MODEM i am using is ublox LARA R280 4G LTE. I may be missing any configuration to make it work. I would really appreciate if you can look into this modem configuration once.


#17

Can you tell me if I want to send “valetron” to my websocket, what should I write as AT+CIPSEND … command?

Thanks!


#18

Hi,
I have shown this in video, how you can form the packet.
Follow the TCP/IP AT command video/MQTT protocol tutorial video.



#19

HI;

I tried exactly the same steps using my username and pasword and host name. but when I try to send publish packet i get Connection refused by remote host

And I was using HERCULES

I don’t know why!


#20

Ok, I succeded but now when I am trying to send via AT+CIPSEND command it says to me:
SEND OK

CLOSED
but nothing appears on websocket UI. I tried sending first connect package and then publish an also I tried sending connect and publish together but stil nothing.

I dont know what to do.

I tried with hex with 0x1A hex format, Binary.

Please help me somehow. I am using SIM800l.

Thanks!


#21

Which MQTT broker are you using exactly. Please create separate thread for your question to keep others discussion to their topic.

Regards,
Ravi