Go Down

Topic: Open-Electronics SIM908 problems with SD.h (Read 1 time) previous topic - next topic

Dear Guys,
This is my first post. So since that I excuse myself if there might be anything wrong.

I started a kind of car automation project quite a while ago and now I found some time to proceed from the early implementation status to a kind of reliably working status.

The Arduino UNO R3 is equipped w/ the SIM908 Shield from open-electronics.org. In parallel, I control some outputs within the car (lock/unlock, park heating on/off, etc) as shown in the script below.

However, all that works correctly and I can get the current GPS information as well correctly printed using Serial.print. NOW, I'd like to save my GPS history on a SD Card. I planned to use this SPI SD interface (http://www.ebay.de/itm/SD-Memory-Card-Kartenleser-Module-Slot-Socket-SPI-Reader-fur-Arduino-ARM-MCU-NEU-/400557662494?pt=Wissenschaftliche_Geräte&hash=item5d4318e11e) which works good as long as I use it in a different sketch.

But now, once I add #include <SD.h> in my original sketch as shown in the first line: The Serial Interface shows just weird information and I can't control anything anymore.

Would be great if somebody could give me some hints. I personally could imagine that there is no solution since the sketch runs out of internal memory?

Thanks guys, Christian

Code: [Select]

//#include <SD.h>

//#include "SIM900.h"//wofuer war das notwendig?
#include <SoftwareSerial.h>
//#include "inetGSM.h"
#include "sms.h"
#include "call.h"
#include "gps.h"
#include "sms.h"
#include <stdlib.h>


//InetGSM inet;
CallGSM call;
GPSGSM gps;
SMSGSM sms;

//Variablen
char kfz[9]="x-yz1234";
char msg1[5];
char msg2[5];
char inSerial[20];
boolean started=false;

//GPS Variablen
char lon[15];
char lat[15];
char alt[15];
char time[20];
char time2[20];
char vel[15];
float lat_db;
float lon_db;
char stat;
//char gps_message[160]; //text to be saved to SD

//SMS
char message[160]; //sms text outbox
char smsbuffer[160];// sms text inbox
int pos=0; // SMS position
char n[20]="";//sms sender number for start. from then on always last sms received number


//PINs
//Pinusage GSM_TXPIN_ 2 and GSM_RXPIN_ 3 refer to GSM.cpp.
int lock = 0; // tueren verriegeln grau
int unlock = 1; // tueren entriegeln gelb
int enable = 7; // tueren power fuer lock/unlock gruen war 10
int heater_on = 9; // heizen an blau war 11
int heater_off = 6; // heizen aus weiss war 12
int summer = A0; // alarm war 13
// int 8 seems to interact w/ sim908 - do not use


void setup()
{
 Serial.begin(9600);
 
//PIN setup
 /*Tueren verriegeln*/ pinMode(lock, OUTPUT); digitalWrite(lock, LOW);
 /*Tueren entriegeln*/ pinMode(unlock, OUTPUT); digitalWrite(unlock, LOW);
 /*Tueren entriegeln enable power*/ pinMode(enable, OUTPUT); digitalWrite(enable, LOW);
 /*Heizung an*/ pinMode(heater_on, OUTPUT); digitalWrite(heater_on, LOW);
 /*Heizung aus*/ pinMode(heater_off, OUTPUT); digitalWrite(heater_off, LOW);
 /*summer*/ pinMode(summer, OUTPUT); digitalWrite(summer, LOW);
 /*SD card*/ pinMode(10, OUTPUT);
 /*SD card*/ // SD.begin(4)
 

 if (gsm.begin(2400)){
   gsm.forceON(); //To ensure that SIM908 is not only in charge mode
   started=true;  
 }

 if(started){
   if (gps.attachGPS())
   delay(20000); //Time for fixing - here ok since not in loop
   stat=gps.getStat();
   gps.getPar(lat,lon,alt,time,vel); //nur notwendig fuer die Zeit in der start SMS.
   strlcpy(time,(time),14);
 }
 
};

void loop()
{
 SMS();
 GPS();
};


