use of serial lib in user library

hello,

i need some help on an issue, which i could not resolve so far.

i am trying to access a siemens sms modem via the standard serial lib on arduino 22 on linux for sending and receiving sms.

serial.begin(9600) is issued on top level in setup(). I have included wprogram.h into the class header.

in my library i declared a class gsm and make use of serial.read / peek / print and println within methods acting on this class. so the serial. routines are called within the methods for the class (1st level - class method calling serial). some methods use other methods, which in turn call the serial. routines (2nd level - class method calling class method calling serial).

i notice that when I use the "2nd level" routines, the serial interface does not perform. the rx / tx leds on the arduino mega do not fire.

when i use the same/similar code on the main program level, i.e. replace a class method by a subroutine and thereby push the methods calling the serial. one level higher, so subeoutine calling class method calling serial instead of method calling method calling serial, they apparently work.

did anyone come across something similar ?

thx & happy new year.

s

Theoretical questions are always much harder to answer than concrete questions.

Can you post the code that is having issues?

If not, at least answer a few questions. Does the gsm class have a begin() method? Are there things in the constructor that rely on hardware having been initialized or other constructors having been called?

i declared a class gsm and make use of serial.read / peek / print and println within methods acting on this class.

What does "methods acting on this class" mean? You're not referring to methods of the class are you? Methods refers to functions that are defined in a class. Those methods belong to instances of the class, and affect that instance only, not the class that the object is an instance of.

The only reason I can think of for some methods to work (can use Serial methods) while others do not (can not use Serial methods) would involve public/private issues. Since Serial is a global instance, those issues should not arise.

ok, if you want to browse through code:

.h

#ifndef tc35i
#define tc35i

#include "WProgram.h"
#include <ctype.h>

#define telnochar(c)      (isdigit(c) || ((c)=='+'))

const int smalldelay=50;

const int bsize=20;
const int telnolength=30;

#define TIMEOUT      5000
#define EOL (char)0

#define INDICATORS      9

#define BATTCHARGE      0
#define SIGNAL            1
#define SERVICE            2
#define SOUNDER            3
#define MESSAGE            4
#define CALL            5
#define ROAM            6
#define SMSFULL            7
#define RSSI            8


class GSMModule {
      
public:
      boolean registered;

      byte indicators[INDICATORS];
      char gsmoperator[telnolength];
      
      GSMModule(char *b=0, int n=0);
      
      int begin(void);
      int getinfo(void);
      int registernetwork(void);

      int sendcommand(char *c);

      void readsms(char *telno);            
      void sendsms(char *telno, char *text);
      void callwaiting(char *telno);
      
      void gettime(void);

      int checknumber (char *number);
      int waitfor(char *c);

      int switchon(void);
      void switchoff(void);      

      char *buffer;
private:

      int seeknonspace(void);

      int getch(void);
      int peekch(void);
      int Readln(char *b);

      int truncright(char *c);      
      int truncleft(char *c);      

      int terminate(void);
      
      int buffsize;
};

#endif

excerpts from .cpp

#include <tc35i.h>
#include <ctype.h>
#include "WProgram.h"

/*****************************
 *
 * initializes gsm variable
 *
 *
 *****/

GSMModule::GSMModule(char *buf, int size) {
      byte i;

      buffer=buf;
      buffsize=size;

      for(i=0; i<INDICATORS; i++)
            indicators[i]=0;

      registered=false;
      *gsmoperator=EOL;
}




/*****************************
 *
 *      starts the gsm module
 *
 *      returns:
 *            0      successfully registered with a GSM operator
 *              -1      AT does not work
 *            -2      ATE0 does not work
 *            -3      CMGF does not work
 *            -4       get info (CIND) does not answer properly
 *            -5      CIND does not pass all parameters
 *            -6      modem could not register      
 *
 *****/

int GSMModule::begin(void) {
      int result;
      
      registered=false;

      result=switchon();
      if(result<0)
            return -1;

      result=sendcommand("ATE0");            // switch off Echo by Modem
      if(result<0)
            return -2;

      result=sendcommand("AT+CMGF=1");      // set the SMS mode to text 
      if(result<0)
            return -3;

      result=getinfo();                  // check for basic modem indicators
      return result;
      if(result<0)
            return -3+result;

      result=registernetwork();            // now attempt to register with network
      if(result<0)
            return -5;

      registered=true;                  //network available only after successful register
      return 0;
}


/*****************************
 *
 * reads character from serial
 *
 * returns:
 *      -1       if timeout
 *      char      otherwise
 *
 *****/

int GSMModule::getch(void) {
      int c;
      long start;

      start=millis();
      
      do {
            c=Serial.read();
      } while ((c==-1) && ((millis()-start)>TIMEOUT));
      
      return c;
}


