My serial port si not reading

Dear All,

The condition _cell.available() retunr false and I do not understand why

        if(_cell.available() != 0){    // if there are data in the UART input buffer, reads it and checks for the asnwer
            response[x] = _cell.read();
            Serial.print(response[x]);
            x++;
            
            Serial.print(F("Response"));
            Serial.println(response);
            Serial.print(F("Expected answer"));
            Serial.println(expected_answer);
            
            if (strstr(response, expected_answer) != NULL)    // check if the desired answer (OK) is in the response of the module
            {
                answer = 1;
            }
        }else{
        if(_debug){
         Serial.println(F("No data in UART"));
         }
        }

In my .ino file I do have this

// GENERAL
int debug = true;
int pinToPowerOnModule = 8;
int dtr = 7;

// LED
int green = 12;
#define MSEC 500
#define MSEC_FAST 150

// SERIAL
int baud_rate = 9600;
int rxpin = 2; 
int txpin = 3;
Sim908 sim908(rxpin, txpin, baud_rate, pinToPowerOnModule, debug, dtr);

My constructor look like:

Sim908::Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr)
{
	pinMode(pinToPowerOnModule, OUTPUT);
	pinMode(dtr, OUTPUT);
	_pinToPowerOnModule = pinToPowerOnModule;
	_debug = debug;
	_baud_rate = baud_rate;
	_dtr = dtr;
	_rxpin = rxpin;
	_txpin = txpin;
	
};

I also have an initialize function

void Sim908::initializeSim908()
{
	//digitalWrite(_dtr,LOW);
	SoftwareSerial _cell(_rxpin,_txpin);
	_cell.begin(_baud_rate);
	powerOnSim908();
	
}

in My Sim908.h file, I declare _call like this:

  Sim908.h - Library 
*/

#ifndef Sim908_h
#define Sim908_h

#include <SoftwareSerial.h>
#include "Arduino.h"

class Sim908{
	private:
		int _pinToPowerOnModule;
		//Stream* _cell;
		SoftwareSerial _cell;
		//SoftwareSerial* _cell;
		int _debug;
		int _baud_rate;
		int _dtr;
		int _rxpin;
		int _txpin;
		
	
	public:
		Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr);
		//Sim908(SoftwareSerial cell, int baud_rate, int pinToPowerOnModule, int debug, int dtr);
		void initializeSim908();

		void powerOnSim908();
		int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout);
		void blinkLed(int lPin, int nBlink, int msec);

};

#endif

The terminal display that error message:

/Users/pierrot/Documents/Arduino/libraries/Sim908/Sim908.cpp: In constructor ‘Sim908::Sim908(int, int, int, int, int, int)’:
/Users/pierrot/Documents/Arduino/libraries/Sim908/Sim908.cpp:6: error: no matching function for call to ‘SoftwareSerial::SoftwareSerial()’
/Applications/Arduino.app/Contents/Resources/Java/libraries/SoftwareSerial/SoftwareSerial.h:83: note: candidates are: SoftwareSerial::SoftwareSerial(uint8_t, uint8_t, bool)
/Applications/Arduino.app/Contents/Resources/Java/libraries/SoftwareSerial/SoftwareSerial.h:48: note: SoftwareSerial::SoftwareSerial(const SoftwareSerial&)

NB: In my Sim908.h and Sim908.cpp I added that line #include “SoftwareSerial.h”

So _cell.available or _cell.read should work as if in my .ino file, I would use that?

SoftwareSerial cell(rxpin,txpin);
cell.begin();
cell.available()
cell.read();

Do you see somethink wrong?

Thank a lot

