1

I'm struggling to learn Arduino's C++ right now. I'm trying to write a simple wrapper so I can use multiple OLED's on my project. Here is what I've got so far :

class Screen
{
  private:
    Adafruit_SSD1306 display;
    unsigned long startTime = 0;

  public :
    Screen(){
       Adafruit_SSD1306 this->display(128, 64, &Wire, -1);
    }
    void init(){
        //Initialize the screen
        this->display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
        this->display.setTextSize(1);
        this->display.setTextColor(SSD1306_WHITE);
        this->display.clearDisplay();
        this->output(60,30,":)");
        this->display.display();
    }

    void output(int x, int y, String S){
      this->display.setCursor(x, y);
      this->display.print(S);
      Display.display();
    }
};


Screen screen();
void setup(){
  screen.init();
}

void loop(){}


Errors are :

In file included from D:\project\escape\puzzle box\source\puzzle_box_v6\Puzzle_box_v6.ino:12:0:
sketch\Screen.h: In constructor 'Screen::Screen()':
Screen.h:12:25: error: expected unqualified-id before 'this'
        Adafruit_SSD1306 this->display(128, 64, &Wire, -1);
                         ^~~~
sketch\Screen.h: In member function 'void Screen::output(int, int, String)':
Screen.h:27:7: error: 'Display' was not declared in this scope
       Display.display();
       ^~~~~~~
sketch\Screen.h:27:7: note: suggested alternative: 'display'
       Display.display();
       ^~~~~~~
       display
D:\project\escape\puzzle box\source\puzzle_box_v6\Puzzle_box_v6.ino: In function 'void setup()':
Puzzle_box_v6:40:9: error: expected unqualified-id before '.' token
   Screen.init();
         ^
exit status 1
expected unqualified-id before 'this'

I would appreciate any and all advice. Perhaps my entire approach is wrong. If not, specifically could I get an explanation on how to generate an object and assign it to a property of another class.

Lastly, if anyone is still reading...I don't what parameter data type I need to declare to pass in the memory location value for init(). Currently it is "0x36" hardcoded, I want to pass it in via parameter. If anyone could advise on this matter I would appreciate it as well.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
hendr1x
  • 1,470
  • 1
  • 14
  • 23
  • what is the line in the constructor supposed to be? Did you try to initialize the member? Call the method? I am as confused as your compiler ;) – 463035818_is_not_an_ai May 12 '21 at 22:47
  • @largest_prime_is_463035818 I was trying to generate a class object so I could perform operations on it (as shown in output function). My thoughts were, each Screen class instance would have its own SSD1306 object that it worked upon. Thanks for your help. – hendr1x May 12 '21 at 22:48
  • @largest_prime_is_463035818 So I am initializing Screen at the bottom of the code snippet and then running screen.init() inside setup. Does that answer your questions. I'm more confused that both you and the compiler. – hendr1x May 12 '21 at 22:49

2 Answers2

3

I am not sure if I understand your intentions, but I suppose you wanted to initialize the display member when you wrote

Adafruit_SSD1306 this->display(128, 64, &Wire, -1);

in the constructor. The thing is: This line makes no sense.

To initialize the member by calling its constructor you should use the member initialization list. Also init should probably be part of Screens constructor:

Screen() : display(123,64, &Wire, -1) {
    //Initialize the screen
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.clearDisplay();
    output(60,30,":)");
    display.display();
}

You don't need to prefix members with this->. Not sure what &Wire is, as its not part of the error message I suppose it is declared in code you did'nt post.

Other errors are 'Display' was not declared in this scope because there is no Display. If you wanted to call the method display of the Adafruit_SSD1306 member you have to pay attention to capitalization: display.display();

Screen screen(); is the so-called most vexing parse. It declares a function. If you want to declare an object of type Screen write this instead:

 Screen screen;          // or ..
 Screen screen{};        // or...
 auto screen = Screen();

The last error is not in the code you posted. It complains about Screen.init() while your have the correct screen.init();. Though, as mentioned above, initialization should probably be part of constructing a Screen and you can remove the method and that call.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I'm not quite on the same page as you. I want a wrapper class for the Adafruit_SSD1306 class that allows me to do common tasks and allows me to handle multiple OLED screens on my project. I want to initalize the Adafruit_SSD1306 class and assign it to Screen->display (or any property of Screen class). I'm not familar with the term member. Does that mean an initialized class object? – hendr1x May 13 '21 at 00:15
  • The whole init() thing was just an example, you are correct about moving it into the constructor but this was more a proof of concept where I am trying to figure out an approach that works with a lot of functionality. The example you provided, because I don't understand things properly of course, doesn't show me how to have any functionality. It just seems likes a consolidation of everything to one method. My apologies about the Display stuff, that was me trying to simplify other code and rushed it. – hendr1x May 13 '21 at 00:15
  • Lastly...about the Screen screen() stuff...I am working off a tutorial @ https://roboticsbackend.com/arduino-object-oriented-programming-oop/ That is how they are generating their LED and Button classes. It didn't make sense to me but I just trusted it was fine. All I'm trying to do is generate a class. I don't really get why its different in @PaulSanders provided code. Lastly, if you have time, could you help me with the last part of the question. I need to pass in a parameter for memory location of the OLED but I don't know what type to assign to the parameter of the function. – hendr1x May 13 '21 at 00:15
  • Sorry for all the text, I just did some reading onr initialization lists and have a better idea of what is going on now. I don't understand how this is a better approach honestly and as mentioned prior, I need the ability to pass in a memory location of the OLED, not sure if that causes issues with initialization – hendr1x May 13 '21 at 00:26
  • you need to learn some basic before jumping into waters. "I'm not familar with the term member." suggests that you are in need of a introductory book. You can find some recommendations here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – 463035818_is_not_an_ai May 13 '21 at 00:33
  • Thank you for the link. I will do some more reading. – hendr1x May 13 '21 at 15:53
2

This line:

Adafruit_SSD1306 this->display(128, 64, &Wire, -1);

is not valid C++. If you want to initialise the display member in your Screen object, you can do something like:

this->display = Adafruit_SSD1306 (128, 64, &Wire, -1);

Disclaimer: I don't know what parameters the Adafruit_SSD1306 constructor is expecting, so the above might need to be tweaked a little.

Alternatively (and better), you can initialise your display member in Screens constructor's initialisation list, as described in @largest_prime's answer. If you don't want to initialise display with all constants then pass any necessary arguments to Screen's constructor in either case.

Also, you don't need to write this-> all over the place. This is assumed by the compiler.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • https://adafruit.github.io/Adafruit_SSD1306/html/class_adafruit___s_s_d1306.html the `&Wire` seems to be some Arduino specific thingy. – 463035818_is_not_an_ai May 12 '21 at 23:19
  • @largest_prime_is_463035818 Yes, I saw that. Lots of constructors to choose from... – Paul Sanders May 12 '21 at 23:20
  • @PaulSanders Oh man, you got it. Thank you. I did some reading on constructor initialisation lists. I get the concept but none of the guides I saw talked about why it was better. I also need the ability to pass in a memory location of the OLED, not sure if that causes issues with initialization – hendr1x May 13 '21 at 00:27