3

I have a header file called Rhino.h with class Rhino. I want to pass RX and TX pin numbers to this object class, and with this, define a SoftwareSerial object to be used inside the Rhino class. The code in my header file looks like this (there are more number of functions like gotoPos() which I have omitted for brevity purpose):

#include "Arduino.h"

class Rhino
{
public:
    Rhino(int rx,int tx):serial(rx,tx){}

    void gotoPos(int pos)
    {
        serial.write(pos);
    }
private:
    SoftwareSerial serial;
}

And my Arduino code looks like this:

#include <Rhino.h>
Rhino motor1(9,10);
void setup()
{
    motor1.gotoPos(10);
}
void loop() {}

I get this as error:

Arduino: 1.0.6 (Windows NT (unknown)), Board: "Arduino Uno"
S:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -IS:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino -IS:\Program Files (x86)\Arduino\hardware\arduino\variants\standard -IS:\Program Files (x86)\Arduino\libraries\Rhino C:\Users\Samvrit\AppData\Local\Temp\build2516495983752907071.tmp\Test2.cpp -o C:\Users\Samvrit\AppData\Local\Temp\build2516495983752907071.tmp\Test2.cpp.o 

In file included from Test2.ino:6:
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:740: error: 'SoftwareSerial' does not name a type
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In constructor 'Rhino::Rhino(int, int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:16: error: class 'Rhino' does not have any field named 'serial'
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::init()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:21: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::reset()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:30: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::autoCalibrate()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:37: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::sendCmd(String)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:46: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::sendCmd(char*)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:58: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::rotate(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:76: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::stopMotor()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:88: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoPos(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:103: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoAngleDeg(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:123: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoAngleRad(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:143: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoAngleDegC(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:164: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoAngleRadC(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:185: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoRel(long int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:218: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoRelDeg(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:253: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::gotoRelRad(float)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:289: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setSFGain(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:306: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setP(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:322: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setI(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:338: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setD(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:355: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setSpeed(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:372: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setI2CAddr(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:389: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'void Rhino::setPos(int)':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:406: warning: unused variable 'curr_pos'
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:415: warning: unused variable 'curr_pos'
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:426: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getPos()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:474: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'float Rhino::getAngleDeg()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:501: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'float Rhino::getAngleRad()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:528: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getSpeed()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:555: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getRotSpeed()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:582: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getI2CAddr()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:609: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getSFGain()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:636: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getP()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:663: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getI()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:690: error: 'serial' was not declared in this scope
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h: In member function 'int Rhino::getD()':
S:\Program Files (x86)\Arduino\libraries\Rhino/Rhino.h:717: error: 'serial' was not declared in this scope
  • 1
    Put a semicolon (;) after right brace (}) that ends the class def. As noted in a C++ Syntax: class page (at end of Track.h section), “The end of the compound statement ... is followed by a semi-colon [unless defining] a class and an object of that class in a single statement” – James Waldby - jwpat7 Mar 24 '16 at 19:16
2

In your header file, I dont see where you included SoftwareSerial.h; this may be a part of why you got those errors. Also you need to end the class definition with a semi-colon, like you were advised in a comment.

That said, you could just pass a pointer to a SoftwareSerial object to your Rhino constructor. In your library header:

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

class Rhino {
  private:
    SoftwareSerial * serial;

  public:
    Rhino(SoftwareSerial * ss);
    // other prototypes
};

In your .cpp source:

#include "Rhino.h"  // assuming thats what you named the header

Rhino::Rhino(SoftwareSerial * ss){
  serial = ss;
 }

void Rhino::begin(uint32_t baud){
  serial->begin(baud);
}

void Rhino::gotoPos(int pos)
{
  serial->write(pos);  // must use the structure pointer operator
}

In your Arduino sketch:

#include "Rhino.h"
#include <SoftwareSerial.h>

SoftwareSerial ss(2,3);
Rhino rhino(&ss);  // pass a pointer to ss

void setup(){
  rhino.begin(9600);
  rhino.gotoPos(50);
}
  • Thank you. It worked when I included the SoftwareSerial library in my Arduino sketch. Also, I figured that it is better to include the SoftwareSerial.h in the Rhino.h as well, because then the order of including the header files in the Arduino sketch doesn't matter. Otherwise the SoftwareSerial.h should be included BEFORE the Rhino.h library. – samvrit Mar 26 '16 at 7:06
6

Personally I wouldn't go down this route. Instead I would pass a Stream object (as a pointer or a reference) to the constructor and use that. Then it is up to your sketch to define what that Stream object is and initialize it.

That way if you want to use the same class on a hardware UART instead of a SoftwareSerial you just change the sketch, not the library.

So you would initialize as something like this:

SoftwareSerial mySerial(6, 7);
Rhino myRhino(mySerial);

void setup() {
    mySerial.begin(9600);
    myRhino.gotoPos(34);
}

Your Rhino class would look something like this:

class Rhino {
    private:
        Stream *_dev;

    public:
        Rhino(Stream *dev) : _dev(dev) {}
        Rhino(Stream &dev) : _dev(&dev) {}
        void gotoPos(int pos);
};

void Rhino::gotoPos(int pos) {
    _dev->write(pos);
}

The double constructors, one with a pointer and one with a reference, allow the simplicity of passing an object as in the example, or as a pointer, which could be done with the new operator all in one step. I like the way shown in the example though since it is nice and clean.

Of course, because you now have a pointer to your stream object, you need to use the pointer dereference operator instead of the normal .:

_dev->write(pos);

Changing to a hardware UART is then as simple as, for example:

Rhino myRhino(Serial);

Heck, you could even send it through the internet since an Ethernet or WiFi Client is also a Stream object.

  • 2
    that's a very interesting approach. Such infinite knowledge you have sir. – Jonathan Mar 24 '16 at 19:40
  • Thank you. Your method is of course more compatible. However, I have functions in my library which use the begin(), listen() & available() functions, which are not available in Stream class. Also, the Rhino motor that I am trying to operate using this library uses only UART. I solved the issue by including SoftwareSerial.h in both the Arduino sketch and the Rhino.h header file. – samvrit Mar 26 '16 at 7:02
  • Also, I don't want the user to initialize an additional SoftwareSerial object in the Arduino code and then send it to the Rhino library. It's better that the user just sends the pin numbers and everything is taken care in the Rhino library. – samvrit Mar 26 '16 at 7:10
0

You need to import the SoftwareSerial library into your Rhino.h file, since you are using that class in your header file. Perhaps you are also in need of a forward declaration. Inside your Rhino.h file, include SoftwareSerial library, and then above class Rhino, type class SoftwareSerial;. This effectively lets the compiler know that Software Serial is being used. More information on forward declarations can be found here.

Modified Code:

#include "Arduino.h"
#include "SoftwareSerial.h"

class SoftwareSerial; //this might be unnecessary, but doesn't hurt to have it.
class Rhino
{
public:
Rhino(int rx,int tx):serial(rx,tx){}

void gotoPos(int pos)
{
    serial.write(pos);
}
private:
    SoftwareSerial serial;
}
  • Thank you. It did work when I included the SoftwareSerial.h in the Rhino.h. – samvrit Mar 26 '16 at 7:12

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.