Sketch written in OOP slower than when written under one tab

Hi All,
I've written a simple program to make the string "Hello" move up and down the screen of a 128x64 OLED display as seen here:

#include <Wire.h>               //include the wire library
#include <Adafruit_GFX.h>       //include the GFX library
#include <Adafruit_SSD1306.h>   //include the SSD1306 library


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT);  

float y = 0;
float yspeed = 1;
float x = 0;
float xspeed = 1;


void setup() {

  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //start screen
  display.setTextColor(SSD1306_WHITE);        //set colour

}

void loop() {

  display.clearDisplay();     //clear screen             
  display.setTextSize(1);     //text size
  display.setCursor(x,y);     //cursor position
  display.print("Hello");     //text to print
  display.display();          //send to screen

  y = y + yspeed;
  //x = x + xspeed;
  Serial.println(y);

  if (y>=56 || y<=0){         //if y is less than 56 or more than 0
    yspeed = yspeed * -1;     // invert the value of yspeed
  }
  if (x>=96 || x<=0){         //if x is less than 96 or more than 0
    xspeed = xspeed * -1;     // invert the value of xspeed
  }

}

As I'm learning Object Oriented Programming (OOP), I decided to rewrite the program in this format. My tabs are as follows:

main.ino

#include "Oled.h"

OLEDDisplay Oled;

void setup() {
  Oled.init();
  //Oled.HelloWorld();

}

void loop() {
  Oled.update();

}

Oled.cpp

//IMPLEMENTATION

#include "Oled.h"

OLEDDisplay::OLEDDisplay()
{
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
}

float y = 0;
float yspeed = 1;
float x = 0;
float xspeed = 1;


void OLEDDisplay::init()
{
  Serial.begin(115200);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextColor(WHITE);
  display.clearDisplay();
  display.display();
}

void OLEDDisplay::update()
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, y);
  display.print("Hello");
  display.display();

  y = y + yspeed;
  //x = x + xspeed;
  Serial.println(y);

    if (y>=56 || y<=0){         //if y is less than 56 or more than 0
    yspeed = yspeed * -1;     // invert the value of yspeed
  }
//  if (x>=96 || x<=0){         //if x is less than 96 or more than 0
//    xspeed = xspeed * -1;     // invert the value of xspeed
//  }
}

Oled.h

//INTERFACE


//Header guard
#ifndef OLED_H
#define OLED_H

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>




const uint8_t SCREEN_WIDTH = 128;
const uint8_t SCREEN_HEIGHT = 64;
const uint8_t BALL_COUNT = 6;

//extern Adafruit_SSD1306 display;
//extern const uint8_t SCREEN_WIDTH;
//extern const uint8_t SCREEN_HEIGHT;


class OLEDDisplay {

private:
  Adafruit_SSD1306 display;



public:
//CONSTRUCTOR
  OLEDDisplay();

  void init();

  void update();
  
};


#endif

Can anybody explain how I can optimise the OOP code to run at the same speed as the original sketch?

Thanks in advance

The display is already an object.
What you do is putting an extra layer (object) around it.
If the compiler cannot optimize it adds an extra indirection (slower)

Have you quantified the performance difference (measurements)?

The basic sketch takes four seconds for the text to scroll down and then back up.
The OOP sketch takes 38 seconds for the same.

That is a serious difference.
First note that the code in init() is not identical to the code in setup()
Second note that the code in update() and in loop() differ.

Can you

  • make the code identical,
  • Serial.println(millis()); in both sketches and
  • post the output of both sketches?

Apologies for the delay.

What I have discovered is that the code "display.begin(SSD1306_SWITCHCAPVCC, 0x3C);" under "void OLEDDisplay::init()" was causing the slow down. By moving it under "void setup" of the main tab, the output to the serial monitor is considerably better. In fact, the output is now faster than the simple sketch and I now have a different problem:
The text "Hello" appears at a random y-position and does not update itself despite the serial monitor proving that the y-position is updating. Here are the new sketches:

main.ino

#include <Wire.h>               //include the wire library
#include <Adafruit_GFX.h>       //include the GFX library
#include <Adafruit_SSD1306.h>   //include the SSD1306 library


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT); 

#include "Oled.h"



Screen screen;


void setup() {
  screen.init();
  Serial.begin(115200);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //start screen
//  display.setTextColor(WHITE);        //set colour
  



}

void loop() {
  screen.change();

}

Oled.h

//INTERFACE


//Header guard
#ifndef OLED_H
#define OLED_H

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1


//const uint8_t SCREEN_WIDTH = 128;
//const uint8_t SCREEN_HEIGHT = 64;
//const uint8_t BALL_COUNT = 6;
//
//extern Adafruit_SSD1306 display;
//extern const uint8_t SCREEN_WIDTH;
//extern const uint8_t SCREEN_HEIGHT;


class Screen {

private:
  Adafruit_SSD1306 display;
  //Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT);
  //Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

  float yPos = 0;
  float ySpeed = 1;
//  float xPos = 0;
//  float xspeed = 1;
  



public:
//CONSTRUCTOR
  Screen() {};
  Screen(float yPos, float ySpeed);

  void init();

  void change();
  
};


#endif

oled.cpp

//IMPLEMENTATION

#include "Oled.h"

Screen::Screen(float yPos, float ySpeed)
{
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  this->yPos = yPos;
  this->ySpeed = ySpeed;
}

float yPos = 0;
float ySpeed = 1;
//float x = 0;
//float xspeed = 1;


void Screen::init()
{
//  Serial.begin(115200);
  //display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  //display.begin();
  display.setTextColor(WHITE);
//  display.clearDisplay();
//  display.display();
}

void Screen::change()
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, yPos);
  display.print("Hello");
  display.display();

  yPos = yPos + ySpeed;
  //x = x + xspeed;
  Serial.print("yPos: ");
  Serial.print(yPos);
  Serial.print(" ");
  Serial.print("time: ");
  Serial.println(millis());

    if (yPos>=56 || yPos<=0){         //if y is less than 56 or more than 0
    ySpeed = ySpeed * -1;     // invert the value of yspeed
  }
//  if (x>=96 || x<=0){         //if x is less than 96 or more than 0
//    xspeed = xspeed * -1;     // invert the value of xspeed
//  }
}

Thanks in advance

Thank you for your reply, but your response is currently beyond my comprehension. Could you give me an example of what you say in your last paragraph?

 if (yPos>=56 || yPos<=0){         //if y is less than 56 or more than 0
    ySpeed = ySpeed * -1;     // invert the value of yspeed

To my eye, code and comments don't match.

Thank you, sir.
You're a genius. It's comforting to see that I wasn't too far off the actual solution.

I hope you get a lot of karma point for this.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.