serial port number to constructor

Hi all,

I have a serial device (small oled display) that is connected to Serial1 port on an Arduino Mega. I also have a library that i use to show text etc. on that display. To start using the library i call a constructor in the following way
uOLED uoled(8,256000); reset pin connected to pin 8 on arduino and using a serial speed of 256K. In the constructor the arduino resets the screen, starts a serial port and does the init sequence to start up the screen. The serial port to use is hardcoded in the library. (a lot of Serial1.write() and so on) So far so good, working as intended.

What i would like however is that in the constructor i can pass a number for which serial port to use. For example
uOLED uoled(8,256000, 1); and that the constructor uses the ‘1’ to open the serial1 port.

Has anyone got an idea/tip on how to accomplish this?

regards,

Jeroen

You'd have to modify the library that implements the constructor. There are two ways, but both may need the library to be changed.

Simplest: modify the library code to accept another argument in the constructor, and to use that argument to decide which serial port in the internal logic.

Possible alternative: derive a new class from the library's class. That constructor takes the extra argument, but calls the library without it. Whenever doing any operation, manipulate the variable that the library is depending on to know which serial port to use. If the library has no such variable (say, the constant 1 appears all over the place), then this approach won't be useful.

If you have the source code to the library, modify it like this:

In the declaration (header) of the class, do this:

private:
  Serial *pSerial;

And in the definition:

uOLED::uOLED(int pin,int Baud, Serial *serialToUse)
{

   // save the port in the class.
    this.pSerial = serialToUse;
}

void uOLED::write(byte *pData)
{
     this.pSerial->write(pData);
}

and construct it like:

uOLED uoled(1, 567000, &Serial1);

In your library, call your class member's write to write data, instead of Serialxxx.write();

If you don't own the source to the library and cannot change the class like that you can't really proceed like this though...

Thanks for the tips all,

I am 'in control of the source' so to speak so that won't be a problem. I'll post the results when i figured it out/have additional questions.

Back to making dinner. :)

Jeroen

hmmmmm, Compiler starts with an error

error: 'Serial' is not a type error: ISO C++ forbids declaration of 'Serial' with no type

Spinlock; That technique you explained, what is the description of that? So that i could read up/ ask google about it.

Jeroen

edit; or anyone else for that matter? :)

Post the code that contains the error.

Without seeing the code, we'd only be guessing, but it looks like the code that causes the error needs to have the Serial.h file #included, but it doesn't, so it has no idea that Serial is a class.

Ok then.

The .h file;

#include "WProgram.h"

#ifndef newoled_h
#define newoled_h

class uOLED
{
  public:
    uOLED (int pin, long baud, Serial *serialToUse);
                  
    //internal variables
    int PinReset;                     //Pin that send Reset signal
    long BRate;                            //serial Baud Rate 
    char res;                            //Result for every command
                      
    // Basic control for uOLED
    void StartUp(void);
    void Cls(void);
    
    // Basic Graphics
    void Line(char x1, char y1, char x2, char y2, unsigned int color);
    
  private:
    Serial *pSerial; 
    write(byte *pData);
    char RBack(void);
};

#endif

The .cpp file;

#include "newoled.h"
#include "WProgram.h"

#define SerialSOMETHING Serial1    // ugly way to change serial port used

//CONSTRUCTOR
uOLED::uOLED(int pin, long baud, Serial *serialToUse)
{
  // save the port in the class.
  this.pSerial = serialToUse;
  
  PinReset=pin;
  pinMode(PinReset, OUTPUT);
  BRate = baud;
}

void uOLED::write(byte *pData)
{
     this.pSerial->write(pData);
} 


//Make a Reset for uOLED and Clear Screen
void uOLED::StartUp()
{
  //Reset display
  digitalWrite(PinReset,LOW);
  delay(20);
  digitalWrite(PinReset,HIGH);
  delay(7000);                     // If you want to see the startup animation change this to something well above 5000
  SerialSOMETHING.begin(BRate);
  //Send 0x55 to stablish baud rate for serial communication
  write(0x55);

  res=RBack();

  Cls();
}

//Obtain result for every command that send Arduino to uOLED
char uOLED::RBack()
{
  // Wait for serial data 
  while (!SerialSOMETHING.available()) 
    { 
     // do nothing 
    }
  return SerialSOMETHING.read();
}