void SMS(){
   if(started){
   pos=sms.IsSMSPresent(SMS_ALL);
   if(pos<=0){pos=0;}
   if(pos){
     sms.GetSMS(pos,n,smsbuffer,100);

//GPS : sms with coordinates
  if(!strcmp(smsbuffer,"GPS")){
    SMS_GPS();
  }//End sms with coordinates

//Alarm
 if(!strcmp(smsbuffer,"Alarm")){
    SMS_GPS();
    digitalWrite(summer, HIGH);
    delay(10000);
    digitalWrite(summer, LOW);
  }//end Alarm

//Absperren
if(!strcmp(smsbuffer,"Zu")){
       digitalWrite(enable, HIGH);
       delay(500);
       digitalWrite(lock, HIGH);
       delay(1000);
       digitalWrite(lock, LOW);
       digitalWrite(enable, LOW);
       message[0]='\0';
          strcat(message, kfz );
          strcat(message, " ");
          strcat(message, time);
          strcat(message," Zugesperrt");
       sms.SendSMS(n, message);
     Serial.println(message); // kann noch geloescht werden
     }  

//Aufsperren
     if(!strcmp(smsbuffer,"Auf")){
       digitalWrite(enable, HIGH);
       delay(500);
       digitalWrite(unlock, HIGH);
       delay(1000);
       digitalWrite(unlock, LOW);
       digitalWrite(enable, LOW);
       message[0]='\0';
          strcat(message, kfz );
          strcat(message, " ");
          strcat(message, time);
          strcat(message," Aufgesperrt");
      sms.SendSMS(n, message);
     Serial.println(message); // kann noch geloescht werden
     }

//LSH ein
     if(!strcmp(smsbuffer,"Heizung an")){
       digitalWrite(heater_on, HIGH);
       delay(1000);
       digitalWrite(heater_on, LOW);
       message[0]='\0';
          strcat(message, kfz );
          strcat(message, " ");
          strcat(message, time);
          strcat(message," Luftstandheizung eingeschaltet");
       sms.SendSMS(n, message);
     Serial.println(message); // kann noch geloescht werden
     }

//LSH aus
     if(!strcmp(smsbuffer,"Heizung aus")){
       digitalWrite(heater_off, HIGH);
       delay(1000);
       digitalWrite(heater_off, LOW);
       message[0]='\0';
          strcat(message, kfz );
          strcat(message, " ");
          strcat(message, time);
          strcat(message," Luftstandheizung ausgeschaltet");
       sms.SendSMS(n, message);
      Serial.println(message); // kann noch geloescht werden
     }

}
if(pos){delsms();}
}
}

void SMS_GPS(){
  digitalWrite(summer, HIGH); // noch auf millis() ohne delay umschreiben
  delay(200);
  digitalWrite(summer, LOW);
  message[0]='\0';
  strcat(message,kfz);
  strcat(message," time: ");
  strcat(message,time);  
  strcat(message," lon: ");
  strcat(message,lon);
  strcat(message," lat: ");
  strcat(message,lat);
  strcat(message," alt: ");
  strcat(message,alt);
  strcat(message," vel: ");
  strcat(message,vel);
  sms.SendSMS(n, message);
}  

void GPS(){
 stat=gps.getStat();
 if(stat==3 || stat==2){
 gps.getPar(lat,lon,alt,time,vel); //habe hier lat und lon gegenueber der dokumentation vertauscht!!!
      lon_db=convert(lon);
      lat_db=convert(lat);
      strlcpy(time,(time),14);//enfernen der tausendstel sekunden
      strlcpy(alt,(alt),7);//Hoehe auf sieben Stellen
      strlcpy(vel,(vel),6);//Geschwindigkeit auf sechs Stellen
     
      message[0]='\0';
          strcat(message, time);
          strcat(message, ";");
          strcat(message, lon);
          strcat(message, ";");
          strcat(message, lat);
          strcat(message, ";");
          strcat(message, alt);
          strcat(message, ";");
          strcat(message, vel);
       Serial.println(message); // kann noch geloescht werden
       //das dann auch auf SD schreiben
 }
}


int strpos(char *str, char *target) {
char *res=0;
res = strstr(str, target);
if (res == NULL) return false;
else             return res - str;
}

float convert(char* str){
float mmmmmm;
float dd;
int pos;
pos=strpos(str,".");
char dd_str[pos-1];
dd_str[0]='\0';
char mmmmmm_str[6];
mmmmmm_str[0]='\0';
for (int i=0; i<pos-2; i++){
  dd_str[i]=str[i];
}
dd_str[pos-2]='\0';
dd=atof(dd_str);
mmmmmm_str[0]=str[pos-2];
mmmmmm_str[1]=str[pos-1];
mmmmmm_str[2]=str[pos];
mmmmmm_str[3]=str[pos+1];
mmmmmm_str[4]=str[pos+2];
mmmmmm_str[5]=str[pos+3];
mmmmmm_str[6]='\0';
mmmmmm=atof(mmmmmm_str);
float result;
result=dd+mmmmmm/1000/60;
return result;
}

