Hardware:
SeeedStalker 3.0
GPRS Bee Rev. 4 (SIM900)
LiPo Battery
Steps:
- Wake Seeedstalker from sleep
- Power up GPRSBee
- Pull data from sensors
- Connect to wireless network
- Connect to thingspeak
- Push data to thingspeak
It is necessary to solder P3 and P4 for for the RTC interrupts to function correctly. See the Seeeduino Stalker wiki for more details on this.
You will also need to solder a wire from pin 9 on the Bee socket to D5. See why here:
http://old.gprsbee.com/
Finally, for debugging, I find it's essential to have serial communication with my computer, so I've had to switch to using SW serial on D6 & D7. This means dealing with the Seeeduino Stalker v3.0's hardware bug. I found Seeed's wiki does not completely address the hardware bug. I had to cut a trace on P6 in addition to the one for P7. If you're having a hard time, just use a multi-meter to ensure you are wired how you expect to be.
Code:
1) Wake Seeedstalker from sleep -
This code has been written mostly by SeeedStudio on their wiki:
http://www.seeedstudio.com/wiki/Seeeduino-Stalker_v3#Data_Logger_Example
I'm not going to cover it again.
2) Power up GPRSBee - I will be adding this gradually in the coming weeks.
void gprspwr_on()
{
Serial.println("Turning on GPRS");
pinMode(5, OUTPUT);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(5,HIGH);
delay(2000);
digitalWrite(5,LOW);
readATcommand("Call Ready",6,10000);
if (answer == 1){
Serial.println("GPRSbee is on!");
}
}
void gprspwr_off()
{
Serial.println("Turning off GPRS");
pinMode(5, OUTPUT);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(5,HIGH);
delay(2000);
digitalWrite(5,LOW);
answer = readATcommand("NORMAL POWER DOWN",2,2000);
if (answer == 1){
Serial.println("Sucessful Powerdown Complete");
}
}
boolean gprspwr_status()
{
Serial.println("GPRS Power Status");
answer = sendATcommand("AT", "OK", 2, 2000);
if (answer == 0){
Serial.println("GPRSbee is Powered off!");
}
else if (answer == 1){
Serial.println("GPRSbee is on!");
}
return answer;
}
int8_t readATcommand(char* expected_answer1, unsigned int expected_answers, unsigned int timeout)
{
uint8_t x=0, answer=0;
boolean complete = 0;
char a;
char response[100];
unsigned long previous;
String incomingdata;
boolean first;
previous = millis();
for(int i = 0; i < expected_answers; i++){
x = 0;
complete = 0;
a = 0;
first = 0;
memset(response, '\0', 100); // Initialize the string
do{
if(SIM900.available() != 0){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 13){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 10){
if (first == 0){
//keep going, just ignore it
}
else{
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
complete = 1;
}
}
}
else if(a == 0){
Serial.println("Found a blank");
}
else {
response[x] = a;
x++;
first = 1;
//Serial.println(response);
}
if(strstr(response, expected_answer1) != NULL)
{
answer = 1;
complete = 1;
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
return answer;
}
else if(strstr(response, "ERROR") != NULL)
{
answer = 2;
}
}
}
while((complete == 0) && ((millis() - previous) < timeout));
//Serial.println(i);
}
return answer;
}
{
Serial.println("Turning on GPRS");
pinMode(5, OUTPUT);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(5,HIGH);
delay(2000);
digitalWrite(5,LOW);
readATcommand("Call Ready",6,10000);
if (answer == 1){
Serial.println("GPRSbee is on!");
}
}
void gprspwr_off()
{
Serial.println("Turning off GPRS");
pinMode(5, OUTPUT);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(5,HIGH);
delay(2000);
digitalWrite(5,LOW);
answer = readATcommand("NORMAL POWER DOWN",2,2000);
if (answer == 1){
Serial.println("Sucessful Powerdown Complete");
}
}
boolean gprspwr_status()
{
Serial.println("GPRS Power Status");
answer = sendATcommand("AT", "OK", 2, 2000);
if (answer == 0){
Serial.println("GPRSbee is Powered off!");
}
else if (answer == 1){
Serial.println("GPRSbee is on!");
}
return answer;
}
int8_t readATcommand(char* expected_answer1, unsigned int expected_answers, unsigned int timeout)
{
uint8_t x=0, answer=0;
boolean complete = 0;
char a;
char response[100];
unsigned long previous;
String incomingdata;
boolean first;
previous = millis();
for(int i = 0; i < expected_answers; i++){
x = 0;
complete = 0;
a = 0;
first = 0;
memset(response, '\0', 100); // Initialize the string
do{
if(SIM900.available() != 0){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 13){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 10){
if (first == 0){
//keep going, just ignore it
}
else{
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
complete = 1;
}
}
}
else if(a == 0){
Serial.println("Found a blank");
}
else {
response[x] = a;
x++;
first = 1;
//Serial.println(response);
}
if(strstr(response, expected_answer1) != NULL)
{
answer = 1;
complete = 1;
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
return answer;
}
else if(strstr(response, "ERROR") != NULL)
{
answer = 2;
}
}
}
while((complete == 0) && ((millis() - previous) < timeout));
//Serial.println(i);
}
return answer;
}
3) Pull data from sensors - This is dependent on your application, so I'm not going to cover it.
4) Connect to wireless network & thingspeak - I will be adding this gradually in the coming weeks.
void loop() {
if (SIM900.available())
{
Serial.write(SIM900.read());
}
//power up gprs
gprspwr_on();
//connect gprs to internet
answer = sendATcommand("AT+CGATT?","OK",5,2000);
answer = sendATcommand("AT+CSTT=\"CMNET\"","OK",3,2000);
answer = sendATcommand("AT+CIICR","OK",3,2000);
answer = sendATcommand("AT+CIFSR","OK",3,2000);
answer = sendATcommand("AT+CIPSPRT=0","OK",3,2000);
//connect gprs to thingspeak
answer = sendATcommand("AT+CIPSTART=\"tcp\",\"api.thingspeak.com\",\"80\"","CONNECT OK",5,2000);
//post data to thingspeak
answer = senddata(battery_percent());
delay(5000);
//power down gprs
gprspwr_off();
//put arduino to sleep?
for (int i=0; i<60; i++){
delay(1000);
Serial.println(i);
}
}
int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int expected_answers, unsigned int timeout)
{
uint8_t x=0, answer=0;
boolean complete = 0, first = 0;
char a;
char response[100];
unsigned long previous;
String incomingdata;
delay(100);
//Serial.println("Send AT Command");
while( SIM900.available() > 0) SIM900.read(); // Clean the input buffer
SIM900.println(ATcommand); // Send the AT command
Serial.println(ATcommand);
//Serial.println("AT Command Sent!");
previous = millis();
for(int i = 0; i < expected_answers; i++){
x = 0;
complete = 0;
a = 0;
first = 0;
memset(response, '\0', 100); // Initialize the string
do{
if(SIM900.available() != 0){
a = SIM900.read();
//Serial.println(a);
//Serial.println(a,DEC);
if (a == 13){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 10){
if (first == 0){
//keep going, just ignore it
}
else{
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
complete = 1;
}
}
}
else if(a == 0){
Serial.println("Found a blank");
}
else {
response[x] = a;
x++;
first = 1;
//Serial.println(response);
}
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
complete = 1;
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
}
else if(strstr(response, "ERROR") != NULL)
{
answer = 2;
complete = 1;
}
}
}
while((complete == 0) && ((millis() - previous) < timeout));
}
return answer;
}
if (SIM900.available())
{
Serial.write(SIM900.read());
}
//power up gprs
gprspwr_on();
//connect gprs to internet
answer = sendATcommand("AT+CGATT?","OK",5,2000);
answer = sendATcommand("AT+CSTT=\"CMNET\"","OK",3,2000);
answer = sendATcommand("AT+CIICR","OK",3,2000);
answer = sendATcommand("AT+CIFSR","OK",3,2000);
answer = sendATcommand("AT+CIPSPRT=0","OK",3,2000);
//connect gprs to thingspeak
answer = sendATcommand("AT+CIPSTART=\"tcp\",\"api.thingspeak.com\",\"80\"","CONNECT OK",5,2000);
//post data to thingspeak
answer = senddata(battery_percent());
delay(5000);
//power down gprs
gprspwr_off();
//put arduino to sleep?
for (int i=0; i<60; i++){
delay(1000);
Serial.println(i);
}
}
int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int expected_answers, unsigned int timeout)
{
uint8_t x=0, answer=0;
boolean complete = 0, first = 0;
char a;
char response[100];
unsigned long previous;
String incomingdata;
delay(100);
//Serial.println("Send AT Command");
while( SIM900.available() > 0) SIM900.read(); // Clean the input buffer
SIM900.println(ATcommand); // Send the AT command
Serial.println(ATcommand);
//Serial.println("AT Command Sent!");
previous = millis();
for(int i = 0; i < expected_answers; i++){
x = 0;
complete = 0;
a = 0;
first = 0;
memset(response, '\0', 100); // Initialize the string
do{
if(SIM900.available() != 0){
a = SIM900.read();
//Serial.println(a);
//Serial.println(a,DEC);
if (a == 13){
a = SIM900.read();
//Serial.println(a,DEC);
if (a == 10){
if (first == 0){
//keep going, just ignore it
}
else{
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
complete = 1;
}
}
}
else if(a == 0){
Serial.println("Found a blank");
}
else {
response[x] = a;
x++;
first = 1;
//Serial.println(response);
}
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
complete = 1;
Serial.print("string: #");
Serial.print(response);
Serial.println("#");
}
else if(strstr(response, "ERROR") != NULL)
{
answer = 2;
complete = 1;
}
}
}
while((complete == 0) && ((millis() - previous) < timeout));
}
return answer;
}
5) Push data to thingspeak - I will be adding this gradually in the coming weeks.
int8_t senddata(float data){
Serial.print("Battery Percent = ");
Serial.println(data);
//while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
SIM900.println("AT+CIPSEND");
//Serial.println("AT+CIPSEND");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("POST /update HTTP/1.1"); // Send the AT command
//Serial.println("POST /update HTTP/1.1");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Host: api.thingspeak.com"); // Send the AT command
//Serial.println("Host: api.thingspeak.com");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Connection: close"); // Send the AT command
//Serial.println("Connection: close");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("X-THINGSPEAKAPIKEY: J79IQXQ0EOM6NCZX"); // Send the AT command
//Serial.println("X-THINGSPEAKAPIKEY: J79IQXQ0EOM6NCZX");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Content-Type: application/x-www-form-urlencoded"); // Send the AT command
//Serial.println("Content-Type: application/x-www-form-urlencoded");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Content-Length:12"); // Send the AT command
//Serial.println("Content-Length:12");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println(""); // Send the AT command
//Serial.println("");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.print("field1="); // Send the AT command
SIM900.println(data);
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println((char)26);
delay(500);
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
answer = 0;
return answer;
}
Serial.print("Battery Percent = ");
Serial.println(data);
//while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
SIM900.println("AT+CIPSEND");
//Serial.println("AT+CIPSEND");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("POST /update HTTP/1.1"); // Send the AT command
//Serial.println("POST /update HTTP/1.1");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Host: api.thingspeak.com"); // Send the AT command
//Serial.println("Host: api.thingspeak.com");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Connection: close"); // Send the AT command
//Serial.println("Connection: close");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("X-THINGSPEAKAPIKEY: J79IQXQ0EOM6NCZX"); // Send the AT command
//Serial.println("X-THINGSPEAKAPIKEY: J79IQXQ0EOM6NCZX");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Content-Type: application/x-www-form-urlencoded"); // Send the AT command
//Serial.println("Content-Type: application/x-www-form-urlencoded");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println("Content-Length:12"); // Send the AT command
//Serial.println("Content-Length:12");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println(""); // Send the AT command
//Serial.println("");
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.print("field1="); // Send the AT command
SIM900.println(data);
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
SIM900.println((char)26);
delay(500);
while( SIM900.available() > 0) Serial.write(SIM900.read()); // Clean the input buffer
delay(500);
answer = 0;
return answer;
}
Complete Code:
GPRS ThingSpeak v0.1 Beta
Useful Links:
Seeeduino Stalker v3 Wiki:
http://www.seeedstudio.com/wiki/Seeeduino-Stalker_v3
Original GPRSBee Site:
http://old.gprsbee.com/
GSM Particulate Sensor - Thanks alcomposer!!! This code helped me a lot and some of my code is base on this.
https://github.com/alcomposer/GSM-Particulate-Meter/blob/master/ParticulateSensorSIM900.ino
SIM900 Thingspeak Code - Thanks maliki!!! This code was also key in helping me get all of this together.
https://codebender.cc/sketch:267851#sim900%20thingspeak.ino
Misc Others:
http://community.thingspeak.com/forum/thingspeak-api/http-post-using-gsm-module/
https://www.pubnub.com/blog/2015-02-17-connect-arduino-gsm-gprs-shield-to-the-internet/
https://community.particle.io/t/uploading-sensor-data-to-thingspeak/5497
http://www.seeedstudio.com/wiki/Seeeduino_GPRS
Hi
ReplyDeleteI tried doing this with a Stalker V3 and found it to be really unreliable. Since then I bought on of these(https://www.amazon.com/dp/B01F9B4WCG) and its been awesome. Good luck with your Project!
Hello Richard. Thanks for the suggestions. I have it 100% functional now. I a limited by my cell phone coverage in the Upper Peninsula of Michigan. Check out my code, maybe it would help you get the Stalker going. Seeed Studios just released a v3.1 which corrected the hardware issue I covered here. The Mayfly is a great solution though.
ReplyDelete