7

I have done quite a few projects with Arduino, but have never done more than a "Hello World" in C. I am writing my first library, and a lot of the object oriented stuff is going over my head. Anyway, my library is working as it is supposed to, I pass a float to my function and it formats it properly and sends it out over serial. However, I implemented it in a clunky way. The Arduino API Style Guide mentions a way that seems much better:

When using serial communication, allow the user to specify any Stream object, rather than hard-coding "Serial". This will make your library compatible all serial ports on Mega and the Due, and can also use alternate interfaces like SoftwareSerial. The Stream object can be passed to your library's constructor or to a begin() function (as a reference, not a pointer). See Firmata 2.3 or XBee 0.4 for examples of each approach.

Can anybody elaborate on how to do this, or show me some code?

9

Here is a simple example (built and tested with a mega2560), with a class that can be passed a Stream object, and sends a Hello over this generic stream object. When constructing the object, you can pass the Stream object you want to actually communicate:

#include "Arduino.h"

class MyProtocol
{
public:
    MyProtocol(Stream& s):serial(s){}
    void send(){
        serial.println("Hello");
    }
private:
    Stream& serial;
};

MyProtocol p(Serial);

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

void loop() {
    delay(1000);
    p.send();
}

NOTE: The serial.println() is not the Serial global object, note the lower case, it is the internal Stream class variable.

If you are confused with the OO and classes, take into account (while you gain more knowledge about it) that this approach can be also used with a simple function, you can pass the serial parameter. Furthermore, it is not necessary to hardwire the Serial interface for ever, you can in fact switch in run time and use a different channel depending on some condition:

#include "Arduino.h"

void send(Stream& serial){
    serial.println("Hello");
}

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

void loop() {
    delay(1000);
    if(someCondition)
        send(Serial);
    else
        send(Serial1);
}
  • You can also declare the constructor as MyProtocol(Stream& s=Serial):serial(s){} sou you don't need to pass the Serial but you can if you want to. You would build then build the object just as MyProtocol p; – hithwen Mar 27 '14 at 8:51
  • Thanks, this was really helpful, it took some work but I figured it out. You can see the result on my Github. – ahalekelly Mar 28 '14 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.