Bitmap output from class field

I am trying to output a bitmap to the ssd1306 screen in Wokwi.
The bitmap is stored in a static field of the class. Output occurs using a class method, which is passed a display object as a parameter. The problem is that instead of the normal bitmap output, I get a crooked drawing.
Main file code:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "SomeClass.h";

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

void setup() {
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

   Serial.begin(9600);

}

void loop() {
  
  display.clearDisplay();

  SomeClass::drawBitmap(display);
  
  display.display();
  delay(1000);
}

SomeClass.h file code:

#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <Adafruit_SSD1306.h>

class SomeClass {
  public:
    static void drawBitmap(Adafruit_SSD1306& display) {
      display.drawBitmap(10, 10, sprite, 8, 8, SSD1306_WHITE);
    }
    static const unsigned char sprite[8];
};

static const unsigned char SomeClass::sprite[8] {
  B11111111,  // ะ ัะดะพะบ 1 (ะฒะตั€ั…ะฝั–ะน ั€ัะดะพะบ)
  B10000001,  // ะ ัะดะพะบ 2
  B10000001,  // ะ ัะดะพะบ 3
  B10000001,  // ะ ัะดะพะบ 4
  B10000001,  // ะ ัะดะพะบ 5
  B10000001,  // ะ ัะดะพะบ 6
  B10000001,  // ะ ัะดะพะบ 7
  B11111111
};

#endif

Also, when I try to display the bitmap obtained from the SomeClass sprite field in the loop() function like "display.drawBitmap(10, 10, SomeClass::sprite, 8, 8, SSD1306_WHITE)", it is also displayed crookedly. What could be the problem?

wokwi

Does it display how you want if you do everything outside of a class? If so, post the code that does that.

Here's the code without using the class

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "SomeClass.h";

Adafruit_SSD1306 display(128, 64, &Wire, -1);
unsigned char sprite[8] {
  B11111111,  
  B10000001,  
  B10000001,  
  B10000001,  
  B10000001,  
  B10000001,  
  B10000001,  
  B11111111
};


void setup() {
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

   Serial.begin(9600);

}

void loop() {
  
  display.clearDisplay();

  display.drawBitmap(10, 10, sprite, 8, 8, SSD1306_WHITE);
  
  display.display();
  delay(1000);
}

This code outputs the bitmap as it should

image

If I pass an array from the SomeClass instead of the local one to the drawBitmap function, it will also be drawn crookedly

See if doing the following helps:

  1. Remove the extraneous semicolons (';') from the end of all #include statements.
  2. Move the definition of sprite from the .h to a separate .cpp file.
  3. Remove the 'static' attribute from the definition but not the declaration.

SomeClass.h:

#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <Arduino.h>
#include <Adafruit_SSD1306.h>

class SomeClass {
  public:
    static void drawBitmap(Adafruit_SSD1306& display) {
      display.drawBitmap(10, 10, sprite, 8, 8, SSD1306_WHITE);
    }

    static const unsigned char sprite[8];
};
#endif

SomeClass.cpp:

#include "SomeClass.h"

const unsigned char SomeClass::sprite[8] {
  B11111111,  // ะ ัะดะพะบ 1 (ะฒะตั€ั…ะฝั–ะน ั€ัะดะพะบ)
  B10000001,  // ะ ัะดะพะบ 2
  B10000001,  // ะ ัะดะพะบ 3
  B10000001,  // ะ ัะดะพะบ 4
  B10000001,  // ะ ัะดะพะบ 5
  B10000001,  // ะ ัะดะพะบ 6
  B10000001,  // ะ ัะดะพะบ 7
  B11111111
};

Same result, the bitmap is not displayed as it should be :frowning:

Next I would start instrumenting the library's source code with print statements to track down the difference between the class and non-class cases.

Post a link to your Wokwi project. Then we can see EXACTLY what's going on.

-jim lee

try

static void drawBitmap(Adafruit_SSD1306& display) {
      display.drawBitmap(10, 10, SomeClass : : sprite, 8, 8, SSD1306_WHITE);
    }

Same result

Nothing changed

To test purpose, try with using the class, but with sprite as independent array and not a class member

In this case, the sprite is also displayed incorrectly

static void drawBitmap(Adafruit_SSD1306& display) {
      unsigned char someSprite[8] = {
        B11111111,  
        B10000001,  
        B10000001,  
        B10000001,  
        B10000001,  
        B10000001,  
        B10000001,  
        B11111111
      };

      display.drawBitmap(10, 10, someSprite, 8, 8, SSD1306_WHITE);
    }

In your class, why are you making things static?

I mean, there are reasons to do this, but typically they are rare. Like building a fast car then leaving the driver's seat laying next to it on the road.

It doesn't matter if the class members have the static attribute, the bitmap still renders poorly. Although really, I'm primarily interested in storing and using a bitmap in a non-static field

To work with bitmap you need to instantiate a SomeClass object first.

Could you try this

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "SomeClass.h";

Adafruit_SSD1306 display(128, 64, &Wire, -1);
SomeClass sc;  // <<<<< instantiate of SomeClass object

void setup() {
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
 Serial.begin(9600);
}

void loop() {
  
  display.clearDisplay();
  sc.drawBitmap(display);   // <<<<<<<  call drawBitmap as an object method
  
  display.display();
  delay(1000);
}

All the same, the bitmap displays crookedly. Although it's a little different

image

Could you try another variant ? :slight_smile:

The loop() (the rest of the file without changes)

void loop() {
  
  display.clearDisplay();
  sc.drawBitmap(&display);  
  display.display();
  delay(1000);
}

SomeClass.h:

#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <Adafruit_SSD1306.h>

class SomeClass {
  public:
    static void drawBitmap(Adafruit_SSD1306* display) {
      display->drawBitmap(10, 10, SomeClass::sprite, 8, 8, SSD1306_WHITE);
    }
    static const unsigned char sprite[8];
};

static const unsigned char SomeClass::sprite[8] {
  B11111111,  // ะ ัะดะพะบ 1 (ะฒะตั€ั…ะฝั–ะน ั€ัะดะพะบ)
  B10000001,  // ะ ัะดะพะบ 2
  B10000001,  // ะ ัะดะพะบ 3
  B10000001,  // ะ ัะดะพะบ 4
  B10000001,  // ะ ัะดะพะบ 5
  B10000001,  // ะ ัะดะพะบ 6
  B10000001,  // ะ ัะดะพะบ 7
  B11111111
};

#endif

Same result

Check:

Sorry, I haven't more ideas