Sim908::Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr)
{
	pinMode(pinToPowerOnModule, OUTPUT);
	pinMode(dtr, OUTPUT);

Anything that interacts with hardware should be in your initialise method, not in the constructor.

class Sim908{
	private:
                ...
		SoftwareSerial _cell;

SoftwareSerial cell(rxpin,txpin);
cell.begin();
cell.available()
cell.read();

You are creating a private instance of SoftwareSerial inside your object, and declaring / using a global instance in your program?

I thought the earlier version of your software passed a pointer to the global instance into the constructor. Why have you changed?

Dear Hackscribe

Thank for your advise.
I moved this to the initializeSim908 function

pinMode(pinToPowerOnModule, OUTPUT);
	pinMode(dtr, OUTPUT);

Now my constructor look like

Sim908::Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr)
{
	_pinToPowerOnModule = pinToPowerOnModule;
	_debug = debug;
	_baud_rate = baud_rate;
	_dtr = dtr;
	_rxpin = rxpin;
	_txpin = txpin;
	
};

You are creating a private instance of SoftwareSerial inside your object, and declaring / using a global instance in your program?

What do you mean? For now _cell is only using in my class

I followed you advise when you told me to remove the begin() from the method

Below there is _cell.begin. It the reason why I make it private

class Sim908{
	private:
                ...
		SoftwareSerial _cell;

Here is my initializeSim908 function

void Sim908::initializeSim908()
{
	pinMode(pinToPowerOnModule, OUTPUT);
	pinMode(dtr, OUTPUT);
	digitalWrite(_dtr,LOW);
	
	SoftwareSerial _cell(_rxpin,_txpin);
	_cell.begin(_baud_rate);
	
	//powerOnSim908();
	
}

What it suprise me, the error message state

/Users/pierrot/Documents/Arduino/libraries/Sim908/Sim908.cpp: In constructor 'Sim908::Sim908(int, int, int, int, int, int)':
/Users/pierrot/Documents/Arduino/libraries/Sim908/Sim908.cpp:7: error: no matching function for call to 'SoftwareSerial::SoftwareSerial()'

but the line Sim908.cpp:7 is my constructor :

Sim908::Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr) // line 7
{
	_pinToPowerOnModule = pinToPowerOnModule;
	_debug = debug;
	_baud_rate = baud_rate;
	_dtr = dtr;
	_rxpin = rxpin;
	_txpin = txpin;
	
};

and there is nothing about SoftwareSerial!!

I thought the earlier version of your software passed a pointer to the global instance into the constructor. Why have you changed?

I think my error come from _cell but I can find it. Then I comment the code about the pointer in order to be concentred on the initializeSim908 function. When this part will be sure and working as if I would have done in my ino file.

SoftwareSerial cell(rxpin,txpin);
cell.begin();
cell.available()
cell.read();

Previosly I did like just above (in the ino file) and it worked, but now I would like to move

SoftwareSerial cell(rxpin,txpin);
cell.begin();

in a library and to be able to use (in the Sim908.cpp file)
_cell.available(), _cell.read as I was doing in an ino file. This is my main issue :cold_sweat:

Do you understand me?
Thank for your help

Quick thing to change.

void Sim908::initializeSim908()
{
	pinMode(pinToPowerOnModule, OUTPUT);
	pinMode(dtr, OUTPUT);

You should use _pinToPowerOnModule and _dtr here

I'll look at the rest of your post.

Ho yep, that's correct. I changed like this

void Sim908::initializeSim908()
{
	pinMode(_pinToPowerOnModule, OUTPUT);
	pinMode(_dtr, OUTPUT);
	digitalWrite(_dtr,LOW);
	
	SoftwareSerial _cell(_rxpin,_txpin);
	_cell.begin(_baud_rate);
	
	//powerOnSim908();
	
}

Thank a lot. I hope I provided enough information

I changed like this

That will never work. The local variable, _cell, goes out of scope when the constructor ends.

OK, I now understand what you meant by this ...

So _cell.available or _cell.read should work as if in my .ino file, I would use that?

SoftwareSerial cell(rxpin,txpin);
cell.begin();
cell.available()
cell.read();

In your library .h file, you have ...

class Sim908{
	private:
		SoftwareSerial _cell;

To initialise the instance, you need to change your constructor to this in your library .cpp file:

Sim908::Sim908(int rxpin, int txpin, int baud_rate, int pinToPowerOnModule, int debug, int dtr): _cell(rxpin, txpin)
{
	_pinToPowerOnModule = pinToPowerOnModule;
	_debug = debug;
	_baud_rate = baud_rate;
	_dtr = dtr;
	_rxpin = rxpin;
	_txpin = txpin;	
};

Hello,
Ok this very interessting because I already that exemple

GSM::GSM():_cell(_GSM_TXPIN_,_GSM_RXPIN_),_tf(_cell, 10),_status(IDLE)

And it compile without error!!!!!

Greate, I am ging to upload my code and see the result. I keep you informed :grin:

Ca marche vachement mieux. Bravo. Toujours un petit bug, mais je vais chercher d'abord... Well done

Ok, it’s work very much better, but there is still a small problem aroud _cell.

I explain step by step.

void Sim908::initializeSim908()
{
	// define the role of pin 8 and 7
        pinMode(_pinToPowerOnModule, OUTPUT);
	pinMode(_dtr, OUTPUT);
        //pu pin 7 the LOW (dtr)
	digitalWrite(_dtr,LOW);
        // Begin _cell (Serial) pin 2 and 3
	_cell.begin(_baud_rate);
        //Powerup SIM908
	powerOnSim908();
}

initializeSim908 call powerOnSim908 funtion

   uint8_t answer=0;
     // Put up pin 8 fro 3 sec to powerup SIM908
    digitalWrite(_pinToPowerOnModule,HIGH);
    delay(3000);
    // Put the pin 8 back down
    digitalWrite(_pinToPowerOnModule,LOW);

     if(_debug){
		Serial.print(F("Powering up SIM908.\n"));  
	}
    while(answer == 0){     // Send AT every two seconds and wait for the answer
    	answer = sendATcommand("AT", "OK", 2000l);
    }
    if(_debug){
	    Serial.print(F("SIM908 is powered on!\n"));  
	}
}

powerOnSim908 call antoher funtion : sendAtCommand in order to continur while OK is received.
The problem is from that moment

int8_t Sim908::sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;
    // For debugin. It display a correct information
   if(_debug){
   	Serial.print("WAITING FOR ANSWER \n");
       Serial.print("Expected answer: ");Serial.println(expected_answer);
       Serial.print("Timeout: ");Serial.println(timeout);
    }

    memset(response, '\0', 100);    // Initialice the string
    
    delay(100);
    
    while( _cell.available() > 0) _cell.read();    // Clean the input buffer
    
    if (ATcommand[0] != '\0')
    {
       // This is displaying
    	if(_debug){
        	Serial.print("Command: ");
        	_cell.println(ATcommand);    // Send the AT command 
        	Serial.println("");
        }
    }

    x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(_cell.available() != 0){    // if there are data in the UART input buffer, reads it and checks for the asnwer
            // THE PROBLEM IS HERE
             response[x] = _cell.read();
            x++;
           // SEE MY COMMENT BELOW
            
			Serial.print(F("*****************\n"));
			Serial.print(F("RESPONSE : "));
            Serial.println(response);
            Serial.print(F("EXPECTED ANSWER : "));
            Serial.println(expected_answer);
            Serial.print(F("*****************\n"));
            
            if (strstr(response, expected_answer) != NULL)    // check if the desired answer (OK) is in the response of the module
            {
                answer = 1;
                 Serial.println(F("ANSWER RECEIVED : "));
                 Serial.println(F(""));
            
            }
        }else{
        if(_debug){
         //Serial.println(F("No data in UART"));
         }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));    // Waits for the asnwer with time out

if(_debug){
Serial.println("");
Serial.print("Answer : ");
Serial.println(answer);
Serial.println("");
}

    return answer;

}

