I am working on a project that collects data using GPS and RFID. I wish to take this data and then send it Thingspeak via SIM800L
I've broken this down to smaller steps so that I can work out the issues before moving the code to the main program/sketch. For the sketch below, I just want to make sure that data is being sent with 100% reliability. If it works all the time, then I would change the kind of data being sent to be the one I am creating in my main project
My hardware for sending the data
- Arduino Mega, Rev 3
- SIM800L GMS module with antenna
- Power supply for the SIM800L
- Micro SIM card for the SIM800L
Program objectives
- Collect some data
- Send the data to Thingspeak
- Verify that the data has been sent and received on Thinsgpeak
- Repeat the above
I checked online for how to use the SIM800L and how to send the data
This link has formed the basis of my project sketch Cellular IoT: Send SIM800/900 GPRS Data to Thingspeak with Arduino
My sketch is as follows:
void setup()
{
Serial2.begin(9600); // the GPRS baud rate
Serial.begin(9600); // the GPRS baud rate
delay(1000);
}
void loop()
{
float h = millis()
float t = millis()/4;
delay(100);
if (Serial2.available())
Serial.write(Serial2.read());
Serial2.println("AT");
delay(1000);
Serial2.println("AT+CPIN?");
delay(1000);
Serial2.println("AT+CREG?");
delay(1000);
Serial2.println("AT+CGATT?");
delay(1000);
Serial2.println("AT+CIPSHUT");
delay(1000);
Serial2.println("AT+CIPSTATUS");
delay(2000);
Serial2.println("AT+CIPMUX=0");
delay(2000);
ShowSerialData();
Serial2.println("AT+CSTT=\"Safaricom\"");//start task and setting the APN,
delay(1000);
ShowSerialData();
Serial2.println("AT+CIICR");//bring up wireless connection
delay(3000);
ShowSerialData();
Serial2.println("AT+CIFSR");//get local IP adress
delay(2000);
ShowSerialData();
Serial2.println("AT+CIPSPRT=0");
delay(3000);
ShowSerialData();
Serial2.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection
delay(6000);
ShowSerialData();
Serial2.println("AT+CIPSEND");//begin send data to remote server
delay(4000);
ShowSerialData();
//API key used below is not the actual one I am using
String str="GET https://api.thingspeak.com/update?api_key=QNMOITJQRVAHMO&field1=" + String(t) +"&field2="+String(h);
Serial.println(str);
Serial2.println(str);//begin send data to remote server
delay(4000);
ShowSerialData();
Serial2.println((char)26);//sending
delay(5000);//waitting for reply, important! the time is base on the condition of internet
Serial2.println();
ShowSerialData();
Serial2.println("AT+CIPSHUT");//close the connection
delay(100);
ShowSerialData();
}
void ShowSerialData()
{
while(Serial2.available()!=0)
Serial.write(Serial2.read());
delay(500);
}
Results expected
For the purpose of testing, I am just collecting the milliseconds and sending that.
My expectation is that the data will be sent and received and that this repeats every period of time as seen by the delays - roughly every minute
Actual results
- Data is sent
- The thingspeak channel does show the data and graphs it
- The data being sent increases in value with time
- However, for every 20 data points that should have been sent, roughly 3 are never received or sent
- This means that the success rate of sending the data is about 85%
For my main program, I have to send all the data I create, there can be no missing data point.
My thinking is that the SIM module is using 2G technolog and it's not that reliable, hence the data drops. The SIM module has enough power and blinks twice per min when sending data.
Therefore, I feel that I need to introduce some kind of check code to verify that the data that should have been sent was actually received on Thingspeak. If it wasn't sent, then it should try again
Due to the fact that the SIM800L uses serial to communicate, how would I check the incoming serial info and verifiy that the data was received at the website?
When the sketch invokes the ShowSerialData(); function - it shows on the serial monitor the following after data was sent
- SEND OK
- A number that increments every time data was sent
I tried to include an if statement that checks if the serial monitor info is SEND OK or not and then do a check with that. But I don't think I got the method right of reading that info
This is what I tried:
void ShowSerialData()
{
while(Serial2.available()!=0)
Serial.write(Serial2.read());
if (Serial2.read()=="SEND OK");
{
Serial.prinln("ABC); // just my way of checking that the if statement worked
}
delay(500);
}
But the test never goes true
Any guidance on this?