Hi all,
i am running a GSM-Modem (Adafruit Fona) with a 328-p and am trying to send some measurement data and then the GPS-Data to a cloud-service (ubidots). Both functionalities do work standalone, i.e. if i comment out one of them ("SendMeasurements()" or "SendGPS()") the code below works fine. If i try to run both routines in one sketch, the first one succeeds and the second wont. For me this very much looks like a memory problem - although i tried everything to optimize the code, did a complete rewrite to get rid of String(), used F() in Serial.println, tried to use PROGMEM (though i am not sure it works). What i can see if the second attempt fails is weird output in the Serial Console if i try to print what the controller tries to send to the modem.
Can anyone have a look at my code and tell me if i am missing something or give any further hints to reduce memory usage?
I am reusing some of the code - but i don't have to worry because of duplicate variable names as long as they sit in separate function calls, right?
Thank you very much in advance.
SoftwareSerial myfona = SoftwareSerial(FONA_TX, FONA_RX);
Adafruit_FONA fona = Adafruit_FONA(&myfona, FONA_RST);
int l; //loop counter
void setup() {
Serial.begin(9600);
l = 1;
if (RGB_sensor.init())
{
for(int i=0;i<2;i++){
unsigned int trash1 = RGB_sensor.readRed();
unsigned int trash2 = RGB_sensor.readGreen();
unsigned int trash3 = RGB_sensor.readBlue();
delay(1000);
}
Serial.println("setting sensor up");
}
fona.setGPRSNetworkSettings(F("eseye.com"), F("user"), F("pass"));
pinMode(FONA_KEY, OUTPUT);
TurnOffFona();
delay(1000);
wdt_disable();
}
void loop() {
wdt_reset();
digitalWrite(led, HIGH);
SendGPS();
SendMeasurements();
digitalWrite(led, LOW);
l++;
delay(100);
TurnOffFona();
delay(100);
sleepabit(3600);
}
void SendMeasurements()
{
char PROGMEM variable_red[]="XXXXX";
char PROGMEM variable_green[]="XXXXX";
char PROGMEM variable_blue[]="XXXXX";
unsigned int red = RGB_sensor.readRed();
unsigned int green = RGB_sensor.readGreen();
unsigned int blue = RGB_sensor.readBlue();
char value_red[24+1];
char value_green[24+1];
char value_blue[24+1];
sprintf(value_red,"%d",red);
sprintf(value_green,"%d",green);
sprintf(value_blue,"%d",blue);
TurnOnFona();
delay(100);
fona.begin(4800);
delay(1000);
wdt_reset();
GetConnected();
wdt_reset();
Send2ubidots(variable_red,value_red,variable_green,value_green,variable_blue,value_blue);
GetDisconnected();
wdt_reset();
TurnOffFona();
wdt_reset();
}
void SendGPS()
{
char PROGMEM variable_gps[]="XXXXXXX";
char replybuffer[80];
uint16_t returncode;
char value_gps[]="98";
for(int z = 0; z<2; z++)
{
TurnOnFona();
fona.begin(4800);
delay(3500);
fona.enableGPRS(false);
delay(3000);
fona.enableGPRS(true);
delay(3000);
if (!fona.getGSMLoc(&returncode, replybuffer, 250))
Serial.println(F("Failed!"));
if (returncode == 0) {
char *lat;
char *lon;
char delimiter[] = ",";
char *ptr;
ptr = strtok(replybuffer, delimiter);
int h = 0;
while(ptr != NULL) {
if(h==0)
lat=ptr;
if(h==1)
lon=ptr;
ptr = strtok(NULL, delimiter);
h++;
}
Send2ubidots_gps(variable_gps,value_gps,lon,lat);
} else {
}
delay(1000);
}
TurnOffFona();
delay(3000);
}
void Send2ubidots(char *variable1, char *value1, char *variable2, char *value2, char *variable3, char *value3)
{
wdt_reset();
wdt_enable(WDTO_8S);
int num;
delay(100);
char PROGMEM char1[]="[{\"variable\": \""; //15
char PROGMEM char2[]="\", \"value\":"; //11
char PROGMEM char3[]="}, {\"variable\": \""; //17
char PROGMEM char4[]="\", \"value\":"; //11
char PROGMEM char5[]="}]"; //2
num = strlen(value1)+strlen(value2)+strlen(value3)+strlen(variable1)+strlen(variable2)+strlen(variable3)+15+11+17+11+17+11+2+1;
Serial.println(F("sizeof var1 is: "));
char sendstring[num];
sprintf(sendstring,"%s%s%s%s%s%s%s%s%s%s%s%s%s",char1,variable1,char2,value1,char3,variable2,char4,value2,char3,variable3,char4,value3,char5);
char numchar[sizeof(num)+8];
itoa(num,numchar,10);
delay(100);
wdt_reset();
char lchar[15+1+strlen(numchar)+1];
char PROGMEM char7[]="Content-Length:";
sprintf(lchar,"%s %s",char7,numchar);
if (fona.println("AT+CIPSHUT")) {
delay(100);
}
if (fona.println("AT+CIPMUX=0")) {
delay(100);
wdt_reset();
}
if (fona.println("at+cipcsgp=1,\"eseye.com\",\"user\",\"pass\"")) {
delay(100);
wdt_reset();
}
//wdt_reset();
if (SendATCommand("AT+CIPSTART=\"tcp\",\"things.ubidots.com\",\"80\"", 'C', 'T')) {
delay(100);
}
wdt_reset();
if (SendATCommand("AT+CIPSEND", '\n', '>')) {
delay(100);
}
fona.println("POST /api/v1.6/collections/values HTTP/1.1");
fona.println("Content-Type: application/json");
fona.println(lchar);
fona.println("X-Auth-Token: XXXXX");
fona.println("Host: things.ubidots.com");
fona.println();
fona.println(sendstring);
fona.println();
fona.println((char)26);
if (SendATCommand("", '2', '0')) {
}
else {
}
if (SendATCommand("AT+CIPCLOSE", 'G', 'M')) {
}
}
void Send2ubidots_gps(char *variable1, char *value1, char *longi, char *lat)
{
int num;
char PROGMEM char1[]="{\"value\":"; //9
char PROGMEM char2[]=", \"context\": {\"lat\": "; //21
char PROGMEM char3[]=", \"lng\": "; //9
char PROGMEM char4[]="}}"; //2
char value[]="12";
num = strlen(longi)+strlen(value1)+strlen(lat)+9+21+9+2+1;
char sendstring[num];
sprintf(sendstring,"%s%s%s%s%s%s%s",char1,value1,char2,longi,char3,lat,char4);
char numchar[sizeof(num)+8];
itoa(num,numchar,10);
char varichar[25+16+strlen(variable1)+2];
char PROGMEM char8[]="POST /api/v1.6/variables/"; //25
char PROGMEM char9[]="/values HTTP/1.1"; //16
sprintf(varichar,"%s%s%s",char8,variable1,char9);
char lchar[15+1+strlen(numchar)+2]; //string below + whitespace + num
char PROGMEM char7[]="Content-Length:";
sprintf(lchar,"%s %s",char7,numchar);
wdt_reset();
if (fona.println("AT+CIPSHUT")) {
delay(100);
}
if (fona.println("AT+CIPMUX=0")) {
delay(100);
wdt_reset();
}
if (fona.println("at+cipcsgp=1,\"eseye.com\",\"user\",\"pass\"")) {
delay(100);
wdt_reset();
}
//wdt_reset();
if (SendATCommand("AT+CIPSTART=\"tcp\",\"things.ubidots.com\",\"80\"", 'C', 'T')) {
delay(100);
}
//wdt_reset();
if (SendATCommand("AT+CIPSEND", '\n', '>')) {
delay(100);
}
fona.println(varichar);
fona.println("Content-Type: application/json");
fona.println(lchar);
fona.println("X-Auth-Token: XXXXXXXXX");
fona.println("Host: things.ubidots.com");
fona.println();
fona.println(sendstring);
fona.println();
fona.println((char)26);
wdt_reset();
if (SendATCommand("", '2', '0')) {
}
else {
//Serial.println("Send Timed out, will retry at next interval");
}
if (SendATCommand("AT+CIPCLOSE", 'G', 'M')) {
//wdt_reset();
}
//wdt_reset();
//wdt_disable();
}
boolean SendATCommand(char Command[], char Value1, char Value2) {
unsigned char buffer[64];
unsigned long TimeOut = 20000;
int count = 0;
int complete = 0;
unsigned long commandClock = millis();
fona.println(Command);
//wdt_reset();
while (!complete && commandClock <= millis() + TimeOut)
{
while (!fona.available() && commandClock <= millis() + TimeOut);
while (fona.available()) {
buffer[count++] = fona.read();
if (count == 64) break;
}
//Serial.write(buffer, count);
for (int i = 0; i <= count; i++) {
if (buffer[i] == Value1 && buffer[i + 1] == Value2) complete = 1;
}
}
//wdt_reset();
if (complete == 1) return 1; // Returns "True" - "False" sticks in the loop for now
else return 0;
}