Rotating a bitmap

Here's some code that works on my 128x32 OLED.

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

// These are the pins I use on a NodeMCU ESP-12E
//#define OLED_SDA D7 //MOSI
//#define OLED_SCL D5 //CLK
//#define OLED_DC  D4  //DC
//#define OLED_CS  12  // My OLED does no have a CS line, so just use a spare pin to keep library happy
//#define OLED_RST D3 //RES

// Software SPI on NodeMCU
//Adafruit_SSD1306 display(OLED_SDA, OLED_SCL, OLED_DC, OLED_RST, OLED_CS);

// Don't specify MOSI and SCLK so hardware SPI on NodeMCU
//Adafruit_SSD1306 display(OLED_DC, OLED_RST, OLED_CS);


// Using hardware SPI pins:
#define OLED_DIN   12
#define OLED_CLK   13
#define OLED_DC    10
#define OLED_CS    9
#define OLED_RESET -1

// Software bit bashed SPI
Adafruit_SSD1306 display(OLED_DIN, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// Hardware SPI
//Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);


#define DEG2RAD 0.0174532925

long unsigned int startMillis;
short unsigned int iter = 0;              // used to calculate the frames per second (FPS)
int angle = 0;

const static uint8_t PROGMEM testbmp1[] =
{ 16, 8,
  B00000001, B10000000,
  B00000010, B01000000,
  B00000100, B00100000,
  B00001000, B00010000,
  B00010000, B00001000,
  B00100000, B00000100,
  B01000000, B00000010,
  B10000000, B00000001
};

const static uint8_t PROGMEM testbmp2[] =
{ 16, 9,
  B00000011, B00000000,
  B00001111, B00000000,
  B00111111, B00000000,
  B01111111, B11111111,
  B11111111, B11111111,
  B01111111, B11111111,
  B00111111, B00000000,
  B00001111, B00000000,
  B00000011, B00000000
};

const static uint8_t PROGMEM bmp5x5[] =
{ 5, 5,
  B11111100, B01101011,
  B00011111, B10000000,
};

static const uint8_t PROGMEM adafruit[] =
{ 16, 16,
  B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000
};

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()   {

  // Need to hardware reset my display manually via pin 7
  digitalWrite(7, LOW);
  pinMode(7, OUTPUT);
  delay(200);
  pinMode(7, INPUT);
  delay(5);
  
  // by default, we'll generate the high voltage from the 3.3v line
  display.begin(SSD1306_SWITCHCAPVCC);  // initialize
}

void loop() {
  for (int angle = 0; angle < 360; angle += 6) {
    display.clearDisplay(); // Clear the display buffer

    drawRotatedBitmap(20, 16, testbmp2, angle);
    drawRotatedBitmap(64, 16, adafruit, angle);
    drawRotatedBitmap(108, 16, bmp5x5, angle);

    display.display();     // Now update the display with the buffer
    //delay(10); // Pause so we see it
  }
}

void drawRotatedBitmap(int16_t x, int16_t y, const uint8_t *bitmap, uint16_t angle) {

  uint8_t w = pgm_read_byte(bitmap++);
  uint8_t h = pgm_read_byte(bitmap++);

  int16_t newx, newy;
  uint8_t data = 0;

  float  cosa = cos(angle * DEG2RAD), sina = sin(angle * DEG2RAD);

  x = x - ((w * cosa / 2) - (h * sina / 2));
  y = y - ((h * cosa / 2) + (w * sina / 2));

  for (int16_t j = 0; j < h; j++) {
    for (int16_t i = 0; i < w; i++ ) {
      if ((j * w + i) & 7) data <<= 1;
      else      data   = pgm_read_byte(bitmap++);

      newx = 0.5 + x + ((i * cosa) - (j * sina));
      newy = 0.5 + y + ((j * cosa) + (i * sina));

      if (data & 0x80) display.drawPixel(newx, newy, 1);
      //else            display.drawPixel(newx, newy, 0);
    }
  }
}

You will have to tweak it for your own display and interface.

The bitmaps are in Adafruit format with two extra start bytes that specify the x and y size.

As mcnobby say's you get digitisation errors with this approach.

On these small OLED screens you are typically better off using 2D or 3D vector graphics, a hacked example 3D vector plotting demo pulled off the web is attached. Again you will have to tweak the sketch to suit your setup.

Oled3d.zip (2.9 KB)