Closed solankigithub closed 4 years ago
You have to replace occurrence of "SerialEvent" with "SerialEvent1". I think this will solve your problem.
Thanks Nithin, I changed the occurrence of serialEvent() to serialEvent1(). It's still not working and giving the below response on the Serial port.
AT
OK
+++AT
ATE1
OK
OK
AT+CREG?
+CREG: 0,1
OK
AT+CIPMUX=0
AT+CIPMODE=1
OK
OK
AT+CGATT?
+CGATT: 0
OK
Call Ready
AT+CGATT=1
OK
AT+CIPSTATUS
OK
STATE: IP INITIAL
SMS Ready
AT+CSTT="AIRTELGPRS.COM"
OK
AT+CIPSTATUS
OK
STATE: IP START
AT+CIICR
OK
AT+CIPSTATUS
OK
STATE: IP GPRSACT
AT+CIFSR
106.218.239.147
AT+CIPSTATUS
OK
STATE: IP STATUS
AT+CIPSTART="TCP","broker.mqttdashboard.com","1883"
OK
AT+CIPSTATUS
OK
STATE: TCP CONNECTING
CONNECT
MQTT.TCP_Flag = True
2
2
Connect Acknowledgment
0
0
PING Response
0
0
PING Response
This is my arduino main program
`
#include "GSM_MQTT.h"
#include <SoftwareSerial.h>
String MQTT_HOST = "broker.mqttdashboard.com";
/*
MQTT host address
*/
String MQTT_PORT = "1883";
/*
MQTT port
*/
SoftwareSerial mySerial(10, 11); // RX, TX
/*
Software Serial through which mqtt events log is printed at 9600 baud rate
*/
void GSM_MQTT::AutoConnect(void)
{
/*
Use this function if you want to use autoconnect(and auto reconnect) facility
This function is called whenever TCP connection is established (or re-established).
put your connect codes here.
*/
connect("clientId-i8ZSXDfphz", 0, 0, "", "", 1, 0, 0, 0, "", "");
/* void connect(char *ClientIdentifier, char UserNameFlag, char PasswordFlag, char *UserName, char *Password, char CleanSession, char WillFlag, char WillQoS, char WillRetain, char *WillTopic, char *WillMessage);
ClientIdentifier :Is a string that uniquely identifies the client to the server.
:It must be unique across all clients connecting to a single server.(So it will be better for you to change that).
:It's length must be greater than 0 and less than 24
:Example "qwerty"
UserNameFlag :Indicates whether UserName is present
:Possible values (0,1)
:Default value 0 (Disabled)
PasswordFlag :Valid only when UserNameFlag is 1, otherwise its value is disregarded.
:Indicates whether Password is present
:Possible values (0,1)
:Default value 0 (Disabled)
UserName :Mandatory when UserNameFlag is 1, otherwise its value is disregarded.
:The UserName corresponding to the user who is connecting, which can be used for authentication.
Password :alid only when UserNameFlag and PasswordFlag are 1 , otherwise its value is disregarded.
:The password corresponding to the user who is connecting, which can be used for authentication.
CleanSession :If not set (0), then the server must store the subscriptions of the client after it disconnects.
:If set (1), then the server must discard any previously maintained information about the client and treat the connection as "clean".
:Possible values (0,1)
:Default value 1
WillFlag :This flag determines whether a WillMessage published on behalf of the client when client is disconnected involuntarily.
:If the WillFlag is set, the WillQoS, WillRetain, WillTopic, WilMessage fields are valid.
:Possible values (0,1)
:Default value 0 (Disables will Message)
WillQoS :Valid only when WillFlag is 1, otherwise its value is disregarded.
:Determines the QoS level of WillMessage
:Possible values (0,1,2)
:Default value 0 (QoS 0)
WillRetain :Valid only when WillFlag is 1, otherwise its value is disregarded.
:Determines whether the server should retain the Will message.
:Possible values (0,1)
:Default value 0
WillTopic :Mandatory when WillFlag is 1, otherwise its value is disregarded.
:The Will Message will published to this topic (WillTopic) in case of involuntary client disconnection.
WillMessage :Mandatory when WillFlag is 1, otherwise its value is disregarded.
:This message (WillMessage) will published to WillTopic in case of involuntary client disconnection.
*/
}
void GSM_MQTT::OnConnect(void)
{
/*
This function is called when mqqt connection is established.
put your subscription publish codes here.
*/
subscribe(0, _generateMessageID(), "sandeepsolanki/s", 2);
/* void subscribe(char DUP, unsigned int MessageID, char *SubTopic, char SubQoS);
DUP :This flag is set when the client or server attempts to re-deliver a SUBSCRIBE message
:This applies to messages where the value of QoS is greater than zero (0)
:Possible values (0,1)
:Default value 0
Message ID:The Message Identifier (Message ID) field
:Used only in messages where the QoS levels greater than 0 (SUBSCRIBE message is at QoS =1)
SubTopic :Topic names to which subscription is needed
SubQoS :QoS level at which the client wants to receive messages
:Possible values (0,1,2)
:Default value 0
*/
publish(0, 0, 0, _generateMessageID(), "sandeepsolanki/s", "Hello MQTT Broker, How are you?");
/* void publish(char DUP, char Qos, char RETAIN, unsigned int MessageID, char *Topic, char *Message);
DUP :This flag is set when the client or server attempts to re-deliver a PUBLISH message
:This applies to messages where the value of QoS is greater than zero (0)
:Possible values (0,1)
:Default value 0
QoS :Quality of Service
:This flag indicates the level of assurance for delivery of a PUBLISH message
:Possible values (0,1,2)
:Default value 0
RETAIN :if the Retain flag is set (1), the server should hold on to the message after it has been delivered to the current subscribers.
:When a new subscription is established on a topic, the last retained message on that topic is sent to the subscriber
:Possible values (0,1)
:Default value 0
Message ID:The Message Identifier (Message ID) field
:Used only in messages where the QoS levels greater than 0
Topic :Publishing topic
Message :Publishing Message
*/
}
void GSM_MQTT::OnMessage(char *Topic, int TopicLength, char *Message, int MessageLength)
{
/*
This function is called whenever a message received from subscribed topics
put your subscription publish codes here.
*/
/*
Topic :Name of the topic from which message is coming
TopicLength :Number of characters in topic name
Message :The containing array
MessageLength:Number of characters in message
*/
Serial.println(TopicLength);
Serial.println(Topic);
Serial.println(MessageLength);
Serial.println(Message);
}
GSM_MQTT MQTT(20);
/*
20 is the keepalive duration in seconds
*/
void setup()
{
MQTT.begin();
/*
You can write your code here
*/
}
void loop()
{
/*
You can write your code here
*/
if (MQTT.available())
{
Serial.println("MQTT AVAILABLE");
/*
if you want to do something when mqtt connection is live.
You can write your code here
*/
}
MQTT.processing();
}
`
This is my GSM_MQTT.cpp
/*
MQTT.h - Library for GSM MQTT Client.
Created by Nithin K. Kurian, Dhanish Vijayan, Elementz Engineers Guild Pvt. Ltd, July 2, 2016.
Released into the public domain.
*/
#include "GSM_MQTT.h"
#include "Arduino.h"
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
extern uint8_t GSM_Response;
extern SoftwareSerial mySerial;
extern String MQTT_HOST;
extern String MQTT_PORT;
extern GSM_MQTT MQTT;
uint8_t GSM_Response = 0;
unsigned long previousMillis = 0;
//char inputString[UART_BUFFER_LENGTH]; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void serialEvent1();
GSM_MQTT::GSM_MQTT(unsigned long KeepAlive)
{
_KeepAliveTimeOut = KeepAlive;
}
void GSM_MQTT::begin(void)
{
Serial.begin(2400);
Serial1.begin(2400);
Serial1.write("AT\r\n");
delay(1000);
_tcpInit();
}
char GSM_MQTT::_sendAT(char *command, unsigned long waitms)
{
unsigned long PrevMillis = millis();
strcpy(reply, "none");
GSM_Response = 0;
Serial1.write(command);
unsigned long currentMillis = millis();
// Serial.println(PrevMillis);
// Serial.println(currentMillis);
while ( (GSM_Response == 0) && ((currentMillis - PrevMillis) < waitms) )
{
// delay(1);
serialEvent1();
currentMillis = millis();
}
return GSM_Response;
}
char GSM_MQTT::sendATreply(char *command, char *replystr, unsigned long waitms)
{
strcpy(reply, replystr);
unsigned long PrevMillis = millis();
GSM_ReplyFlag = 0;
Serial1.write(command);
unsigned long currentMillis = millis();
// Serial.println(PrevMillis);
// Serial.println(currentMillis);
while ( (GSM_ReplyFlag == 0) && ((currentMillis - PrevMillis) < waitms) )
{
// delay(1);
serialEvent1();
currentMillis = millis();
}
return GSM_ReplyFlag;
}
void GSM_MQTT::_tcpInit(void)
{
switch (modemStatus)
{
case 0:
{
delay(1000);
Serial1.print("+++");
delay(500);
if (_sendAT("AT\r\n", 5000) == 1)
{
modemStatus = 1;
}
else
{
modemStatus = 0;
break;
}
}
case 1:
{
if (_sendAT("ATE1\r\n", 2000) == 1)
{
modemStatus = 2;
}
else
{
modemStatus = 1;
break;
}
}
case 2:
{
if (sendATreply("AT+CREG?\r\n", "0,1", 5000) == 1)
{
_sendAT("AT+CIPMUX=0\r\n", 2000);
_sendAT("AT+CIPMODE=1\r\n", 2000);
if (sendATreply("AT+CGATT?\r\n", ": 1", 4000) != 1)
{
_sendAT("AT+CGATT=1\r\n", 2000);
}
modemStatus = 3;
_tcpStatus = 2;
}
else
{
modemStatus = 2;
break;
}
}
case 3:
{
if (GSM_ReplyFlag != 7)
{
_tcpStatus = sendATreply("AT+CIPSTATUS\r\n", "STATE", 4000);
if (_tcpStatusPrev == _tcpStatus)
{
tcpATerrorcount++;
if (tcpATerrorcount >= 10)
{
tcpATerrorcount = 0;
_tcpStatus = 7;
}
}
else
{
_tcpStatusPrev = _tcpStatus;
tcpATerrorcount = 0;
}
}
_tcpStatusPrev = _tcpStatus;
Serial.print(_tcpStatus);
switch (_tcpStatus)
{
case 2:
{
_sendAT("AT+CSTT=\"AIRTELGPRS.COM\"\r\n", 5000);
break;
}
case 3:
{
_sendAT("AT+CIICR\r\n", 5000) ;
break;
}
case 4:
{
sendATreply("AT+CIFSR\r\n", ".", 4000) ;
break;
}
case 5:
{
Serial1.print("AT+CIPSTART=\"TCP\",\"");
Serial1.print(MQTT_HOST);
Serial1.print("\",\"");
Serial1.print(MQTT_PORT);
if (_sendAT("\"\r\n", 5000) == 1)
{
unsigned long PrevMillis = millis();
unsigned long currentMillis = millis();
while ( (GSM_Response != 4) && ((currentMillis - PrevMillis) < 20000) )
{
// delay(1);
serialEvent1();
currentMillis = millis();
}
}
break;
}
case 6:
{
unsigned long PrevMillis = millis();
unsigned long currentMillis = millis();
while ( (GSM_Response != 4) && ((currentMillis - PrevMillis) < 20000) )
{
// delay(1);
serialEvent1();
currentMillis = millis();
}
break;
}
case 7:
{
sendATreply("AT+CIPSHUT\r\n", "OK", 4000) ;
modemStatus = 0;
_tcpStatus = 2;
break;
}
}
}
}
}
void GSM_MQTT::_ping(void)
{
if (pingFlag == true)
{
unsigned long currentMillis = millis();
if ((currentMillis - _PingPrevMillis ) >= _KeepAliveTimeOut * 1000)
{
// save the last time you blinked the LED
_PingPrevMillis = currentMillis;
Serial1.print(char(PINGREQ * 16));
_sendLength(0);
}
}
}
void GSM_MQTT::_sendUTFString(char *string)
{
int localLength = strlen(string);
Serial1.print(char(localLength / 256));
Serial1.print(char(localLength % 256));
Serial1.print(string);
}
void GSM_MQTT::_sendLength(int len)
{
bool length_flag = false;
while (length_flag == false)
{
if ((len / 128) > 0)
{
Serial1.print(char(len % 128 + 128));
len /= 128;
}
else
{
length_flag = true;
Serial1.print(char(len));
}
}
}
void GSM_MQTT::connect(char *ClientIdentifier, char UserNameFlag, char PasswordFlag, char *UserName, char *Password, char CleanSession, char WillFlag, char WillQoS, char WillRetain, char *WillTopic, char *WillMessage)
{
ConnectionAcknowledgement = NO_ACKNOWLEDGEMENT ;
Serial1.print(char(CONNECT * 16 ));
char ProtocolName[7] = "MQIsdp";
int localLength = (2 + strlen(ProtocolName)) + 1 + 3 + (2 + strlen(ClientIdentifier));
if (WillFlag != 0)
{
localLength = localLength + 2 + strlen(WillTopic) + 2 + strlen(WillMessage);
}
if (UserNameFlag != 0)
{
localLength = localLength + 2 + strlen(UserName);
if (PasswordFlag != 0)
{
localLength = localLength + 2 + strlen(Password);
}
}
_sendLength(localLength);
_sendUTFString(ProtocolName);
Serial1.print(char(_ProtocolVersion));
Serial1.print(char(UserNameFlag * User_Name_Flag_Mask + PasswordFlag * Password_Flag_Mask + WillRetain * Will_Retain_Mask + WillQoS * Will_QoS_Scale + WillFlag * Will_Flag_Mask + CleanSession * Clean_Session_Mask));
Serial1.print(char(_KeepAliveTimeOut / 256));
Serial1.print(char(_KeepAliveTimeOut % 256));
_sendUTFString(ClientIdentifier);
if (WillFlag != 0)
{
_sendUTFString(WillTopic);
_sendUTFString(WillMessage);
}
if (UserNameFlag != 0)
{
_sendUTFString(UserName);
if (PasswordFlag != 0)
{
_sendUTFString(Password);
}
}
}
void GSM_MQTT::publish(char DUP, char Qos, char RETAIN, unsigned int MessageID, char *Topic, char *Message)
{
Serial1.print(char(PUBLISH * 16 + DUP * DUP_Mask + Qos * QoS_Scale + RETAIN));
int localLength = (2 + strlen(Topic));
if (Qos > 0)
{
localLength += 2;
}
localLength += strlen(Message);
_sendLength(localLength);
_sendUTFString(Topic);
if (Qos > 0)
{
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
}
Serial1.print(Message);
}
void GSM_MQTT::publishACK(unsigned int MessageID)
{
Serial1.print(char(PUBACK * 16));
_sendLength(2);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
}
void GSM_MQTT::publishREC(unsigned int MessageID)
{
Serial1.print(char(PUBREC * 16));
_sendLength(2);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
}
void GSM_MQTT::publishREL(char DUP, unsigned int MessageID)
{
Serial1.print(char(PUBREL * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
_sendLength(2);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
}
void GSM_MQTT::publishCOMP(unsigned int MessageID)
{
Serial1.print(char(PUBCOMP * 16));
_sendLength(2);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
}
void GSM_MQTT::subscribe(char DUP, unsigned int MessageID, char *SubTopic, char SubQoS)
{
Serial1.print(char(SUBSCRIBE * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
int localLength = 2 + (2 + strlen(SubTopic)) + 1;
_sendLength(localLength);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
_sendUTFString(SubTopic);
Serial1.print(SubQoS);
}
void GSM_MQTT::unsubscribe(char DUP, unsigned int MessageID, char *SubTopic)
{
Serial1.print(char(UNSUBSCRIBE * 16 + DUP * DUP_Mask + 1 * QoS_Scale));
int localLength = (2 + strlen(SubTopic)) + 2;
_sendLength(localLength);
Serial1.print(char(MessageID / 256));
Serial1.print(char(MessageID % 256));
_sendUTFString(SubTopic);
}
void GSM_MQTT::disconnect(void)
{
Serial1.print(char(DISCONNECT * 16));
_sendLength(0);
pingFlag = false;
}
//Messages
const char CONNECTMessage[] PROGMEM = {"Client request to connect to Server\r\n"};
const char CONNACKMessage[] PROGMEM = {"Connect Acknowledgment\r\n"};
const char PUBLISHMessage[] PROGMEM = {"Publish message\r\n"};
const char PUBACKMessage[] PROGMEM = {"Publish Acknowledgment\r\n"};
const char PUBRECMessage[] PROGMEM = {"Publish Received (assured delivery part 1)\r\n"};
const char PUBRELMessage[] PROGMEM = {"Publish Release (assured delivery part 2)\r\n"};
const char PUBCOMPMessage[] PROGMEM = {"Publish Complete (assured delivery part 3)\r\n"};
const char SUBSCRIBEMessage[] PROGMEM = {"Client Subscribe request\r\n"};
const char SUBACKMessage[] PROGMEM = {"Subscribe Acknowledgment\r\n"};
const char UNSUBSCRIBEMessage[] PROGMEM = {"Client Unsubscribe request\r\n"};
const char UNSUBACKMessage[] PROGMEM = {"Unsubscribe Acknowledgment\r\n"};
const char PINGREQMessage[] PROGMEM = {"PING Request\r\n"};
const char PINGRESPMessage[] PROGMEM = {"PING Response\r\n"};
const char DISCONNECTMessage[] PROGMEM = {"Client is Disconnecting\r\n"};
void GSM_MQTT::printMessageType(uint8_t Message)
{
switch (Message)
{
case CONNECT:
{
int k, len = strlen_P(CONNECTMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(CONNECTMessage + k);
Serial.print(myChar);
}
break;
}
case CONNACK:
{
int k, len = strlen_P(CONNACKMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(CONNACKMessage + k);
Serial.print(myChar);
}
break;
}
case PUBLISH:
{
int k, len = strlen_P(PUBLISHMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PUBLISHMessage + k);
Serial.print(myChar);
}
break;
}
case PUBACK:
{
int k, len = strlen_P(PUBACKMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PUBACKMessage + k);
Serial.print(myChar);
}
break;
}
case PUBREC:
{
int k, len = strlen_P(PUBRECMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PUBRECMessage + k);
Serial.print(myChar);
}
break;
}
case PUBREL:
{
int k, len = strlen_P(PUBRELMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PUBRELMessage + k);
Serial.print(myChar);
}
break;
}
case PUBCOMP:
{
int k, len = strlen_P(PUBCOMPMessage );
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PUBCOMPMessage + k);
Serial.print(myChar);
}
break;
}
case SUBSCRIBE:
{
int k, len = strlen_P(SUBSCRIBEMessage );
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(SUBSCRIBEMessage + k);
Serial.print(myChar);
}
break;
}
case SUBACK:
{
int k, len = strlen_P(SUBACKMessage );
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(SUBACKMessage + k);
Serial.print(myChar);
}
break;
}
case UNSUBSCRIBE:
{
int k, len = strlen_P(UNSUBSCRIBEMessage );
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(UNSUBSCRIBEMessage + k);
Serial.print(myChar);
}
break;
}
case UNSUBACK:
{
int k, len = strlen_P(UNSUBACKMessage );
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(UNSUBACKMessage + k);
Serial.print(myChar);
}
break;
}
case PINGREQ:
{
int k, len = strlen_P(PINGREQMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PINGREQMessage + k);
Serial.print(myChar);
}
break;
}
case PINGRESP:
{
int k, len = strlen_P(PINGRESPMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(PINGRESPMessage + k);
Serial.print(myChar);
}
break;
}
case DISCONNECT:
{
int k, len = strlen_P(DISCONNECTMessage);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(DISCONNECTMessage + k);
Serial.print(myChar);
}
break;
}
}
}
//Connect Ack
const char ConnectAck0[] PROGMEM = {"Connection Accepted\r\n"};
const char ConnectAck1[] PROGMEM = {"Connection Refused: unacceptable protocol version\r\n"};
const char ConnectAck2[] PROGMEM = {"Connection Refused: identifier rejected\r\n"};
const char ConnectAck3[] PROGMEM = {"Connection Refused: server unavailable\r\n"};
const char ConnectAck4[] PROGMEM = {"Connection Refused: bad user name or password\r\n"};
const char ConnectAck5[] PROGMEM = {"Connection Refused: not authorized\r\n"};
void GSM_MQTT::printConnectAck(uint8_t Ack)
{
switch (Ack)
{
case 0:
{
int k, len = strlen_P(ConnectAck0);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck0 + k);
Serial.print(myChar);
}
break;
}
case 1:
{
int k, len = strlen_P(ConnectAck1);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck1 + k);
Serial.print(myChar);
}
break;
}
case 2:
{
int k, len = strlen_P(ConnectAck2);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck2 + k);
Serial.print(myChar);
}
break;
}
case 3:
{
int k, len = strlen_P(ConnectAck3);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck3 + k);
Serial.print(myChar);
}
break;
}
case 4:
{
int k, len = strlen_P(ConnectAck4);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck4 + k);
Serial.print(myChar);
}
break;
}
case 5:
{
int k, len = strlen_P(ConnectAck5);
char myChar;
for (k = 0; k < len; k++)
{
myChar = pgm_read_byte_near(ConnectAck5 + k);
Serial.print(myChar);
}
break;
}
}
}
unsigned int GSM_MQTT::_generateMessageID(void)
{
if (_LastMessaseID < 65535)
{
return ++_LastMessaseID;
}
else
{
_LastMessaseID = 0;
return _LastMessaseID;
}
}
void GSM_MQTT::processing(void)
{
if (TCP_Flag == false)
{
MQTT_Flag = false;
_tcpInit();
}
_ping();
}
bool GSM_MQTT::available(void)
{
return MQTT_Flag;
}
void serialEvent1()
{
while (Serial1.available())
{
char inChar = (char)Serial1.read();
if (MQTT.TCP_Flag == false)
{
if (MQTT.index < 200)
{
MQTT.inputString[MQTT.index++] = inChar;
}
if (inChar == '\n')
{
MQTT.inputString[MQTT.index] = 0;
stringComplete = true;
Serial.print(MQTT.inputString);
if (strstr(MQTT.inputString, MQTT.reply) != NULL)
{
MQTT.GSM_ReplyFlag = 1;
if (strstr(MQTT.inputString, " INITIAL") != 0)
{
MQTT.GSM_ReplyFlag = 2; //
}
else if (strstr(MQTT.inputString, " START") != 0)
{
MQTT.GSM_ReplyFlag = 3; //
}
else if (strstr(MQTT.inputString, "IP CONFIG") != 0)
{
_delay_us(10);
MQTT.GSM_ReplyFlag = 4;
}
else if (strstr(MQTT.inputString, " GPRSACT") != 0)
{
MQTT.GSM_ReplyFlag = 4; //
}
else if ((strstr(MQTT.inputString, " STATUS") != 0) || (strstr(MQTT.inputString, "TCP CLOSED") != 0))
{
MQTT.GSM_ReplyFlag = 5; //
}
else if (strstr(MQTT.inputString, " TCP CONNECTING") != 0)
{
MQTT.GSM_ReplyFlag = 6; //
}
else if ((strstr(MQTT.inputString, " CONNECT OK") != 0) || (strstr(MQTT.inputString, "CONNECT FAIL") != NULL) || (strstr(MQTT.inputString, "PDP DEACT") != 0))
{
MQTT.GSM_ReplyFlag = 7;
}
}
else if (strstr(MQTT.inputString, "OK") != NULL)
{
GSM_Response = 1;
}
else if (strstr(MQTT.inputString, "ERROR") != NULL)
{
GSM_Response = 2;
}
else if (strstr(MQTT.inputString, ".") != NULL)
{
GSM_Response = 3;
}
else if (strstr(MQTT.inputString, "CONNECT FAIL") != NULL)
{
GSM_Response = 5;
}
else if (strstr(MQTT.inputString, "CONNECT") != NULL)
{
GSM_Response = 4;
MQTT.TCP_Flag = true;
Serial.println("MQTT.TCP_Flag = True");
MQTT.AutoConnect();
MQTT.pingFlag = true;
MQTT.tcpATerrorcount = 0;
}
else if (strstr(MQTT.inputString, "CLOSED") != NULL)
{
GSM_Response = 4;
MQTT.TCP_Flag = false;
MQTT.MQTT_Flag = false;
}
MQTT.index = 0;
MQTT.inputString[0] = 0;
}
}
else
{
uint8_t ReceivedMessageType = (inChar / 16) & 0x0F;
uint8_t DUP = (inChar & DUP_Mask) / DUP_Mask;
uint8_t QoS = (inChar & QoS_Mask) / QoS_Scale;
uint8_t RETAIN = (inChar & RETAIN_Mask);
if ((ReceivedMessageType >= CONNECT) && (ReceivedMessageType <= DISCONNECT))
{
bool NextLengthByte = true;
MQTT.length = 0;
MQTT.lengthLocal = 0;
uint32_t multiplier=1;
delay(2);
char Cchar = inChar;
while ( (NextLengthByte == true) && (MQTT.TCP_Flag == true))
{
if (Serial1.available())
{
inChar = (char)Serial1.read();
Serial.println(inChar, DEC);
if ((((Cchar & 0xFF) == 'C') && ((inChar & 0xFF) == 'L') && (MQTT.length == 0)) || (((Cchar & 0xFF) == '+') && ((inChar & 0xFF) == 'P') && (MQTT.length == 0)))
{
MQTT.index = 0;
MQTT.inputString[MQTT.index++] = Cchar;
MQTT.inputString[MQTT.index++] = inChar;
MQTT.TCP_Flag = false;
MQTT.MQTT_Flag = false;
MQTT.pingFlag = false;
Serial.println("Disconnecting");
}
else
{
if ((inChar & 128) == 128)
{
MQTT.length += (inChar & 127) * multiplier;
multiplier *= 128;
Serial.println("More");
}
else
{
NextLengthByte = false;
MQTT.length += (inChar & 127) * multiplier;
multiplier *= 128;
}
}
}
}
MQTT.lengthLocal = MQTT.length;
Serial.println(MQTT.length);
if (MQTT.TCP_Flag == true)
{
MQTT.printMessageType(ReceivedMessageType);
MQTT.index = 0L;
uint32_t a = 0;
while ((MQTT.length-- > 0) && (Serial1.available()))
{
MQTT.inputString[uint32_t(MQTT.index++)] = (char)Serial1.read();
delay(1);
}
Serial.println(" ");
if (ReceivedMessageType == CONNACK)
{
MQTT.ConnectionAcknowledgement = MQTT.inputString[0] * 256 + MQTT.inputString[1];
if (MQTT.ConnectionAcknowledgement == 0)
{
MQTT.MQTT_Flag = true;
MQTT.OnConnect();
}
MQTT.printConnectAck(MQTT.ConnectionAcknowledgement);
// MQTT.OnConnect();
}
else if (ReceivedMessageType == PUBLISH)
{
uint32_t TopicLength = (MQTT.inputString[0]) * 256 + (MQTT.inputString[1]);
Serial.print("Topic : '");
MQTT.PublishIndex = 0;
for (uint32_t iter = 2; iter < TopicLength + 2; iter++)
{
Serial.print(MQTT.inputString[iter]);
MQTT.Topic[MQTT.PublishIndex++] = MQTT.inputString[iter];
}
MQTT.Topic[MQTT.PublishIndex] = 0;
Serial.print("' Message :'");
MQTT.TopicLength = MQTT.PublishIndex;
MQTT.PublishIndex = 0;
uint32_t MessageSTART = TopicLength + 2UL;
int MessageID = 0;
if (QoS != 0)
{
MessageSTART += 2;
MessageID = MQTT.inputString[TopicLength + 2UL] * 256 + MQTT.inputString[TopicLength + 3UL];
}
for (uint32_t iter = (MessageSTART); iter < (MQTT.lengthLocal); iter++)
{
Serial.print(MQTT.inputString[iter]);
MQTT.Message[MQTT.PublishIndex++] = MQTT.inputString[iter];
}
MQTT.Message[MQTT.PublishIndex] = 0;
Serial.println("'");
MQTT.MessageLength = MQTT.PublishIndex;
if (QoS == 1)
{
MQTT.publishACK(MessageID);
}
else if (QoS == 2)
{
MQTT.publishREC(MessageID);
}
MQTT.OnMessage(MQTT.Topic, MQTT.TopicLength, MQTT.Message, MQTT.MessageLength);
MQTT.MessageFlag = true;
}
else if (ReceivedMessageType == PUBREC)
{
Serial.print("Message ID :");
MQTT.publishREL(0, MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
Serial.println(MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
}
else if (ReceivedMessageType == PUBREL)
{
Serial.print("Message ID :");
MQTT.publishCOMP(MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
Serial.println(MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
}
else if ((ReceivedMessageType == PUBACK) || (ReceivedMessageType == PUBCOMP) || (ReceivedMessageType == SUBACK) || (ReceivedMessageType == UNSUBACK))
{
Serial.print("Message ID :");
Serial.println(MQTT.inputString[0] * 256 + MQTT.inputString[1]) ;
}
else if (ReceivedMessageType == PINGREQ)
{
MQTT.TCP_Flag = false;
MQTT.pingFlag = false;
Serial.println("Disconnecting");
MQTT.sendATreply("AT+CIPSHUT\r\n", ".", 4000) ;
MQTT.modemStatus = 0;
}
}
}
else if ((inChar = 13) || (inChar == 10))
{
}
else
{
Serial.print("Received :Unknown Message Type :");
Serial.println(inChar);
}
}
}
}
Hey Guys, any help ? The publish is working when i call it inside the loop(). But unfortunately, the subscribe not working, I am sending messages but not able to receive it to my Arduino i.e the OnMessage event/method doesn't execute.
Thanks
Have you found any answers? I have the same problem. The library is working, but MQTT.available() returns allways false and some things behave weird.
Same issue !! not working.. got stuck at MQTT.MessageFlag = true; any solution ?
I got it to work with Altsoft serial on pin 8 and 9
@nictally Can you tell me the changes you did in the cpp file and the example file. For me the output is just stuck at +++AT i.e. SerialEvents @solankigithub Did you get it working?
Guys for me all works like a charm when i rewrite serial event. I will upload my code in some days :D
Can't wait to try it! Thanks.
Here it is https://files.fm/f/6qwyj9z9
@arminsalcin Hello. I need to know if this code works even for software serial because I don't want to use Mega. I will be using nano, pro mini or Uno with a software serial attached to the Sim808 module.
I need to test it first with software serial , then if i make it it will be here. Have a nice day :D
I found a way for Software serial but have a problems with SerialEvent() fuction becouse it work like a hardware interrupt when some informations come in serial it will run , so if we use a software serial nothing came in and code bug but if i connect arduino hardware serial RX with Software serial TX its run normaly. So found way but don't know is it okay to your project.
@arminsalcin If I wanted to connect it on the 0,1 pins that is Serial of arduino uno, then do I need to replace all the Serial1.write/Serial1.print functions with Serial.write/print resp? Currently the Serial is used for notifying us right?
Hello all, I am getting this error:
C:\Users\Abhay.S.Bharadwaj\Desktop\sim900_mqtt_test\sim900_mqtt_test.ino: In function 'void loop()':
sim900_mqtt_test:52: error: cannot convert 'GSM_MQTT::available' from type 'bool (GSM_MQTT::)()' to type 'bool'
if (MQTT.available)
^
sim900_mqtt_test:58: error: '_generateMessageID' was not declared in this scope
MQTT.publish(0, 1, 0, _generateMessageID(), publishTopic, gasPayload);
^
Using library SoftwareSerial at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial
exit status 1
**cannot convert 'GSM_MQTT::available' from type 'bool (GSM_MQTT::)()' to type 'bool'**
I have not done any changes to the library. My code is as follows:
`#include "GSM_MQTT.h"
#include <SoftwareSerial.h>
#define gasPin A1
String MQTT_HOST = "test.mosquitto.org";
String MQTT_PORT = "1883";
char* WillTopic = "*********";
char* WillMessage = "offline";
char* publishTopic = "*********";
SoftwareSerial mySerial(10, 11); // RX, TX
void GSM_MQTT::AutoConnect(void)
{
connect("kumbh1", 0, 0, "username", "password", 1, 1, 1, 1, WillTopic, WillMessage);
}
void GSM_MQTT::OnConnect(void)
{
subscribe(0, _generateMessageID(), "SampleTopic", 1);
publish(0, 1, 0, _generateMessageID(), "SampleTopic", "Hello");
}
void GSM_MQTT::OnMessage(char *Topic, int TopicLength, char *Message, int MessageLength)
{
mySerial.println("New MQTT Message Reseived! Details: ");
mySerial.println(TopicLength);
mySerial.println(Topic);
mySerial.println(MessageLength);
mySerial.println(Message);
}
GSM_MQTT MQTT(20); //20 is the keepalive duration in seconds
void setup()
{
// initialize mqtt:
// GSM modem should be connected to Hardware Serial
// index =0;
MQTT.begin();
/*
Write your setup related arduino code like:
pinMode(gasPin, INPUT);
*/
}
void loop()
{
/*
You can write your maincode here. Example:
*/
float x = analogRead(gasPin);
char* gasPayload = f2s(x, 0); //f2s is our function to convert float values to string
if (MQTT.available)
{
/*
if you want to do something when mqtt connection is live.
You can write your code here
*/
MQTT.publish(0, 1, 0, _generateMessageID(), publishTopic, gasPayload);
}
MQTT.processing();
}
/* float to string
f is the float to turn into a string
p is the precision (number of decimals)
return a string representation of the float.
*/
char *f2s(float f, int p)
{
char * pBuff; // use to remember which part of the buffer to use for dtostrf
const int iSize = 10; // number of buffers, one for each float before wrapping around
static char sBuff[iSize][20]; // space for 20 characters including NULL terminator for each float
static int iCount = 0; // keep a tab of next place in sBuff to use
pBuff = sBuff[iCount]; // use this buffer
if (iCount >= iSize - 1)
{ // check for wrap
iCount = 0; // if wrapping start again and reset
}
else
{
iCount++; // advance the counter
}
return dtostrf(f, 0, p, pBuff); // call the library function
}
` can anyone help me out?
Edit: one error was resolved. i changed if (MQTT.available) to if (MQTT.available()).
but i still cant resolve this:
sim900_mqtt_test:58: error: '_generateMessageID' was not declared in this scope
MQTT.publish(0, 1, 0, _generateMessageID(), publishTopic, gasPayload);
^
in void loop change _generateMessageID() to example "armin" with quotes put your name or whatever tou want to be your message id
MQTT.publish(0, 1, 0, "armin", publishTopic, gasPayload);
ok. I shall try it out! Thank you for your quick response!
You're welcome :D , try it and say if it works.
@karanmakharia I am also stuck at +++AT. Can someone please help? I am using the same code given above. @arminsalcin Can you please upload your code again? The link seems to be expired Any help would be appreciated guys. Thanks
Can you provide us more information , like what module you use? , where do you connect your module rx and tx ? , how do you power your module ...
Hi @arminsalcin , thanks for the responses. As @Akelectro asked it would be great if you could upload the edited library that allows for the use of software-serial interface with the Sim800 :-) Despite that it might have problems in relation to SerialEvent().
@jalkestrup Hello guys sorry for link expired , i will uplaod new one ASAP !
@arminsalcin link plz..lin provided is broken
@arminsalcin Please share the link! I am using SIM800 module and SIM800 RX --> Arduino's TX & SIM800 TX --> Arduino's RX. I am able to publish the message with the topic but not able to subscribe. Please help if anyone finds a solution.
@nithinkurian @solankigithub @arminsalcin Hi am using SIM800 with ATmega328p with seial on (2,3)
I have changed the software serrial and hardware serial and also renamed the serialEvent to serialEvent1. But am getting response upto AT+CIPSTART. after sending connect request, am not getting any response
Here is my serial terminal output. can u please help me to solve this issue..?
AT
OK ATE1
OK AT+CREG?
+CREG: 0,2
OK AT+CREG?
+CREG: 0,1 -5þAT+CIPMUX=0
OK AT+CIPMODE=1
OK AT+CGATT?
+CGATT: 1 -5þAT+CIPSTATUS
OK
STATE: IP INITIAL AT+CSTT="www","",""
OK AT+CIPSTATUS
OK
STATE: IP START AT+CIICR
OK AT+CIPSTATUS
OK
STATE: IP GPRSACT AT+CIFSR
10.244.81.80 AT+CIPSTATUS
OK
STATE: IP STATUS AT+CIPSTART="TCP","192.168.2.139","1883"
OÿAT+CIPSTATUS
OK
STATE: TCP CONNECTING CONNECT MQTT.TCP_Flag = True
@shijinjose you cant use serialevent1 on arduino uno (atmega328) becouse it have only one hardware serial port and thats serial event . You can use only pins 0,1- arduino or 2,3- atmega328 directly.
hi, your link expired again. @arminsalcin
@coffeerr2004001 MQTT.zip
Tested with "Arduino Mega" and things work flawlessly. Was able to get the publish part on Arduino UNO/Nano over software serial. but Subscribe never worked.
again, everything is working flawlessly in MEGA/Serial1.
@abhaysbharadwaj Can you share your code ? , what code you used ?
SIM800L_MQTT.zip file is same as that given by @arminsalcin
@abhaysbharadwaj
if (MQTT.available())
{
MQTT.subscribe(0, 0, "/topic", 1);
}
Try to add subscribe in loop part if it works try also to put in "on connect" function play little bit with it !
GSM_MQTT_Arduino_Subscribe_Publish.zip This is the file. I have modified it to work on software serial of Arduino Uno. Only publish and LWT works. Subscribe is not working.(it requires hardware serial for event generation).
I have tried all this, It's not working. Tried to do subscribe in loop, in setup, in MQTT.available(). Didn't work.
@abhaysbharadwaj Can you also please share connection diagram arduino - sim module
SIM800L -- Arduino Uno/nano Vcc - powered by external buck converter Gnd - Gnd Tx - SoftwareSerial Rx (D5) Rx - SoftwareSerial Tx (D6)
@abhaysbharadwaj Yes you can't get data from subscribe because you changed function to your internal function but it doesn't have any interrupt functions with hardware so when your data maybe come you cant read it , cause rx buffer only stays it don't interrupt any function to read .
oh, then I have to see how to work around this! But I haven't changed any functions. Only Software Serial --> Hardware and Hardware --> Software Serial.
@abhaysbharadwaj
Try this , connect jumper from D5 to arduino serial RX pin , and change in software function "myserialevent" back as default "serialevent" . You should get and subscribe but this is hack not solution... . And yes you changed function ..
ah! I should try this out! regarding the function, I only renamed it. I didn't think it will affect anything.
basically changes all the "Serial" to "mySerial" and vice versa and worked it around a little.
Now, what you say should work. Connecting a jumper from SIM800L Tx to Arduino Uno Hardware Rxo get the data and generate an event. I'll have to try this.
yes you should stay connection also to D5 as you set in code its your rx pin , you only interrupting RX pin this way :)
serialEvent() - looks as normal function but it has actually interrupt function so whenever soem data comes to rx pin it start this function ,changing name at any kind will corrupt it .
now I get it!! "Serial" and "serial" made me assume it was a custom function! :P
@abhaysbharadwaj I'm glad you understand it now , have a nice day !
Thank you very much for the insight and help. You too have a great day.
Hi. I tried the code from @arminsalcin and @abhaysbharadwaj but MQTT.AVAILABLE() never succeeds. Can anyone help me out? I ran out of ideas.
My GSM module allows to set the communicating PINs and I set them to 2(TX) and 5 (RX), and they are wired to the MEGA's 19(RX) and 18(TX) (2 to 19 and 5 to 18). The serial seems to spit all OK messages, but it still doesn't work, it goes into a loop where it just starts all over again. Below is the console output. Any help will be deeply appreciated. Thank you!
AT
OK +++AT ATE1
OK AT+CREG?
+CREG: 0,1
OK AT+CIPMUX=0 AT+CIPMODE=1
OK AT+CGATT?
+CGATT: 1
OK AT+CIPSTATUS
OK
STATE: IP INITIAL AT+CSTT="ac.vodafone.es","vodafone","vodafone"
OK AT+CIPSTATUS
OK
STATE: IP START AT+CIICR
OK AT+CIPSTATUS
OK
STATE: IP GPRSACT AT+CIFSR
77.209.117.183 AT+CIPSTATUS
OK
STATE: IP STATUS AT+CIPSTART="TCP","io.adafruit.com","1883"
OK
CONNECT OK AT+CIPSTATUS
OK
STATE: CONNECT OK AT+CIPSHUT
SHUT OK +++AT
OK ATE1
OK AT+CREG?
+CREG: 0,1
OK AT+CIPMUX=0 AT+CIPMODE=1
OK AT+CGATT?
+CGATT: 1
OK AT+CIPSTATUS
OK
STATE: IP INITIAL AT+CSTT="ac.vodafone.es","vodafone","vodafone"
Nevermind, I found out that if I add a small delay in SerialEvent1, it works...
void serialEvent1()
{
while (Serial1.available())
{
delay(5); //Small delay to make it work
char inChar = (char)Serial1.read();
Hi, First of all, a wonderful job for creating such library. Issue: When i look into the source, "Serial" (Hardware Serial) has been used to communicate with the SIM800 modem and mySerial has been used to print the output.
I am using MEGA, where i need to use "Serial1" to communicate with SIM800 and "Serial" to print the output. So i replaced the occurrence of "Serial" with "Serial1" and "mySerial" with "Serial". I didn't change any other code. The library is not working anymore.. Can you please help to make it little flexible with respect to choosing the serial ports.