In my point of view this does not work

response[x] = _cell.read();

I think _cell.read() can not read correctly.

In my code I added this for debuging

Serial.print(F("*****************\n"));
			Serial.print(F("RESPONSE : "));
            Serial.println(response);
            Serial.print(F("EXPECTED ANSWER : "));
            Serial.println(expected_answer);
            Serial.print(F("*****************\n"));

and Serial.print(F("RESPONSE : ")); is displaying “xü” like this, while it waiting for OK


RESPONSE : x
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK



RESPONSE : xü
EXPECTED ANSWER : OK


External module is running at a different baud rate from what you expect, maybe?

Hello

@Hackscribble
no, all are at 9600.

@PaulS and and @Hackscribble ( and all who want)
You helped me and I thank you again, but I can not solve and make it working, this because I am not a expert.
Would you be agree to take a bit of your time to see my complete code? It will really help me because I know nobody, in my town or work, who know Arduino or C++.
I Put my files in https://github.com/pierrot10/sim908 and I added some comment to read how and where I see the problem
. I think it around the _cell variable and IsStringReceived() function

I will really appreciate your help :o)

I am sure, I will be able to adapt all of my other functions quickly when it will be solved.

You could use a test program like this, not using the library, to send “AT” to the module and print what characters it returns. This would eliminate hardware issues, baud rate as problems.