void delsms(){
   int pos=sms.IsSMSPresent(SMS_ALL);
     if (pos!=0){//pos>0
     Serial.print("Find SMS at the pos ");
     Serial.println(pos);
     if (sms.DeleteSMS(pos)==1){    
       Serial.print("Deleted SMS at the pos ");
       Serial.println(pos);      
     }
   }
}

The serial interface use Pin 0 and 1, so you cannot use Pin 0 and 1 for other things.

#2
Dec 13, 2013, 09:11 pm Last Edit: Dec 13, 2013, 09:50 pm by christian1328 Reason: 1
Dear Lupus,
Totally right, thanks for letting me know.

However, I've adjusted this, now but I am still not able to use SD and GPS in parallel.
I'l be trying for the next time and post updates / additional questions.

That is where I currently stand with some demo code. It works just fine as long as I use only one of the two voids. Once I use both, I am not getting it running.
Code: [Select]

{
 SD_card();
 GPS();
}


Any help would be great :)

Code: [Select]

#include <SoftwareSerial.h>
#include "sms.h"
#include "call.h"
#include "gps.h"
#include "sms.h"
#include <stdlib.h>
#include <SD.h>

//SD
const int chipSelect = 10;

//InetGSM inet;
CallGSM call;
GPSGSM gps;
SMSGSM sms;

//Variablen
const char kfz[9]="X-XX1234";
char msg1[5];
char msg2[5];
char inSerial[20];
boolean started=false;

//GPS Variablen
char lon[15];
char lat[15];
char alt[15];
char time[20];
char time2[20];
char vel[15];
float lat_db;
float lon_db;
char stat;

//SMS
char message[160]; //sms text outbox
char smsbuffer[160];// sms text inbox
int pos=0; // SMS position
char n[20]="numberplaceholder";//sms sender number for start. from then on always last sms received number

//PINs
//Pinusage GSM_TXPIN_ 2 and GSM_RXPIN_ 3 refer to GSM.cpp.
const int lock = A1; // tueren verriegeln grau
const int unlock = A2; // tueren entriegeln gelb
const int enable = 7; // tueren power fuer lock/unlock gruen
const int heater_on = 9; // heizen an blau
const int heater_off = 6; // heizen aus weiss
const int summer = A0; // alarm grau
// int 8 seems to interact w/ sim908 - do not use


void setup()
{
// Open serial communications and wait for port to open:
 Serial.begin(9600);

//PIN setup
 /*SD*/ pinMode(10, OUTPUT);
 /*Tueren verriegeln*/ pinMode(lock, OUTPUT); digitalWrite(lock, LOW);
 /*Tueren entriegeln*/ pinMode(unlock, OUTPUT); digitalWrite(unlock, LOW);
 /*Tueren entriegeln enable power*/ pinMode(enable, OUTPUT); digitalWrite(enable, LOW);
 /*Heizung an*/ pinMode(heater_on, OUTPUT); digitalWrite(heater_on, LOW);
 /*Heizung aus*/ pinMode(heater_off, OUTPUT); digitalWrite(heater_off, LOW);
 /*summer*/ pinMode(summer, OUTPUT); digitalWrite(summer, LOW);  
 
 if (gsm.begin(2400)){
   gsm.forceON(); //To ensure that SIM908 is not only in charge mode
   Serial.println("GSM"); // kann noch rausgenommen werden
   started=true;  
 }  

 if(started){
   if (gps.attachGPS())
     Serial.println("GPS"); // kann noch rausgenommen werden
   delay(20000); //Time for fixing - here ok since not in loop
   stat=gps.getStat();
   //gps.getPar(lat,lon,alt,time,vel); //nur notwendig fuer die Zeit in der start SMS.
   //strlcpy(time,(time),14);
 }
 
 if (SD.begin(chipSelect)) {
   Serial.println("SD");
 }
}


void loop()
{
 SD_card();
 GPS();
}

void GPS(){
 stat=gps.getStat();
 if(stat==3 || stat==2){
 gps.getPar(lat,lon,alt,time,vel); //habe hier lat und lon gegenueber der dokumentation vertauscht!!!
      strlcpy(time,(time),14);
      strlcpy(alt,(alt),7);
      strlcpy(vel,(vel),6);
     
      message[0]='\0';
          strcat(message, time);
          strcat(message, ";");
          strcat(message, lon);
          strcat(message, ";");
          strcat(message, lat);
          strcat(message, ";");
          strcat(message, alt);
          strcat(message, ";");
          strcat(message, vel);
       Serial.println(message); // kann noch geloescht werden\
       //das dann auch auf SD schreiben
 }
}