//Erase Screen
void uOLED::Cls()
{
  write(0x45);
  res=RBack();  
}

//Draw a line
void uOLED::Line(char x1, char y1, char x2, char y2, unsigned int color)
{
  write(0x4C);
  write(x1);
  write(y1);
  write(x2);
  write(y2);
  write(color >> 8);            
  write(color & 0xFF);
  res=RBack();
}

And the sketch;

#include "newoled.h"

uOLED uoled(8,256000, &Serial1);          // create an instance of the uOLED class with the reset line connected to pin 8 and a serial speed of 256000

void setup() {
  uoled.StartUp();              // reset and initialize the display
  uoled.Cls();                  // clears the screen of everything on it. It uses the background color   
  uoled.Line(0, 0, 100, 100, 65000);
}

void loop() {
  
}

Thanks in advance,

Jeroen

Serial is no type, try HardwareSerial :)

Oh right...

I should have checked that; I am used to things like HardwareSerial and SoftwareSerial inheriting a base Serial class.

Unfortunately still no success. Main issue is probably that i’m using a technique that i dont understand. Here is the code so far.

.h file

#include "WProgram.h"

#ifndef newoled_h
#define newoled_h

class uOLED
{
  public:
    uOLED (int pin, long baud, HardwareSerial *serialToUse);
                  
    //internal variables
    int PinReset;                     //Pin that send Reset signal
    long BRate;                            //serial Baud Rate 
    char res;                            //Result for every command
                      
    // Basic control for uOLED
    void StartUp(void);
    void Cls(void);
    
    // Basic Graphics
    void Line(char x1, char y1, char x2, char y2, unsigned int color);
    
  private:
    HardwareSerial *pSerial; 
    write(byte *pData);
    char RBack(void);
};

#endif

.ccp

#include "newoled.h"
#include "WProgram.h"

#define SerialSOMETHING Serial1    // ugly way to change serial port used

//CONSTRUCTOR
uOLED::uOLED(int pin, long baud, HardwareSerial *serialToUse)
{
  // save the port in the class.
  [glow]this.pSerial = serialToUse;[/glow]  // <- highlighted after compiling
  
  PinReset=pin;
  pinMode(PinReset, OUTPUT);
  BRate = baud;
}

void uOLED::write(byte *pData)
{
     this.pSerial->write(pData);
} 


//Make a Reset for uOLED and Clear Screen
void uOLED::StartUp()
{
  //Reset display
  digitalWrite(PinReset,LOW);
  delay(20);
  digitalWrite(PinReset,HIGH);
  delay(7000);                     // If you want to see the startup animation change this to something well above 5000
  SerialSOMETHING.begin(BRate);
  //Send 0x55 to stablish baud rate for serial communication
  write(0x55);

  res=RBack();

  Cls();
}

//Obtain result for every command that send Arduino to uOLED
char uOLED::RBack()
{
  // Wait for serial data 
  while (!SerialSOMETHING.available()) 
    { 
     // do nothing 
    }
  return SerialSOMETHING.read();
}

//Erase Screen
void uOLED::Cls()
{
  write(0x45);
  res=RBack();  
}

//Draw a line
void uOLED::Line(char x1, char y1, char x2, char y2, unsigned int color)
{
  write(0x4C);
  write(x1);
  write(y1);
  write(x2);
  write(y2);
  write(color >> 8);            
  write(color & 0xFF);
  res=RBack();
}

Sketch used.

#include "newoled.h"

uOLED uoled(8, 256000, &Serial1);          // create an instance of the uOLED class with the reset line connected to pin 8 and a serial speed of 256000

void setup() {
  uoled.StartUp();              // reset and initialize the display
  uoled.Cls();                  // clears the screen of everything on it. It uses the background color   
  uoled.Line(0, 0, 100, 100, 65000);
}

void loop() {
  
}

and the errors after compiling.

error: request for member ‘pSerial’ in ‘this’, which is of non-class type ‘uOLED* const’

C:\DOCUME~1\jeroen\LOCALS~1\Temp\build24003.tmp/newoled.h:25: error: ISO C++ forbids declaration of ‘write’ with no type

