Using a selfmade library for serial communication UNO

Hi.
I am new to Arduino and C++. I have seen similar questions asked, but no answers that were either relevant or simple enough for me to understand.

I have an Arduino UNO and I am using VSC on Ubuntu.
I use the integrated Serial to communicate with the computer and I believe I have made a software serial on the digital pins to communicate with a device that I have got, called "modem". I have named the sw serial modemSerial. When I try to download the program I get the following error: src/modem_lib.h:10:5: error: 'modemSerial' was not declared in this scope

My question is how to use serial functions as serial.read and serial.write etc for both the Serial and the modemSerial within modem_lib.h.
The intention is to make my code tidy.

Here is my main.cpp:

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <modem_lib.h>
//#include"computer_lib.h"
//using namespace std;

//create sw-serial
const byte rxPin = 2;
const byte txPin = 3;
SoftwareSerial modemSerial (rxPin, txPin);

void setup()
{
  //start serial comm with computer at baud rate 9600 baud.
  Serial.begin(9600); 
  Serial.println("Serial connection with computer initiated");

  //Configure digital pins as serial  pins
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  modemSerial.begin(9600); //start serial comm with modem at baud rate 9600 baud
  modemSerial.println("Serial connections with modem initiated");


  //Set LED-pin to output
  //pinMode(13, OUTPUT);

}

void loop() 
{
  requestReport();
  //blinkLedFast();
}

Here is the code in modem_lib.h

#include <HardwareSerial.h>

void requestReport() 
{
    modemSerial.write("r");
    delay(1000);
    modemSerial.write("r");
    
    Serial.println("Report requested");
};

There are multiple things wrong with your code.
For a basic guide to breaking larger projects into smaller pieces using .h / .cpp file, see My Post #5 in this Thread.

Hi,

I can't give you hints about using the serial, but I see where the error you get comes from:

With the "#include" statement you include the text in the file. In that case the definition of the function "requestReport".

This function uses the object "modemSerial", but at this time this object is not yet defined, because you only define it some lines later in your main.cpp.

How to fix this?

change your modem_lib.h to this:


void requestReport(SoftwareSerial mySerial)
{
    mySerial.write("r");
    delay(1000);
    mySerial.write("r");
    
    Serial.println("Report requested");
};

In the main program call replace requestReport() by requestReport(modemSerial)

@slartibartfass Thank you! That did solve my problem :slight_smile:

Hi gfvalvo. I've looked at your post and I understand that at least in larger projects it is useful to split into .h and .cpp files if you want your code to be tidy. You say that there are multiple things that are wrong with my code, could you please be more specific, so that I get the opportunity to fix it?

1 Like

First, modem_lib.h should not contain your function's implementation rather (as stated in the guide that I linked), it should only contain the interface spec. The implementation belongs in a .cpp file (again, as stated in the guide that I linked).

Second, your modem_lib code has no idea about the modemSerial object, hence the error message. I'm not sure what you final goal is. But the current modemSerial code is so trivial it's probably no worth breaking it out into its own library. If it were to expand in functionality, I'd restructure it into a class that's passed a Stream reference in the constructor. It all depends on your experience level and ultimate plans.

I agree with @gfvalvo that you need to pass a reference to a Stream object to your library.

The reason for this is that Serial and SoftwareSerial classes are different classes, so if your library expects a reference to a Serial object and you pass a reference to a SoftwareSerial object, it will not compile, and the same problem in reverse.

But Serial and SoftwareSerial share the same parent class which is called Stream. All the functions like .println() are defined by Stream, not by Serial or SoftwareSerial, so there is no problem for your library to use them, whether the object that is given to it is Serial or SoftwareSerial

Thank you @PaulRB and @gfvalvo. The code is quite large, but I am starting over with small pieces to fix errors and improve structure. I understand that my errors here are probably huge and due to my lack of cpp understanding, but I would really appreciate if you would take your time to help me understand what I am doing wrong and how I can make it right. Please look at my code below:

My modem.h:

#include <Arduino.h>

class Modem
{
    public:
        _modem(SoftwareSerial &modemSerial);
        
        void requestReport(_modem);
    
    private:
        SoftwareSerial *modemSerial;
};

My modem.cpp:

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

// Import inctance of class Modem
Modem mdm;

// Request report from modem
void mdm::requestReport()
{
    mdm.write("r");
    delay(1000);
    mdm.write("r");

    return;
}

My main:

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <modem.h>
#include <led.h>
//#include"computer_lib.h"
//using namespace std;

//create sw-serial 
const byte rxPin = 10;
const byte txPin = 11;
SoftwareSerial modemSerial (rxPin, txPin);