void SD_card(){
 char dataString[] = "toll";
 File dataFile = SD.open("datalog2.txt", FILE_WRITE);
  if (dataFile) {
   dataFile.println(dataString);
   dataFile.close();
   Serial.println(dataString);
 }  
 else {Serial.println("error opening");}
}


void delsms(){
   int pos=sms.IsSMSPresent(SMS_ALL);
     if (pos!=0){//pos>0
     Serial.print("Find SMS at the pos ");
     Serial.println(pos);
     if (sms.DeleteSMS(pos)==1){    
       Serial.print("Deleted SMS at the pos ");
       Serial.println(pos);      
     }
   }
}

Okay, what I've been identifying so far is that the GSM/GPS library on its own consumes more or less all Uno RAM. Therefore it's challenging running additional libraries in paralell.

I for example get the result chkMem free= 38, memory used=2010 only with sms.h and gps.h running. Then there are no additional ~400 byte left for the SD.h

Now, I question myself if there is an easier, more efficient way in handling the gsm/gps related memory.

By the way, my current sketch...

Code: [Select]

#include <SoftwareSerial.h>
//#include "inetGSM.
#include "sms.h"
#include "gps.h"
#include <SD.h>

//InetGSM inet;
GPSGSM gps;
SMSGSM sms;

//Variablen
const char kfz[9]="A-BC1234";

//SD
//const int chipSelect = 10;

//GPS
char lon[15];
char lat[15];
char alt[15];
char time[20];
char vel[15];

//SMS
char message[160]="no message"; //sms text outbox
char smsbuffer[160];// sms text inbox
int pos=0; // SMS position
char n[20]="+491701234567";//sms sender number for start. from then on always last sms received number

//PINs
//Pinusage GSM_TXPIN_ 2 and GSM_RXPIN_ 3 refer to GSM.cpp.
//D8 seems to interact w/ sim908 - do not use
const int lock = A4; // doors lock grau
const int unlock = A5; // doors unlock gelb
const int enable = 7; // doors enable power lock/unlock gruen
const int heater_on = 9; // LSH heater on blau
const int heater_off = 6; // LSH heater off weiss
const int summer = A0; // alarm grau
#define RAMSIZE 2048 //you can probably get this from another define somewhere



void setup()
{
  Serial.begin(9600);

//PIN setup
  /*SD*/ pinMode(10, OUTPUT);
  /*doors lock*/ pinMode(lock, OUTPUT); digitalWrite(lock, LOW);
  /*doors unlock*/ pinMode(unlock, OUTPUT); digitalWrite(unlock, LOW);
  /*doors enable power*/ pinMode(enable, OUTPUT); digitalWrite(enable, LOW);
  /*LSH heater on*/ pinMode(heater_on, OUTPUT); digitalWrite(heater_on, LOW);
  /*LSH heater off*/ pinMode(heater_off, OUTPUT); digitalWrite(heater_off, LOW);
  /*alarm*/ pinMode(summer, OUTPUT); digitalWrite(summer, LOW); 
 
  if (gsm.begin(9600)){
    gsm.forceON(); //To ensure that SIM908 is not only in charge mode
    Serial.println("GSM"); // can be removed
  } 

  if (gps.attachGPS())
    Serial.println("GPS"); // kann noch rausgenommen werden
  delay(20000); //Time for fixing - here ok since not in loop

 
  //if (SD.begin(chipSelect)) {
  //  Serial.println("SD");
  //}
}


void loop()
{
 
chkMem();
  GPS();
}

int availableMemory() {
  int size = RAMSIZE;
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL);
  free(buf);
  return size;
}

void chkMem() {
  Serial.print("chkMem free= ");
  Serial.print(availableMemory());
  Serial.print(", memory used=");
  Serial.println(RAMSIZE-availableMemory());
}
void GPS(){
  gps.getPar(lat,lon,alt,time,vel); //lon lat!!!
       strlcpy(time,(time),14);
       strlcpy(alt,(alt),7);
       strlcpy(vel,(vel),6);
       
       message[0]='\0';
           strcat(message, time);
           strcat(message, ";");
           strcat(message, lon);
           strcat(message, ";");
           strcat(message, lat);
           strcat(message, ";");
           strcat(message, alt);
           strcat(message, ";");
           strcat(message, vel);
        Serial.println(message); // can be deleted

   /*File dataFile = SD.open("datalog2.txt", FILE_WRITE);
        if (dataFile) {
        dataFile.println(message);
        dataFile.close();
     } 
  else {Serial.println("error opening");}
*/
}

Now, ordered the Mega to avioud the memory bottlenecks. Keeping you updated.

Looks like it is not a open electronics or library issue since all functions work fine, only more SRAM is needed.

Cheers, Christian

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy