Go Down

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

christian1328

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);      
     }
   }
}

Lupus1963

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

christian1328

#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);      
     }
   }
}

christian1328

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");}
*/
}

christian1328

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