void setup()
{
  //start serial comm with computer at baud rate 9600 baud.
  Serial.begin(9600); 
  Serial.println("Serial connection with computer initiated");
  HardwareSerial *SerialPnt = &Serial;

  //Configure digital pins as serial pins
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  modemSerial.begin(9600); //start serial comm with modem at baud rate 9600 baud
  modemSerial.println("Serial connection with modem initiated");
  SoftwareSerial *modemSerialPnt = &modemSerial;


  //Set LED-pin to output
  pinMode(13, OUTPUT);

  //retrieve classes from libraries
  Modem mdm;

}

void loop() 
{
  mdm.requestReport(&modemSerial);

  blinkLedSlow();

}

It will not compile. Error message to the modem.h file:
src/modem.h:8:28: error: '_modem' is not a type
src/modem.h:3:7: error: uninitialized reference member in 'class Modem'

I thought initialized the class name Modem here and do not understand why it should be initialized somewhere else?

Did I not declare _modem as a pointer in __modem(SoftwareSerial &modemSerial); ?

In the main.cpp file I get this error message:
src/main.cpp:34:9: error: use of deleted function 'Modem::Modem()'
src/main.cpp:40:3: error: 'mdm' was not declared in this scope

is this not the way to call a function from the library?

void mdm::requestReport()
{
}

In main I get a red underscore under mdm in the function call to requestReport.

Modem mdm;
Why can I not declare an instance of Modem like this?

First your latest code is incomplete ... where is led.h?

Second, there were so many things wrong that it would take dozens of back and forth posts here to help you get it right. Instead, I provided below a skeletal version that actually compiles. Study it for understanding and ask questions about it.

Modem.h:

#ifndef MODEM_H
#define MODEM_H

#include <Arduino.h>

class Modem{
    public:
        Modem(Stream &s) : stream(s) {}        
        void requestReport();
    
    private:
        Stream &stream;
};

#endif

Modem.cpp:

#include "Modem.h"

// Request report from modem
void Modem::requestReport() {
  stream.write("r");
  delay(1000);
  stream.write("r");
  return;
}

main.ino:

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

//create sw-serial
const byte rxPin = 10;
const byte txPin = 11;
SoftwareSerial modemSerial (rxPin, txPin);
Modem mdm(modemSerial);

void setup() {
  Serial.begin(115200);
  Serial.println("Serial connection with computer initiated");
  modemSerial.begin(9600); //start serial comm with modem at baud rate 9600 baud
}

void loop() {
  mdm.requestReport();
  delay(500);
}

@gfvalvo Thanks a lot! This solved my problem. My code now runs. I have googled Stream, which helped a lot. When I looked at other examples I thought they were using pointers, but I understand that the '&' refers to the assigned address here? Is 'stream' (with the small s) just a name? Or do it have to be the exact syntax? I tried to change it and it did not compile.

Why do you have to declare it both in public and in private?

No. In this case '&' signifies a C++ Reference - that would be a good internet search term.

Yes, it's arbitrary.

Then you did something wrong. Without seeing the code, it's impossible to tell what.

It's not. It's only private:

    private:
        Stream &stream;

BTW, what is your prior experience with Object Oriented Programming and classes? How about coding in general?

I am an intermediate coder in Python, and have touched into go. Just started learning cpp.

As for my stream-naming problem. I have created another set of .h and .cpp files that will handle the Serial stream between the computer and the arduino. Everything else works but my cstream (I tried to name it differently) does not work. Here is my code:

The .h file:

#ifndef COMPUTER_H
#define COMPUTER_H

#include <Arduino.h>

class Computer {
    public:
        Computer(Stream &stream_computer) : cstream(stream_computer){}
        void sendTranspToComputer();
        void recPackFromComputer()

    private:
        Stream &cstream;

};
    
#endif

Extraction from my .cpp file:

void Computer::sendTranspToComputer() {
    for (int i = 0; i < sizeof(transparentPacket); i++) { 
    cstream.write(transparentPacket[i]);
    }
    return;
};

Error message is "identifier cstream is undefined".

Please post the complete code, not extractions. Include the .ino file too.
What is transparentPacket?

The code is allready quite large, and cstream is the only error I get right now.

const byte numTranspBytes = 2;

char transparentPacket[numTranspBytes];

Give it a shot, post it all anyway.

Or, post an MRE. That's the smallest possible complete code that demonstrates the problem at hand and only that problem.

Otherwise, without seeing a complete picture, I'm unable to assist further as the problem is obviously not where you think it is.

Please show a complete error message at least

Thanks a lot for all your support @gfvalvo. You were right: cstream was not the problem. I'm having issues with external variables. But I guess my problems are getting far out of the topic of this thread, so I'll try to figure it out myself or ask on a cpp programming forum. Thank you very much!!

External variables are covered by the post I linked in Post #2.

I'm sure it can be resolved right in this C++ forum.