Go Down

Topic: serial port number to constructor (Read 1 time) previous topic - next topic

Yot

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
Code: [Select]
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
Code: [Select]
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

halley

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.

Spinlock

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

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

Code: [Select]
private:
 Serial *pSerial;


And in the definition:

Code: [Select]
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:

Code: [Select]
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...

Yot

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

Yot

#4
Dec 05, 2009, 10:15 am Last Edit: Dec 05, 2009, 11:10 am by Yot Reason: 1
hmmmmm, Compiler starts with an error
Quote
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? :)

PaulS

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.

Yot

Ok then.

The .h file;
Code: [Select]
#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;
Code: [Select]
#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;
Code: [Select]
#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

AlphaBeta

Serial is no type, try HardwareSerial  :)

Spinlock

Oh right...

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

Yot

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
Code: [Select]
#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
Code: [Select]
#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.
Code: [Select]
#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.
Quote
error: request for member 'pSerial' in 'this', which is of non-class type 'uOLED* const'

Quote
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

PaulS

What happens if you add

Code: [Select]
#include <HardwareSerial.h>

to your class' header file?

Yot

Thanks for your time PaulS.

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

Jeroen

AlphaBeta

#12
Dec 08, 2009, 01:27 pm Last Edit: Dec 08, 2009, 01:30 pm by AlphaBeta Reason: 1
this.pSerial = serialToUse;

must be:
this->pSerial = serialToUse;
or
pSerial = serialToUse;

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

Yot

After AlphaBeta's hint the compiler changed his errors. It had something to complain about
Quote
error: call of overloaded 'write(byte*&)' is ambiguous

After some fiddling i've changed
Code: [Select]
write(byte *pData); in the .h and .cpp files to
Code: [Select]
write(byte pData); and the errors disappeared. That went well i thought so i've made
Code: [Select]
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
Code: [Select]
#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
Code: [Select]
#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
Code: [Select]
#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

Yot

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

Go Up