/*****************************
 *
 * peeks character from serial
 *
 * returns:
 *      -1       if timeout or no character
 *      char      otherwise
 *
 *****/

int GSMModule::peekch(void) {
      int c;
      long start;

      start=millis();
      
      do {
            c=Serial.peek();
      } while ((c==-1) && ((millis()-start)>TIMEOUT));
      
      return c;
}


/*****************************
 *
 * reads line terminated by LF 0x0a into buffer
 * eliminates CR / LF pairs
 *
 * returns length of read string
 *
 *****/

#define lineterminator(c) ((c==0x0A) || (c==0x0D))

int GSMModule::Readln(char *b) {      
      int i=0;
      byte c;
      
        do {
            c=getch();
            if(c>0)
                  b[i++]=c;
      } while (!lineterminator(c) && (i<(buffsize-1)) && (c>-1));
      
      b[i++]=(char)0;
      
      do {
            c=peekch();
            if (lineterminator(c))
                  c=getch();

            } while (lineterminator(c));

//      truncleft(b);
      return truncright(b);
}


/*****************************
 *
 * switches GSM module on
 *
 * returns
 *
 *       0 if all ok
 *       negative value if no AT command could be received
 *
 *****/

int GSMModule::switchon() {
byte i;
int res;

      Serial.flush();
      i=0;
      do {                  // issue ATs to synchronize modem serial 
            res=sendcommand("AT");
      } while((res<0) && (i++<5));
return res;
}



/*****************************
 *
 * sends command to GSM Module
 *
 * returns
 *      answer in buffer, truncated on both ends
 *
 *       length of the Modules's answer
 *      -1 if timeout from serial
 *      0 if module not registered
 *
 *****/



int GSMModule::sendcommand(char *cmd) {
      int res;

      Serial.println(cmd);
      delay(4*smalldelay);            // give time to execute cmd
      res=waitfor("\r\n");            // reads first CR, LF
      if(res>=0) {
            Readln(buffer);            // reads answer (OK, ERROR, other) and 2nd CR, LF
            res=strlen(buffer);
            if(isin(buffer,"OK")!=0) {
                  terminate();
            }
      }
      return res;
}



/*****************************
 *
 * waits for command termination, i.e. OK CR/LF
 * 
 *
 *****/

int GSMModule::terminate(void) {
      
      return waitfor("OK\r\n");  
}




/*****************************
 *
 * receives informatio from SMS Module
 * 
 * saves status information into variables
 *       returns
 *      0      all ok
 *      -1      no answer from CIND
 *      -2      not all parameters read
 *
 *****/

int GSMModule::getinfo(void) {
      char *p;
      int result;
      byte i=0;

      sendcommand("AT+CIND?");

      if(isin(buffer, "+CIND:")!=0) {
            writestr(buffer);
            return -1;
      }

      do {
            for(p=buffer;(!isdigit(*p) && *p);p++); // search for 1st digit

            result=0;
            for(; isdigit(*p); p++) {
                  result*=10;
                  result+=*p-'0';
            }            
            indicators[i++]=result;
      } while ((i<INDICATORS) && *p);

      if (i<INDICATORS)
            return -2;

      return 0;
}

main:

#include <tc35i.h>

const int bufsize=160;

char gsmbuf[bufsize];

GSMModule gsm(gsmbuf,bufsize);



void setup() {
   pinMode(13,OUTPUT);
   Serial.begin(9600);
}


void blink(int cnt) {
  int i;
  
  for(i=0;i<cnt;i++) {
    digitalWrite(13,HIGH);
    delay(250);
    digitalWrite(13,LOW);
    delay(500);
  }
}

int mybegin(void) {
      int result;
      
      gsm.registered=false;

      result=gsm.switchon();
      if(result<0)
            return -1;

      result=gsm.sendcommand("ATE0");            // switch off Echo by Modem
      if(result<0)
            return -2;

      result=gsm.sendcommand("AT+CMGF=1");      // set the SMS mode to text 
      if(result<0)
            return -3;

      result=gsm.getinfo();                  // check for basic modem indicators
      if(result<0)
            return -3+result;

      result=gsm.registernetwork();            // now attempt to register with network
      if(result<0)
            return -6;

      gsm.registered=true;                  //network available only after successful register
      return 0;
}



void loop() {
  byte c;
  int i,j,result;

//  i=gsm.begin();  will not work 

  i=mybegin(); // works

  if(i<0)
    blink(-i);
  else 
    blink(9);
 
for(;1;);
}

i took care to call the gsm.begin after the gsm instance is defined and after the serial.begin is called.

what i meant is that when i create the gsm class and define -say- getinfo, it apparently does not work when called from gsm.begin, but works when called from mybegin. in contrast to this, sendcommand works.

any help would be appreciated.