#include <SoftwareSerial.h>

int pinToPowerOnModule = 8;
int dtr = 7;
int baud_rate = 9600;
int rxpin = 2;
int txpin = 3;
SoftwareSerial testCell(rxpin, txpin);

void setup()
{
  Serial.begin(9600);
  Serial.println("Test started");

  pinMode(pinToPowerOnModule, OUTPUT);
  digitalWrite(pinToPowerOnModule, LOW); // should default to this, but just being careful
  pinMode(dtr, OUTPUT);
  digitalWrite(dtr, LOW);

  testCell.begin(baud_rate);

  digitalWrite(pinToPowerOnModule, HIGH);
  delay(3000);
  digitalWrite(pinToPowerOnModule, LOW);

  testCell.println("AT");
  Serial.println("Command sent");
}

void loop()
{
  if (testCell.available())
  {
    Serial.print("Character received: >>");
    Serial.write(testCell.read());
    Serial.println("<<");
  }
}

Hello.
Your test code work fine and it return reading text between the >> <<.

I also tryed to have the same result using a library and it works

SoftwareSerialTest.ino

#include <Morse.h>
#include <SoftwareSerial.h>

Morse morse(4800);

int pinToPowerOnModule = 8;
int dtr = 7;
int baud_rate = 4800;
int rxpin = 2;
int txpin = 3;


void setup()
{
  Serial.begin(9600);
  Serial.println("Test started");

  pinMode(pinToPowerOnModule, OUTPUT);
  digitalWrite(pinToPowerOnModule, LOW); // should default to this, but just being careful
  pinMode(dtr, OUTPUT);
  digitalWrite(dtr, LOW);

  digitalWrite(pinToPowerOnModule, HIGH);
  delay(3000);
  digitalWrite(pinToPowerOnModule, LOW);

   morse.begin();
}

void loop()
{
  morse.testSerial();
}

Morse.h

#ifndef Morse_h
#define Morse_h

#include "SoftwareSerial.h"
//#include "WProgram.h"

#define RXPIN 2
#define TXPIN 3

class Morse
{
  public:
    Morse(int pin);
    SoftwareSerial _cell;
    void begin(void);
    int baute_rate;
    void testSerial(void);
    
  private:
    int _baute_rate;
};

#endif

Morse.cpp

//#include "WProgram.h"
#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int baute_rate):_cell(RXPIN,TXPIN)
{

  _baute_rate = baute_rate;
}

void Morse::begin(void){
	_cell.begin(_baute_rate);
	_cell.println("AT");
  	Serial.println("Command sent");
}

void Morse::testSerial(void){
	if (_cell.available())
  	{
    Serial.print("Character received: >>");
    Serial.write(_cell.read());
    Serial.println("<<");
  }else{
  	//Serial.println("none");
  }
}

This is the result

noneTest started
Command sent
Character received: >>A<<
Character received: >>T<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>O<<
Character received: >>K<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>C<<
Character received: >>a<<
Character received: >>l<<
Character received: >>l<<
Character received: >> <<
Character received: >>R<<
Character received: >>e<<
Character received: >>a<<
Character received: >>d<<
Character received: >>y<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>
<<
Character received: >>G<<
Character received: >>P<<
Character received: >>S<<
Character received: >> <<
Character received: >>R<<
Character received: >>e<<
Character received: >>a<<
Character received: >>d<<
Character received: >>y<<
Character received: >>
<<
Character received: >>
<<

Would you have a comment?

I was used to use a function the read the return display but it’s mess.
Would you have recommandation to return true when we got “GPS ready”, for exple?

May be I will open a new post and search for a solution

Many thank for your help
Cheers