I want to make a class in cpp for arduino uno that writes on a display. I'm using the LiquidCrystal_I2C library but I can't use it in my class. I know how to do it without a class, but right now I want to build a class and I cant get it to work.
My .h file:
// WriteDisplay.h
#ifndef _WRITEDISPLAY_h
#define _WRITEDISPLAY_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire/Wire.h>
#include <LiquidCrystal_I2C2004V1/LiquidCrystal_I2C.h>
class WriteDisplayClass
{
public:
WriteDisplayClass();
void write(String text);
private:
LiquidCrystal_I2C lcd(0x27,20,4);
};
extern WriteDisplayClass WriteDisplay;
#endif
My .cpp:
#include "WriteDisplay.h"
WriteDisplayClass::WriteDisplayClass()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
}
WriteDisplayClass::write(String text)
{
lcd.clear();
lcd.print(text);
}
WriteDisplayClass WriteDisplay;
My .ino:
#include "WriteDisplay.h"
WriteDisplayClass wdc;
void setup()
{
wdc.write("Hello World");
}
void loop()
{
}
I'm using AtmelStudio with Visual Micro. I'm getting it to work when I'm only using my .ino-file, but I can't do the same thing in cpp. I'm getting errors that LiquidCrystal_I2C.h can't be found and stuff like that. How should I do to get it to work the way I want it to? Or is it even possible?
Thanks for answer.
Sorry I misread the question the first time.
To use libraries in the .cpp file of an Arduino sketch you must also include them in the master .ino file. They are only compiled if found in the .ino
You can add the includes manually or use the "Project>Add/Import Sketch Library" menu item which will add them to the .ino for you.
Based on this post here the problem with your code is related the class being instantiated as global. The problem comes that the compiler doesn't guarantee the order of global variables processing, so in order to guarantee that the object concerning the display is executed lastly after all the library ones, you have to instantiate it in the setup() function!
The solution to your .ino code is to set a global pointer and then you assign the object inside the setup() function, like so:
#include "WriteDisplay.h"
WriteDisplayClass *wdc;
void setup()
{
wdc = new WriteDisplayClass();
wdc->write("Hello World");
}
void loop()
{
}
Related
I have noticed the following code, which is obviously invalid C++, compiles in Arduino IDE (using AVR-GCC):
// The program compiles even when the following
// line is commented.
// void someRandomFunction();
void setup() {
// put your setup code here, to run once:
someRandomFunction();
}
void loop() {
// put your main code here, to run repeatedly:
}
void someRandomFunction() {
}
What is going on here? C++ requires functions to be declared before they are used. When the compiler comes to the line someRandomFunction() in the setup() function, how does it know it will be declared?
This is what we call Forward declaration and in C++ it only requires you to declare the prototype of the function before attempting to use it, instead of defining the whole function.:
Taking as example the following two pieces of code:
CODE A:
#include <Arduino.h>
void setup(){}
void AA(){
// any code here
}
void loop(){
AA();
}
CODE B:
#include <Arduino.h>
void setup(){}
void loop(){
BB();
}
void BB(){
// any code here
}
Strictly speaking C requires that functions be forward declared for the compiler to compile and link them. So in CODE A we do not have declared the function but it defined, which makes it legal for proper C code. But the CODE B has the function definition after the loop, which would be illegal for plain C. A solution would be the following one:
#include <Arduino.h>
void BB();
void setup(){}
void loop(){
BB();
}
void BB(){
// any code here
}
This, however, to fit the Arduino script format of having a void setup() following from a void loop(), required Arduino to include a script on its IDE that automatically looks for functions and generate prototypes up top for you so you do not need to worry about it. So despite being written in C++, you will NOT see Arduino sketches using Forward declaration often in their sketches, as it works out fine and it is often easier to read having first setup() and loop().
Your file is .ino not .cpp. .ino is 'Arduino language'.
The main ino file with additional ino files are processed by the Arduino builder to C++ source and only then processed as C++ (preprocessor, compilation).
I have this problem:
Problem:
I am trying to create a library (ard33WiFi) that manages and handles
a couple of other libraries (WiFiServer library for example)
I need to create the server object that I then use in functions in my Library (ard33WiFi):
WiFiServer myServer(iPort);
The problem is that when I call myServer in the members of the class I get:
'myServer' was not declared in this scope
Where/how do I declare myServer so that is becomes available to the entire class (ard33WiFi)? I have taken out any decleration because whatever I was trying was wrong. I have pasted a skeleton code below.
// HEADER FILE (.h)
// ----------------------------------------------------------------------------------------------
#ifndef Ard33WiFi_h
#define Ard33WiFi_h
#include <WiFiNINA.h>
#include <WiFiUdp.h>
class ard33WiFi{
public:
ard33WiFi(int iPort)
void someFunction();
void serverBegin();
private:
int _iPort;
};
#endif
// ----------------------------------------------------------------------------------------------
// C++ FILE (.cpp)
// -----------------------------------------------------------------------------------------------
#include <Ard33Wifi.h>
ard33WiFi::ard33WiFi(int iPort){
_iPort = iPort;
}
void ard33WiFi::someFunction(){
// code here required to prepare the server for initializing
// but ultimately not relevant to the question
}
void ard33WiFi::serverBegin(){
myServer.begin();
Serial.println("Server Online");
}
I run into the same problem with the UDP library as I need to call the UDP object in various functions to do UDP things.
Any help would be greatly appreciated.
I suppose you are using this:
https://www.arduino.cc/en/Reference/WiFiServer
I can see that you are not declaring the myServer in your class; that I guess is the error in your code. If I am not wrong, it should be something like this:
#ifndef Ard33WiFi_h
#define Ard33WiFi_h
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <WiFi.h> // Not sure if you have to append this include
class ard33WiFi{
public:
ard33WiFi(int iPort)
void someFunction();
void serverBegin();
private:
int _iPort;
WiFiServer myServer;
};
#endif
The implementation, you would need to initialise the instance:
#include <Ard33Wifi.h>
ard33WiFi::ard33WiFi(int iPort):myServer(iPort), _iPort(iPort) {
}
void ard33WiFi::someFunction(){
// code here required to prepare the server for initializing
// but ultimately not relevant to the question
}
void ard33WiFi::serverBegin(){
myServer.begin();
Serial.println("Server Online");
}
I am having much trouble learning to use files for classes in C++. To learn I use Bucky Roberts/The New Boston C++ tutorials, I have tried exactly what he does, but it does not work.
I have the main.cpp and the OtherClass.cpp with the OtherClass.h for header. Every time I try doing OtherClass::OtherClass(){} for the constructor it errors out with "C++ requires a type specifier for all declarations"
Could someone give me an example of how to do C++ class files correctly? Really confused right now.
Thanks!
A simple example of using header files for classes (with the implementation in a separate .cpp file) looks something like this:
Your main.cpp file:
#include "OtherClass.h"
int main()
{
OtherClass otherClass;
//use otherClass here...
}
Next, your OtherClass.h file:
class OtherClass
{
public:
OtherClass();
int someFunction(int parameters);
};
And then finally your OtherClass.cpp file:
#include "OtherClass.h"
OtherClass::OtherClass()
{
//implementation here
}
int OtherClass::someFunction(int parameters)
{
//implemenation here
return 0;
}
The main things to keep in mind:
#include "OtherClass.h" goes in both OtherClass.cpp and main.cpp
make sure you finish constructor and function declarations with ';' not '{}' if you are defining the implementation elsewhere.
make sure you're compiling OtherClass.cpp as well as main.cpp. With MinGW this looks like g++ main.cpp OtherClass.cpp
Your question is a little cryptic to understand, but if I understand correctly you're looking for the `correct' way to create classes with interfaces in the header file. Here is an example of a class that does this:
Scene.h
#pragma once
#include "Window.h"
#include "Entity.h"
class Scene
{
public:
Scene(Window *_window);
~Scene(void);
void render(Entity item);
void render(Entity item, SDL_Rect *clip);
protected:
Window *window;
};
Scene.cpp
#include "Scene.h"
Scene::Scene(Window *_window)
{
window = _window;
}
Scene::~Scene(void)
{
}
void Scene::render(Entity item) {
render(item, NULL);
}
void Scene::render(Entity item, SDL_Rect *clip) {
window->draw( item.getImage(), item.getCoordinates(), clip, item.getAngle() );
}
Notice that the header file includes the headers that it needs to link properly, while the implementation file (.cpp) just includes the header file. The linker should automatically manage all this trouble for you as long as you stick to these semantics.
I hope this helps; if it doesn't, consider rephrasing your question or pasting some code.
I have some code that I wanted to put into a library which uses another library, SoftwareSerial. Now I added the SoftwareSerial.h and SoftwareSerial.cpp files to the same folder as the library I'm creating.
My header file looks something like this:
#ifndef MyLibrary_h
#define MyLibrary_h
#include "Arduino.h"
#include "SoftwareSerial.h"
#define MyLibrary_VERSION 1 // software version of this library
//DEFINE ALL CLASS VARIABLES
#define DATA_BUFFER_SIZE 50 //soft serial has 63 byte buffer.
class MyLibrary
{
public:
MyLibrary(uint8_t port_in, uint8_t port_out);
float getSomeValue(uint8_t some_index);
private:
SoftwareSerial _serial;
//Not sure if I should add the constructors below to the above declaration.
//(uint8_t in_pin=4, uint8_t out_pin=5, bool logic_reversed = false);
float convertSomeValue(byte upperbyte, byte lowerbyte);
void flushSerialBuffer();
};
#endif
My .cpp file looks like this:
#include "Arduino.h"
#include "MyLibrary.h"
#include "SoftwareSerial.h"
MyLibrary::MyLibrary(uint8_t in_pin, uint8_t out_pin)
{
bool logic_reversed = false;
this->_serial(in_pin*, out_pin*, logic_reversed);
//I tried the declaration below as well.
//SoftwareSerial _serial(in_pin*, out_pin*, logic_reversed);
}
float MyLibrary::getSomeValue(uint8_t sensor_index) {
float someValue = 1.1;
return someValue;
}
float MyLibrary::convertSome(byte upperbyte, byte lowerbyte) {
float someValue = 0.9;
return someValue;
}
void MyLibrary::flushSerialBuffer() {
//Flush serial buffer
while(_serial.available())
char c = _serial.read();
}
I would like SoftwareSerial to be a private field in MyLibrary (preferably static but not necessary) but I've tried many was of declaring it but nothing seems to work. I keep getting errors like no matching function for call to 'SoftwareSerial::SoftwareSerial() or invalid use of qualified-name 'MyLibrary::_serial'.
I got it to compile fine once by declaring static SoftwareSerial _serial; in my .h file, and SoftwareSerial MyLibrary::_serial(4,5,false); at the top of my .cpp file. The thing is, I would like to set the ports of _serial in my constructor for MyLibrary (so I can create a MyLibrary that uses specific in/out pins for SoftwareSerial) and not have them explicitly declared at the top of the .cpp file.
I'm not so familiar with C coding and Arduino so it would be a great help if someone could explain to me how to declare these properly in the .h file and instanciate them with the correct ports in the MyLibrary constructor or a MyLibrary.begin() function (or something of the like).
Thanks in advance for you helpful comments.
What you need is to make your constructor do the initialization as follows:
class MyLibrary{
public:
MyLibrary(uint8_t, uint8_t);
//...
private:
SoftwareSerial _serial;
//...
};
MyLibrary::MyLibrary(uint8_t in, uint8_t out)
: _serial(in, out)
{
//do initialization
}
This syntax might seem strange at first, but although it isn't quite as pretty, it clearly differentiates initialization of variables vs operations on variables, which is something that placing the initialization in the body of the constructor can make slightly fuzzy. As a rule, UNLESS you use this syntax to initialize a member variable, C++ will call the default constructor, which will cause a compile error iff the member does not have a callable default constructor.
I'm trying to do Serial.println() within a class in the Arduino IDE. However, the compiler is saying that Serial was not declared in this scope. Here is the code:
Code in Menu.h
class Menu
{
public:
int options[4];
void test() {
Serial.println("here");
}
private:
};
Code in main file:
#include "Menu.h"
Menu menu;
void setup() {
Serial.begin(9600);
menu.test();
}
void loop() {
}
The right #include is probably added automatically by Arduino to your .pde. Try #include <WProgram.h> in the top of your Menu.h.
I'm not sure if the code snippet is complete (if it isn't, please post a complete one) but it looks like you forgot to include the appropriate header file which declares the class Serial.