In constructor ‘uOLED::uOLED(int, long int, HardwareSerial*)’:
error: request for member ‘pSerial’ in ‘this’, which is of non-class type ‘uOLED* const’ At global scope:
In member function ‘void uOLED::StartUp()’:
In member function ‘void uOLED::Cls()’:
In member function ‘void uOLED::Line(char, char, char, char, unsigned int)’:

Jeroen

What happens if you add

#include <HardwareSerial.h>

to your class’ header file?

Thanks for your time PaulS.

Exact the same error is spitted. With the same line highlighted in my previous post.

Jeroen

this.pSerial = serialToUse;

must be:

this->pSerial = serialToUse;

or

pSerial = serialToUse;

this is a pointer to the instance, it is not the instance. :)

After AlphaBeta’s hint the compiler changed his errors. It had something to complain about

error: call of overloaded ‘write(byte*&)’ is ambiguous

After some fiddling i’ve changed write(byte *pData); in the .h and .cpp files to write(byte pData); and the errors disappeared. That went well i thought so i’ve made

void begin(long BaudRate);
boolean available(void);
int read(void);

in the .h and .cpp files. Still no error from the compiler but now the display won’t initialize.

The files are now like this; .h

#include "WProgram.h"

#ifndef newoled_h
#define newoled_h

class uOLED
{
  public:
    uOLED (int pin, long baud, HardwareSerial *serialToUse);
                  
    //internal variables
    int PinReset;                     //Pin that send Reset signal
    long BRate;                            //serial Baud Rate 
    char res;                            //Result for every command
                      
    // Basic control for uOLED
    void StartUp(void);
    void Cls(void);
    
    // Basic Graphics
    void Line(char x1, char y1, char x2, char y2, unsigned int color);
    
  private:
    HardwareSerial *pSerial; 
    void write(byte pData);
    void begin(long BaudRate);
    boolean available(void);
    int read(void);
    char RBack(void);
};

#endif

.cpp

#include "newoled.h"
#include "WProgram.h"

//CONSTRUCTOR
uOLED::uOLED(int pin, long baud, HardwareSerial *serialToUse)
{
  // save the port in the class.
  pSerial = serialToUse;
  
  PinReset=pin;
  pinMode(PinReset, OUTPUT);
  BRate = baud;
}

void uOLED::write(byte pData)
{
     pSerial->write(pData);
} 

void uOLED::begin(long BaudRate)
{
     pSerial->begin(BaudRate);
} 

boolean uOLED::available()
{
     pSerial->available();
} 

int uOLED::read()
{
     pSerial->read();
} 

//Make a Reset for uOLED and Clear Screen
void uOLED::StartUp()
{
  //Reset display
  digitalWrite(PinReset,LOW);
  delay(20);
  digitalWrite(PinReset,HIGH);
  delay(7000);                     // If you want to see the startup animation change this to something well above 5000
  begin(BRate);
  //Send 0x55 to stablish baud rate for serial communication
  write(0x55);

  res=RBack();

  Cls();
}

//Obtain result for every command that send Arduino to uOLED
char uOLED::RBack()
{
  // Wait for serial data 
  while (!available()) 
    { 
     // do nothing 
    }
  return read();
}

//Erase Screen
void uOLED::Cls()
{
  write(0x45);
  res=RBack();  
}

//Draw a line
void uOLED::Line(char x1, char y1, char x2, char y2, unsigned int color)
{
  write(0x4C);
  write(x1);
  write(y1);
  write(x2);
  write(y2);
  write(color >> 8);            
  write(color & 0xFF);
  res=RBack();
}

and the sketch

#include "newoled.h"

uOLED uoled(8, 256000, &Serial1);          // create an instance of the uOLED class with the reset line connected to pin 8 and a serial speed of 256000

void setup() {
  uoled.StartUp();              // reset and initialize the display
  uoled.Cls();                  // clears the screen of everything on it. It uses the background color   
  uoled.Line(0, 0, 100, 100, 65000);
}

void loop() {
  
}

Jeroen

As always; it's in the details....

The functions int uOLED::read() and boolean uOLED::available() did not return anything because i did not add the word "return" in them.

Thanks for your help all.

Jeroen