SSD1306 rotation by 90*

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I am working with SSD1306 (xmega 32E5, I2C, 64x48 OLED) and I need to rotate that display by 90 degrees (permanently, not run time).

Unfortunately, I can set up the SSD from horizontal mode to vertical (memory adressing), but this does not solve my problem at all, since it is not on bit/pixel level, but on a byte level. This results in possibility to change which will be the next 8 bits drawn, but not the orientation of drawing 8 pixel block (1 byte).

 

Flipping by 180 degrees and other directional commands also seem not to do the trick for me, since they also does not change the orientation by 90 degrees; 180 degrees flip is easily done, mirroring image and such are easy, but I cannot see how to do 90 degrees rotation (swaping the roles of pages and columns).

 

All I can think of is edit the fonts I use and also since the basic font now is:

 - 8x12 and I write 12 lines, 1 byte each (8 pixels), 1 page x 12 columns

 

I will have to edit some of the functions as well, since now the actual length will be:

 - 8x12; 8 lines, x 1.5 page each

 

Meaning I will have to write 8 lines * 2 pages and adapt the fucntions to take the missing 4 bits above the first line (odd pages) and below the last (even pages) in order not to mess up the other lines of text. Of course, I can also go to a 8x16 or 5x8 fonts to avoid this complication, but this is not preferred - Nx8 seems too small, Nx16 seems to big for 64x48 dsp, I can fit too little information.

 

So, is there a simpler and elegant way for 90* rotation, done by configs of SSD1306, without having to change my font and code greatly?

 

P.S.

Here is what horizontal mode does with 4 bytes:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

 

Here is what vertical mode does with 4 bytes:

0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23

8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31

 

Here is what I need done:

0 16

1 17

2 18

3 19

4 20

5 21

6 22

7 23

etc...

This topic has a solution.
Last Edited: Wed. Jan 31, 2018 - 10:45 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know it may be less efficient than "blitting" but if you simply create a setPixel(x, y) then drawing font characters becomes (bitwise) a process of going across the x and up/down the y. Then to rotate you just exchange x and y.

As I say, because you do the pixels individually rather than 8 at a time or more this is not efficient (which may not matter) but once you have the simple working solution you can then look at optimizing it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

There was a similar question on Arduino.cc or perhap it was here.

 

Many libraries maintain a mirror-image in an SRAM buffer and you simply blit the whole buffer when you want to "re-draw the screen".

It is simple enough to blit in whichever style you choose.   Or you swap x,y in the low-level drawPixel() layer.

drawPixel(x, y, color) is a macro in most mirror-buffer implementations.

 

Big displays are too expensive for a mirror buffer.

Since your 64x48 only requires 384 bytes of SRAM it is a no-brainer.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, that clarifies it - it cannot be done by simple ssd1306 settings.

 

Your suggestions are of course valid, I'd prefer to do some rework to avoid bit by bit drawing, but it is always a choice between work done and code performance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Just one small issue but 64x48 is not "square". So if you prepare a buffer in one orientation with a view to "blitting" it in the other (to get the required rotation) how do you account for one being 64x48 and the other being 48x64 ? You'll have a bit hanging off one end and a gap too..

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yup, true. I guess converting the font (outside the embedded code) and then tuning the function for displaying 1 character is the most efficient way to do it and using DrawPixel is the fastest and easiest, though very un-optimized.

 

I am not familiar with blitting actually, though by the context I suppose I understand - but I guess it is possible to store a single char in 12x12 (instead of 8x12), and then use the blit function, same goes for the whole dsp - write 64x48 in 64x64 array, blit, take the 48x64 zone for drawing.