Comments (56)
@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.
from sim800_mqtt.
You have to replace occurrence of "SerialEvent" with "SerialEvent1". I think this will solve your problem.
from sim800_mqtt.
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
from sim800_mqtt.
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();
}
`
from sim800_mqtt.
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);
}
}
}
}
from sim800_mqtt.
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
from sim800_mqtt.
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.
from sim800_mqtt.
Same issue !! not working.. got stuck at MQTT.MessageFlag = true;
any solution ?
from sim800_mqtt.
I got it to work with Altsoft serial on pin 8 and 9
from sim800_mqtt.
@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?
from sim800_mqtt.
Guys for me all works like a charm when i rewrite serial event. I will upload my code in some days :D
from sim800_mqtt.
Can't wait to try it! Thanks.
from sim800_mqtt.
Here it is https://files.fm/f/6qwyj9z9
from sim800_mqtt.
@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.
from sim800_mqtt.
I need to test it first with software serial , then if i make it it will be here.
Have a nice day :D
from sim800_mqtt.
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.
from sim800_mqtt.
@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?
from sim800_mqtt.
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?
from sim800_mqtt.
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);
^
from sim800_mqtt.
in void loop change _generateMessageID() to example "armin" with quotes put your name or whatever tou want to be your message id
from sim800_mqtt.
MQTT.publish(0, 1, 0, "armin", publishTopic, gasPayload);
from sim800_mqtt.
ok. I shall try it out!
Thank you for your quick response!
from sim800_mqtt.
You're welcome :D , try it and say if it works.
from sim800_mqtt.
@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
from sim800_mqtt.
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 ...
from sim800_mqtt.
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().
from sim800_mqtt.
@jalkestrup Hello guys sorry for link expired , i will uplaod new one ASAP !
from sim800_mqtt.
@arminsalcin link plz..lin provided is broken
from sim800_mqtt.
@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.
from sim800_mqtt.
@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
from sim800_mqtt.
hi, your link expired again. @arminsalcin
from sim800_mqtt.
from sim800_mqtt.
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.
from sim800_mqtt.
@abhaysbharadwaj
Can you share your code ? , what code you used ?
from sim800_mqtt.
SIM800L_MQTT.zip
file is same as that given by @arminsalcin
from sim800_mqtt.
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 !
from sim800_mqtt.
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).
from sim800_mqtt.
I have tried all this, It's not working.
Tried to do subscribe in loop, in setup, in MQTT.available(). Didn't work.
from sim800_mqtt.
@abhaysbharadwaj
Can you also please share connection diagram arduino - sim module
from sim800_mqtt.
SIM800L -- Arduino Uno/nano
Vcc - powered by external buck converter
Gnd - Gnd
Tx - SoftwareSerial Rx (D5)
Rx - SoftwareSerial Tx (D6)
from sim800_mqtt.
@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 .
from sim800_mqtt.
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.
from sim800_mqtt.
@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 ..
from sim800_mqtt.
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.
from sim800_mqtt.
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 .
https://www.arduino.cc/en/Tutorial/SerialEvent
from sim800_mqtt.
now I get it!! "Serial" and "serial" made me assume it was a custom function! :P
from sim800_mqtt.
@abhaysbharadwaj
I'm glad you understand it now , have a nice day !
from sim800_mqtt.
Thank you very much for the insight and help. You too have a great day.
from sim800_mqtt.
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"
from sim800_mqtt.
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();
from sim800_mqtt.
Hola alguien q me ayude con q pines se une un arduino mega y el sim900, para q funcione el codigo, en el monitor serie se queda en "++AT"
from sim800_mqtt.
Hi I change the Serial to mySerial n use the 2,3 as Rx Tx in Arduino Uno with SIM800, but still didn't get any response 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+CIPSTATUS
12:15:12.218 -> OK
12:15:12.218 ->
12:15:12.218 -> STATE: IP INITIAL
12:15:12.265 -> �AT+CSTT="WWW"
12:15:12.265 -> OK
AT+CIPSTATUS
12:15:12.343 -> OK
12:15:12.343 ->
12:15:12.343 -> STATE: IP START
STATE: IP GPRSACT
12:15:29.406 -> �AT+CIFSR
12:15:29.406 -> 100.115.165.214
12:15:29.453 -> AT+CIPSTATUS
12:15:29.499 -> OK
12:15:29.499 ->
12:15:29.499 -> STATE: IP STATUS
12:15:29.499 -> �AT+CIPSTART="TCP","broker.hivemq.com","1883"
12:15:29.640 -> OK
12:15:30.515 -> CONNECT
12:15:30.515 -> MQTT.TCP_Flag = True
from sim800_mqtt.
any help???
from sim800_mqtt.
Same issue !! not working.. got stuck at MQTT.MessageFlag = true;
any solution ?
i change the sim its working now
from sim800_mqtt.
For all those getting stuck at MQTT.MessageFlag = true
when using software serial, ESP8266 or other platforms, change GSM_MQTT::processing
in GSM_MQTT.cpp
to
void GSM_MQTT::processing(void)
{
if (TCP_Flag == false)
{
MQTT_Flag = false;
_tcpInit();
}
_ping();
//**************new code*****************
unsigned long t = millis();
//add long waitPeriod = 0; somewhere at the beginning of the file
if (t - waitPeriod > 1000L)
{
waitPeriod = t;
serialEvent(); //call serialEvent every second
}
//*****************************************
}
from sim800_mqtt.
code works perfectly fine!!!!!!!!!!!!!!!!!!
from sim800_mqtt.
Related Issues (20)
- AutoConnect bug.. HOT 2
- [QUESTION] ESP8266 compatibility HOT 4
- For GSM M590 COMPABILITY
- Problem with autoconnect HOT 1
- Stuck at MQTT.TCP_Flag = True ( Sim 800 with atmega328) HOT 3
- SIM ROAMING not supported HOT 1
- Support to websockets HOT 1
- Can't publish and subscribe HOT 2
- Getting unwanted Text after connection HOT 2
- Help in Publish continuous data HOT 1
- inchar == 13 what is it mean HOT 1
- KeepAlive not attempting to reconnect HOT 3
- +++AT loop, SIM800L, Arduino UNO HOT 5
- Not being able to subscribe... HOT 1
- +CMT HOT 1
- error when compiling HOT 3
- Not compiled
- long messages not arriving complete
- Call back functions not working
- MQTT Ping failed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sim800_mqtt.