Go Down

Topic: Hardware Serial Port Referencing (Read 672 times) previous topic - next topic

NobleNoob

Dec 25, 2012, 01:58 am Last Edit: Dec 25, 2012, 03:00 am by NobleNoob Reason: 1
Hey All :)

I am trying to figure out how to use references with the hardware serial ports.

// File: sketch.ino

#include <Arduino.h>
#include <TestSerial.h>

TestSerial testSerial(Serial);

void setup() {
 Serial.begin(9600);
}

void loop() {
 if (Serial.available() > 0) {
   byte iByte = Serial.read();
     testSerial.sayit();
 }
}

// File: TestSerial.h
#ifndef TestSerial_h
#define TestSerial_h

class TestSerial {
 private:
    // Here is where I want to declare whatever it is I need to declare to get the reference supplied by the constructor
    // but I have no idea what to do.  I have tried:
    HardwareSerial& privateSerial;  
    // Which generates a compiler error cannot convert 'HardwareSerial' to 'HardwareSerial*' in assignment

 public:
   TestSerial(HardwareSerial& localSerial);
   void sayit();
};

#endif

// File: TestSerial.cpp

#include <Arduino.h>
#include <TestSerial.h>

TestSerial::TestSerial(HardwareSerial& localSerial) {
 // Here is where I want to put the reference 'localSerial' into the 'privateSerial'
 // I tried:
 privateSerial = localSerial; - No go because of compiler error
}

void TestSerial::sayit() {
 privateSerial.println("HELLO WORLD!");
}

Any ideas?

johnwasser

I think you can use a pointer to Print for output to a hardware or software serial port:

Code: [Select]

Print *myPort;

SoftwareSerial mySoftSerial(2,3);

myPort = Serial1;
myPort = mySoftSerial;

myPort->println("Hello, world.");


For input I think you may need a Stream pointer instead.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Nick Gammon

#2
Dec 25, 2012, 04:02 am Last Edit: Dec 25, 2012, 04:06 am by Nick Gammon Reason: 1
Change TestSerial.h to read:


Code: [Select]
#ifndef TestSerial_h
#define TestSerial_h

class TestSerial {
 private:
    HardwareSerial& privateSerial;  

 public:
   TestSerial(HardwareSerial& localSerial) : privateSerial (localSerial) { }
   void sayit();
};

#endif


And remove the constructor from TestSerial.cpp.

NobleNoob

Ok, that last suggestion works wonderful for a single reference, but...

What if I wanted to have the constructor deal with multiple hardware serial port references?

And could I get them into an array?

class MyClass {
    private:
        HardwareSerial&   portA;
        HardwareSerial&   portB;
        HardwareSerial&   portC;
        HardwareSerial&   portD;

        // What about
        HardwareSerial&   ports[4];


  public:
        MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial sRefD)


};


That's as far as I have gotten, need further direction....


PaulS

Quote
And could I get them into an array?

Define the array correctly, and assign the instances one at a time.

What about that declaration? Didi it compile? Did the assignments in the constructor work? Did the array access then work?

Nick Gammon

Example code from an earlier thread:

Code: [Select]

class myMenu
  {
  private:
    Stream & port_;
  public:
    myMenu (Stream & port) : port_ (port) { }
    void begin ();
  };

void myMenu::begin ()
  {
  port_.println ("Menu initialized.");
  }

myMenu menu (Serial);

void setup ()
  {
  Serial.begin (115200);
  menu.begin ();
  }  // end of setup

void loop () { }

NobleNoob

I thank you guys for being patient with me, however, I am still a little stumped.

I need my class to contain all 4 hardware serial ports as references so that I can work with them locally inside the class.

Your example for a single reference worked fine for a singe serial port reference.

How do I get the constructor to deal with all of the references I pass to it?

IE:

// Header file

class MyClass {
   private:
      HardwareSerial&   portA, portB, portC, portD;

   public:
       MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) {
                // How to assign the references passed to the constructor to the local class objects?
                //
        }


// Or deal with them in the source file constuctor...

// Source file
#include <MyClass.h>

MyClass::MyClass(HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) {
      portA = sRefA;       // Does not work
      portB = sRefB;
      portC = sRefC;
      portD = sRefD;

}



Nick Gammon

Time to start using code tags.

How to use this forum

You use the initialization list syntax which my example showed. This compiles:

Code: [Select]

class MyClass
  {
  private:
    HardwareSerial&   portA, portB, portC, portD;
 
  public:
    // constructor
    MyClass (HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD);
  };

MyClass::MyClass (HardwareSerial& sRefA, HardwareSerial& sRefB, HardwareSerial& sRefC, HardwareSerial& sRefD) :
  // initialization list
  portA (sRefA), portB (sRefB), portC (sRefC), portD (sRefD)
  {
    // other code
  }

MyClass foo (Serial, Serial1, Serial2, Serial3);

void setup () { }
void loop () { }

NobleNoob

Thank you ever so much!  This works perfectly!

I am not quite sure what is happening, but it works and for now that's all that matters.

Again, thank you for your help!

and thank you for pointing out the code blocks pointer, I was wondering how you guys did that :)

Go Up