Use Pointer or Reference to Serial or SoftwareSerial in Library

Hello,

Before i start i would like to say i have searched and found various similar topics.

I have followed the advice in those and other topics here and in other parts of the web but I’m still having trouble.

I have been using and extending this library for my project (and will do in future ones):
http://codeandlife.com/2013/02/03/piserial-arduino-communication-library/#more-1219
It’s rather neat and was a great staring point but i have got to point where i would like to extend it to use both Software or Hardware serial.

Now obviously i can duplicate the library and replace Serial with SoftwareSerial and that would work but it seems ridiculous to have two practically identical library’s and use them both a the same time.
I have been trying to get the library to take ether object and i was having trouble with that so i stripped it back to just taking a Serial object and i cant even get that to work!

I’ve tried al-sorts, pointers, references, initializing in the constructor etc.
here is all simple test code I’m using (hardly changed from the original codeandlife example).
also ive commented out all the softserial stuff for the moment.

h file:

/*

 PiSerial - a simple binary serial communication module

 This library utilizes Serial library to implement easy
 serial communications with another device, such as Raspberry Pi.
 See CodeAndLife.com for details.

 License: Public domain

 (C) Copyright 2013 Joonas Pihlajamaa

 */

#ifndef __PISERIAL_H
#define __PISERIAL_H

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

class PiSerial {
private:
	char nextCommand; // set to non-zero when command received during paramXXX calls
	//SoftwareSerial *_softSerial;
	HardwareSerial *_hardSerial;
	int serialAvailable();
	int serialRead();
	bool serialMode;

public:
	PiSerial();
	~PiSerial();
	//void init(SoftwareSerial  *_serial);
	void init(HardwareSerial *_serial);

	char getCommand();
	
	int paramHex();
	int paramByte();
	int paramInt();
	
	void endCommand();
	
	int isError();
	
	void sendOK();
	void sendError();
};

#endif

cpp file:

 /*

 PiSerial - a simple binary serial communication module

 This library utilizes Serial library to implement easy
 serial communications with another device, such as Raspberry Pi.
 See CodeAndLife.com for details.

 License: Public domain

 (C) Copyright 2013 Joonas Pihlajamaa

 */
 
#include "PiSerial.h"


PiSerial::PiSerial(){
	nextCommand = 0;
	_hardSerial = NULL;
}


PiSerial::~PiSerial() {

}

void PiSerial::init(HardwareSerial *_serial) {
	serialMode = 0;
	_hardSerial = _serial;
}

/*
PiSerial::PiSerial(SoftwareSerial *_serial){
	nextCommand = 0;
	_softSerial = _serial;
}

void PiSerial::init(SoftwareSerial *_serial) {
	serialMode = 1;
	_softSerial = _serial;
}


int serialAvailable(){
	if (!serialMode) {
		return _softSerial->available();
		
	}else {
		return _hardSerial->available();
	}
}

int serialRead(){
	if (!serialMode) {
		return _softSerial->read();
		
	}else {
		return _hardSerial->read();
	}
}
*/

int serialAvailable(){
	if (!serialMode) {
		return 0 ;//_softSerial->available();
		
	}else {
		return _hardSerial->available();
	}
}

int serialRead(){
	if (!serialMode) {
		return 0;//_softSerial->read();
		
	}else {
		return _hardSerial->read();
	}
}



char PiSerial::getCommand() {
	int cmd;
	
	if(nextCommand) { // command received during paramXXX() calls
		cmd = nextCommand;
		nextCommand = 0; // clear error state now that we process command
	} else if(!serialAvailable()) {
		return 0; // no command available
	} else 
		cmd = serialRead();
	
	if(cmd < 'a' || cmd > 'z') // not a valid command
		return 0;
	
	return cmd;
}

int PiSerial::paramHex() {
	int ch;
	
	if(isError()) // don't read more if error state
		return 0;
	
	while(!serialAvailable()) {} // wait for character
	
	ch = serialRead();
	
	if(ch >= '0' && ch <= '9')
		return ch - '0';
	else if(ch >= 'A' && ch <= 'F')
		return ch - 'A' + 10;
	
	// not a valid HEX, assume it's a command
	nextCommand = ch; // enter error state, store potential command
	return 0;
}

int PiSerial::paramByte() {
	return (paramHex() << 4) + paramHex();
}

int PiSerial::paramInt() {
	return (paramByte() << 8) + paramByte();
}

void PiSerial::endCommand() { // consume \r\n or \n after a command and parameters
	int ch;
	
	if(isError()) // don't read more if error state
		return;
	
	while(!serialAvailable()) {} // wait for character
	ch = serialRead();
	
	if(ch == '\r') {
		while(!serialAvailable()) {} // wait for character
		ch = serialRead();
	}
	
	if(ch != '\n')
		nextCommand = ch; // enter error state, store potential command
}

int PiSerial::isError() {
	return nextCommand; // nonzero when paramXXX() commands failed
}


void PiSerial::sendOK() {
	_hardSerial->print("OK");
	
}

void PiSerial::sendError() {
	_hardSerial->print("RR");
}

/*
void PiSerial::sendOK() {
	if (!serialMode) {
		_softSerial->print("OK");
	}else {
		_hardSerial->print("OK");
	}
}

void PiSerial::sendError() {
	if (!serialMode) {
		_softSerial->print("RR");   
	}else {
		_hardSerial->print("RR");
	}
}
*/

ino file:

#include "PiSerial.h"
#include "Wire.h"
//#include <SoftwareSerial.h>


PiSerial piSerial;


void setup(){
  Serial.begin(9600);
  delay(1000);
  piSerial.init(&Serial);
}


void loop() {
  int param;

  // read command and process
  switch(piSerial.getCommand()) {
  case 0: // non-command character
    break; // ignore

  case 'c': // command 'c' received
    param = piSerial.paramHex(); // one hex parameter
    piSerial.endCommand(); // end of command

    if(!piSerial.isError()) {
      digitalWrite(13, (param ? HIGH : LOW));
      piSerial.sendOK();
    } else
      piSerial.sendError();
    break;

  default: // Unknown command
    piSerial.sendError();
  }

}

with the code in this state i have the least errors, which are:
PiSerial.cpp: In function ‘int serialAvailable()’:
PiSerial.cpp:65: error: ‘serialMode’ was not declared in this scope
PiSerial.cpp:69: error: ‘_hardSerial’ was not declared in this scope
PiSerial.cpp: In function ‘int serialRead()’:
PiSerial.cpp:74: error: ‘serialMode’ was not declared in this scope
PiSerial.cpp:78: error: ‘_hardSerial’ was not declared in this scope

What have i missed?
Any help would be greatly appreciated.
Thanks.

Prefix the function with the class name like you have on the other functions.

Also instead of using a pointer/reference to the HardwareSerial object, You can use the Stream object. Or if you only send data, the Print object ( Serial inherits both. )

An example of inheriting print: http://forum.arduino.cc/index.php?topic=200975.msg1481633#msg1481633 In the above example, Print can be replaced with Stream.

Wow how did I miss something so simple (total face palm moment). I was going around in circles with that one. All is working now and I can pass both soft and hardware serial with no problems (so far). it's great to have another pair of eyes on these things, some times you just cant see what's right in front of you!

Thanks for your help it's much appreciated.