Scrolling Bitmaps

Go To Last Post
57 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought I would start a new post with a more meaningful title.

 

I want to scroll some numbers left and right or up and down (only one of them depending on orientation). I have 7 individual bitmaps at the moment and my brain can't get around how to scroll one of the screen (SSD1306 OLED) as the next scrolls on to the screen.

 

Would creating a single bitmap with all the required numbers in a row and then scrolling the "x" start position be a suitable solution?

 

Link to the other short thread.  https://www.avrfreaks.net/forum/arduino-ide-v-atmel-studio

Last Edited: Wed. May 27, 2020 - 11:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

windoze_killa wrote:
a new post with a more meaningful title

so don't forget to add a link in your old thread, in case people want to follow the discussion.

 

and, if the other thread is resolved, mark the solution - see Tip #5 in my signature.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

There have been recent threads on the Arduino.cc Displays Forum.

 

We have no idea what libraries,  bitmap format, fonts, ... C or C++, ... you are using.

 

So the only answer that I can give is:   Buy a pencil.    Draw your big bitmap on paper.    See the effect of starting at different offsets into your big bitmap.

 

David.

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

I can scroll a bitmap off one side BUT it starts to appear on the other side. I want another bitmap to appear. EG. A big number "1" scrolls off to the left and a big "2" scrolls on from the right. Then a "3" and so on an then back the other way.

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

Suppose that you have an 8x8 character displayed and you want to shift is left.

 

Assume that the left most column of each character is column 0.

 

Then, after displaying a whole character, display columns 1-7 of the first character and column 0 of the second character

 

Next, display columns 2-7 of the first and columns 0-1 of the second.

 

Repeat this pattern.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Start out with something minimal that you can wrap your mind around, and it will scale up.

 

A 3x3 bitmap is a good start-

https://godbolt.org/z/7LxzLU

 

There may be a better way, but you can tinker with small examples first then go big when it works properly.

 

If you make all your bitmaps into one bitmap, yes you can just move x around (or y if vertical), but you will then be stuck with movement in the one axis and will still need to come up with something if also want to scroll vertical, or 'scroll' bitmap data that is not adjacent to each other.

 

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

As far as scrolling verticle or horizontal I would just create 2 bitmaps, one for each and call the one I wanted. For bitmap data that isn't adjacent...it will never happen, they must always transition through each other.

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

For horizontal to the right, do just the opposite to what I wrote above. For vertical, just increment or decrement rows rather than columns. 

 

For vertical, you might want a different bitmap description that is organized by rows rather than columns.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Thu. May 28, 2020 - 03:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not sure what you are getting at. Are you talking about the bitmap code within the sketch? If so isn't each of the characters in a column = to 8 pixels?

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

Without scrolling, how do you load the bitmap into the display? Do you do it a column at a time, or a row at a time?

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

display.drawbitmap

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

<edit> Overlapping post - I didn't know he was using Adafruit_SSD1306 lib when I wrote this. </edit>

 

You need to write a clipping function. Then treat pixel co-ordinates as "virtual" so they can become -VE and also greater than MAX_X,MAX_Y. I.e. when you call setPixel() with an invalid co-ordinate for the LCD you don't do the write.

 

E.g. If you wish to scroll a digit left that's already written at co-ordinates 0,0, you perform a write at virtual co-ordinates -1,0; and again sometime later at -2,0. Repeat until no part of the digit appears on the LCD.

 

Last Edited: Thu. May 28, 2020 - 09:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Saying that you use display.drawbitmap tells nothing. I am guessing that (almost) nobody here knows exactly what that does. I do know that I don't know what it does. How do you horizontally scroll a single character, now?

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Thu. May 28, 2020 - 07:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

There have been recent threads on the Arduino.cc Displays Forum.

 

We have no idea what libraries,  bitmap format, fonts, ... C or C++, ... you are using.

 

I can guess which library might have a display.drawbitmap() C++ method.

 

But life is much simpler if you quoted libraries by name or preferably with links.

And if you quote a method,   you spelled it correctly.

 

David.

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

In the good old days of bitmap based games and things what you would often do is employ a thing called a "back buffer". In this you could "blit" parts of bitmaps and just ignore anything that "falls off the edges". Then take the "active rectangle" (often called "Region of Interest" = "ROI") and blit the whole composite image onto the screen.

 

AVRs don't really lend themselves to this kind of thing as you may not have enough RAM.

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

I am using the Adafruit_SSD1306 lib.I am also using the Arduino IDE as it seems simpler than AVR Studio.

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

Can you show the format in which you are actually holding the bitmaps? On the whole "scrolling" bitmaps is usually easy in one axes and trickier in the other. Take the classic 8x8 mono characters held as 8 bytes of info. If you only want the bottom 5 lines of the 8, for example because it's scrolling "off the top" of the screen, then you just skip reading the first 3 bytes then take each line from there onwards. But if it's going "off the right" so you only wanted to show 7 of the 8 pixels in each line you have to take the pixel defining bytes in turn and >>1 each one so you only have the top 7 bits each time then "blit" that. That is where things can get trickier. This then gets even more complex when you switch from mono to colour.

Last Edited: Thu. May 28, 2020 - 08:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

windoze_killa wrote:
I am using the Adafruit_SSD1306 lib.

david.prentice wrote:
preferably with links.

 

You missed that bit?

 

So try this link:  https://www.google.com/search?q=adafruit_ssd1306+library+scroll+image

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No. Because it said OR  preferably with links.

 

Thanks for the search link. It may have what I want....hopefully.

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

If you look at the source code, they appear to do like anyone else where you eventually end up in a draw pixel type function.

 

This draw pixel function will just return if either x or y is not on the display, so take advantage and do something like this-

 

//if display is 128x64, and bitmaps are 64x64 for example
//and bitmaps are centered (32,0)

 

//start drawing at position of current bm1 on display
int16_t bm1_x = 32; //bm1 starts at 32,0 (currently displayed)
int16_t bm2_x = 32 + display.width(); //bm2 will be 1 display width to the right

 

for( ; bm2_x >= 32; bm1_x--, bm2_x-- ){ //keep shifting left until bm2 in position (32,0)
    display.drawBitmap( bm1_x, 0, bm1, 64, 64, 1 );

    display.drawBitmap( bm2_x, 0, bm2, 64, 64, 1 );

    display.display(); //I think this updates the display, but don't know

    delay( whateverYouWant );
}

 

Should be easy enough to try. If the bitmaps take the whole display, then change the 32's to 0., or change anything else as needed.

Last Edited: Fri. May 29, 2020 - 03:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is very similar to what I have been trying. Unfortunately it is not working. I am sure it will be something very simple as as been most of my problems.

 

I will have a play over the weekend and see what I cn do.

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

Having a play but for some reason it is not working. I will keep trying and post any changes

 

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

curtvm wrote:

If you look at the source code, they appear to do like anyone else where you eventually end up in a draw pixel type function.

 

This draw pixel function will just return if either x or y is not on the display, so take advantage and do something like this-

 

//if display is 128x64, and bitmaps are 64x64 for example
//and bitmaps are centered (32,0)

 

//start drawing at position of current bm1 on display
int16_t bm1_x = 32; //bm1 starts at 32,0 (currently displayed)
int16_t bm2_x = 32 + display.width(); //bm2 will be 1 display width to the right

 

for( ; bm2_x >= 32; bm1_x--, bm2_x-- ){ //keep shifting left until bm2 in position (32,0)
    display.drawBitmap( bm1_x, 0, bm1, 64, 64, 1 );

    display.drawBitmap( bm2_x, 0, bm2, 64, 64, 1 );

    display.display(); //I think this updates the display, but don't know

    delay( whateverYouWant );
}

 

Should be easy enough to try. If the bitmaps take the whole display, then change the 32's to 0., or change anything else as needed.

 

I had a play with this code with a few mods and I have the screen scrolling but there is no image just the white background scrolling on.......very slowly. It takes about 10 seconds to scroll. delay (0) so I don't know why it is so slow. 1 to 2 seconds would be better. I will post some code later when on my other computer.

 

Any clues?

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

Here is the bit of code that isn't working.

 

  //Display/scroll bitmap

  //start drawing at position of current bm1 on display
  int16_t bmN_x = 64; //bm1 starts at 32,0 (currently displayed)
  int16_t bm1_x = 64 + 64; //bm2 will be 1 display width to the right

  display.clearDisplay ();
  
  if (New_Gear == Current_Gear) {}


  else if (New_Gear == 1 and Current_Gear ==0)    //Scroll Left

    for ( ; bm1_x >= 64; bmN_x--, bm1_x-- ) { //keep shifting left until bm1 in position (64,0)
      display.drawBitmap( bmN_x, 0, bmN, 64, 128, 1 );
      display.drawBitmap( bm1_x, 0, bm1, 64, 128, 1 );

      display.display();

      delay(0);
    }

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  delay(0);

An interesting concept! Is this like "If a tree falls in a forest and no one is around to hear it, does it make a sound?"

 

Anyway I rather think that if you want to "see" the scrolling you probably do need a short "viewing delay" at each stage.

 

Having said that things like image blits generally take a finite amount of visible time so just the slowness of the blitting might be enough to show the "frames" ?

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

Did you investigate the hardware scroll ? the video looked excellent.

 

In #18 awneil Presented a google search as a link - that's not ideal because search results can vary depending on location, your cookies, and over time.

 

This article contains the video mentioned above:

https://hackaday.io/project/10533-nano-tty/log/34525-smooth-scrolling-on-a-ssd1306

 

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

I would say the scroll by redraw are doomed to be ugly, because it's slow. (and that you use SPI don't help)

Are you sure that you can't change the memory start pointer on the controller that is the "normal" way of doing it. (some chips can HW scroll what inside a box).

 

I know that not all datasheets are that good but when you first understand all the pointers do it's not so hard.   

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

>Here is the bit of code that isn't working.

 

Its quite hard to see through the code that cannot be seen. I appears you may be using the display in a vertical position, but who knows. If the bitmaps are 64x128 (vertical), and your starting x value for the first bitmap is 64, then that would seem wrong. If the bitmaps are the same size as the display, then the first starting x is 0, and the new x will start at 64-

bm1: 0,0 -> -1,0 -> -2,0 -> ... -> -64,0

bm2: 64,0 -> 63,0 -> 62,0 -> ... -> 0,0

 

 

How about simply just get a bitmap to scroll 1 position left. Then 2. Then for the display width in a loop. When you get  that figured out, add the second bitmap and start over.

 

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

Yes, you can "scroll" a 128x32 SSD1306 because it thinks 128x64.

 

Run that code on a real 128x64 and you can see what is happening.

 

Yes,  you can use several tricks to scroll in software.   And you can do it faster than the human eye.

But in practice you actually want a slow scroll that the human eye finds pleasant.

 

The OP has never mentioned any dimensions.   Or given any example bitmaps.   Or even said whether I2C or SPI interface to SSD1306.

 

I can think of "likely" situations.   e.g. animating a digit from a standard font or merging one photo into another.

Merging photos is never going to be practical on a tiny monochrome display.    But possible on a grayscale or colour display.

 

You could animate digits horizontally, vertically or even diagonally.

 

David.

Last Edited: Thu. Jun 4, 2020 - 04:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just looked at the datasheet for the SSD1306 and the commands 0x26 to 0x2f is about auto scroll of the display. (0xA3 is used to define the size) 

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

Ok. I have obviously left out a few things of importance.

 

1.   I am using I2C.

2.   Display has been rotated using display.setRotation (3). (Adafruit_SSD1306.h)

3.   The bitmaps are very simple, 64 x 128. Images are just numbers 1 to 7. (Text doesn't work, I have tried that) Each number takes up the whole screen.

 

Unfortunately Mr Sparrow you have just aimed about 3 miles above my head. How do I do this? It would be great if I can work out how to do this in hardware. I am using the Arduino IDE and a Mega2560 for testing. 

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

windoze_killa wrote:
about 3 miles above my head. How do I do this?
Start by studying the code you are already using. It appears to be here...

 

https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.cpp#L521

 

That line 521 shows "command sequences" that they already send to the display to command it to do various operations. Each sequence starts with some command byte like  SSD1306_DISPLAYOFF ( 0xAE ),  SSD1306_SETVCOMDETECT ( 0xDB )

 

So the example commands Sparrow suggests like 0x26, 0x2F, 0xA3 would presumably be sent in a similar way. In fact when you look at:

 

https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.h#L70

 

This is already defining a list of commands that are being used in the existing code so on the whole you can probably just re-use the pattern and existing functions for sending command sequences to add support for these additional ones.

 

(To be honest, this being Adafruit who are known for the quality and completeness of their code, I'm a bit surprised the library doesn't already have support for all the features the controller offers!)

 

EDIT: Oh I'm blind, I thought that list of commands was in numeric order and I couldn't see 0x26 etc there. I should have read a bit further:

 

https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.h#L98

Last Edited: Fri. Jun 5, 2020 - 08:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK after finding the stuff in my most recent EDIT I then looked at the code to see where it might be used and found things such as:

 

// To scroll the whole display, run: display.startscrollright(0x00, 0x0F)
void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop) {
  TRANSACTION_START
  static const uint8_t PROGMEM scrollList1a[] = {
    SSD1306_RIGHT_HORIZONTAL_SCROLL,
    0X00 };
  ssd1306_commandList(scrollList1a, sizeof(scrollList1a));
  ssd1306_command1(start);
  ssd1306_command1(0X00);
  ssd1306_command1(stop);
  static const uint8_t PROGMEM scrollList1b[] = {
    0X00,
    0XFF,
    SSD1306_ACTIVATE_SCROLL };
  ssd1306_commandList(scrollList1b, sizeof(scrollList1b));
  TRANSACTION_END
}

So that already has support for 0x26. In fact you might have guessed that a function called "startScrollRight" might have some connection to the 0x26 command !f I were you I'd maybe explore:

  void         display(void);
  void         clearDisplay(void);
  void         invertDisplay(boolean i);
  void         dim(boolean dim);
  void         drawPixel(int16_t x, int16_t y, uint16_t color);
  virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
  virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
  void         startscrollright(uint8_t start, uint8_t stop);
  void         startscrollleft(uint8_t start, uint8_t stop);
  void         startscrolldiagright(uint8_t start, uint8_t stop);
  void         startscrolldiagleft(uint8_t start, uint8_t stop);
  void         stopscroll(void);
  void         ssd1306_command(uint8_t c);
  boolean      getPixel(int16_t x, int16_t y);
  uint8_t     *getBuffer(void);

some more and see what each of these offers.

 

(I knew AdaFruit code would be complete!!)

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

Thank you very much. I am not saying the other posts weren't useful because they have taught me heaps but this is what I call great. Not telling me what to dobut clearly pointing me where to look. Thanks again. I will let you know how I go.

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

These scroll functions are not what you want. They are simply scrolling whatever is already in the display memory (all or part), which is what the hardware allows. These do nothing for getting that second bitmap to start showing up.

 

If speed is needed, then you can probably combine what they have for functions into something that shifts the display in hardware, then write a new single line from the next bitmap, repeat until done. That eliminates the need for a complete buffer write for each 'frame'. That will faster, but harder than what you are attempting now.

 

I would go back to the beginning, and take it slow- draw bitmap, display, wait, draw bitmap at x origin 1 to the left/right, wait, repeat. If you cannot scroll a single bitmap or figure out what is happening, then no use advancing to the next steps. 

 

 

 

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

BINGO. Well sort of. I can scroll the left and right but there a a couple of problems. First one is it takes 8 seconds to scroll. I have no delays in it. The other is no matter how I set the rotation of the display it always scrolls left and right along the long axis. So when I have the display set to portrait it scrolls up and down. This in itself is not a problem IF it would complete its scroll in 1 second.

 

Thank you clawson, this is the biggest step forward so far.

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

curtvm wrote:

These scroll functions are not what you want. They are simply scrolling whatever is already in the display memory (all or part), which is what the hardware allows. These do nothing for getting that second bitmap to start showing up.

 

If speed is needed, then you can probably combine what they have for functions into something that shifts the display in hardware, then write a new single line from the next bitmap, repeat until done. That eliminates the need for a complete buffer write for each 'frame'. That will faster, but harder than what you are attempting now.

 

I would go back to the beginning, and take it slow- draw bitmap, display, wait, draw bitmap at x origin 1 to the left/right, wait, repeat. If you cannot scroll a single bitmap or figure out what is happening, then no use advancing to the next steps. 

 

 

 

 

Thank you. Good idea. But just a I thought I was solving it you shoot me down. laugh I guess it is all part of the learning process. 2 months ago i couldn't even spell "C".

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

Thanks curtvm for the kick in the arse. It did what was required. I now have it scrolling how I want it. One image scrolling on while the other is scrolling off. It still takes 8 seconds though. I am not sure how to do it line by line.

 

Here is the bit that is working.

  if (New_Gear == Current_Gear) {}


    else if (New_Gear > Current_Gear)    //Scroll Right
      for (int Gear_0_x = 0 ; Gear_0_x >= -64; Gear_0_x--) { 
       display.clearDisplay();
       display.drawBitmap(Gear_0_x, 0, Gear_0, 64, 128, 1 );
       display.drawBitmap(Gear_0_x+64, 0, Gear_1, 64, 128, 1 );

       display.display();

       delay(0);
    }
  Current_Gear = New_Gear;

 

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

>One image scrolling on while the other is scrolling off. It still takes 8 seconds though

 

Take inventory of what functions are available to you, grab the datasheet and see how the hardware determines its starting line/column (display start or display offset). Somewhere in that mix you may be able to shift the display 1 line, then replace the line (or page) on some edge with new data, repeat for every line/column/page. If there is nothing in the current functions that will do what you want, maybe you will need to add a lower level function or use a command function to talk to the hardware. You will be bypassing the ram buffer unless you want to use it as a scratchpad if needed.

 

It also looks like scrolling left/right in the vertical format will be slower than scrolling left/right in the horizontal, since you would have to rewrite a whole page byte (7bits of old data, 1bit of new, which means more complicated). So for a 64 pixel scroll in vertical, it takes 128bytes per shift- 128bytes*64=8192bytes total. For a 128 pixel scroll in horizontal, it takes 8bytes per shift- 8bytes*128=1024bytes. You are currently moving 64k (1024*64) in 8 seconds it seems. Another alternative for the left/right scroll in the vertical position is to just do it 8 pixels at a time so you don't have to merge old/new data in a page byte.

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

As you were typing that I had a brain fart and I am goig to have another go at it. I saw something the other day that should work with some mods if I can find it again.startscrollright

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

FAIL. Uses libaries that are for text only. I have been at this too long for one day.

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

I have attached a sketch.

 

It uses Adafruit_SSD1306 library with a 128x64 I2C display.

 

I suggest that you experiment with step size etc.   Then substitute your own bitmaps.

Note that the SPI displays are a lot faster.

 

If you want to scroll faster,  please give some actual times.

It is possible to start a left or right scroll and write a single vertical column synchronised with the Frame frequency but it would be a bit hairy.

Set the hardware scroll step interval to 2 frames and increase the frequency.

 

David.

 

 

Attachment(s): 

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

Awesome. Speechless.

 

I now jus have to spend some time deciphering it all.

 

Speed wise, somewhere between the 4 to 5 and the 5 to 6 transition would be perfect.

 

Play time.

 

Thank youu so much.

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

After a bit of a look I have a couple of questions.

 

If I dump my own bitmaps into digits.h I should be able to delete mkdigits(void) and write_mono_map, correct?

 

I don't understand this bit at the top of each bitmap. ((64 + 7)/8) * 128 Can I just put in the result, 1136?

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

1136 as a number doesn’t have much meaning -whereas the equation gives some hint. The compiler will happily calculate it for us so there is no overhead at run time.
The underlying concept here is ‘magic numbers’ - that is a number that gives no idea of what it means. You want to avoid magic numbers in your code.

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

Yep. Makes sense.

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

I don't understand this bit at the top of each bitmap. ((64 + 7)/8) * 128 Can I just put in the result, 1136?

 

Add these two lines to your setup()

void setup()
{
    Serial.begin(9600);
    Serial.print("// sizeof(digit_5_b) = ");
    Serial.println(sizeof(digit_5_b));
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // required to run SSD1306
    display.setRotation(3);
    //mkdigits();   //create test bitmaps. copy-paste to "digits.h"
}

The Compiler will do the maths for you.

 

The reason for the expression is to cater for bitmap widths that are not multiples of 8.

The Adafruit drawBitmap() method can display a 63x128 bitmap but only if each row starts on a byte boundary.

Formats like BMP require their bitmaps to be on 32-bit boundaries.

 

Incidentally,  the FreeFont bitmaps understand packed bitmaps.   So a 1x8 letter would only use one byte.  The Adafruit bitmap would use 8 bytes.

 

Speed wise, somewhere between the 4 to 5 and the 5 to 6 transition would be perfect.

 

4, 5 are both drawn three rows at a time  (step = 3) i.e. whole screen is re-drawn 43 times.   I suggest that you try step = 4 (32 re-draws)

 

6 is drawn in 64ms.  7 is drawn in 3200ms.   i.e. hardware is dramatically faster.   There is no "re-draw".   The hardware just uses the "vertical shift register 0xD3"

 

I suggest that you play around with the loop() statements until happy.

 

Speed is always limited to the I2C bus.   Re-drawing the whole screen means 1024 data bytes with a bit of housekeeping.   e.g. 27ms @ 400kHz I2C bus.    The SPI version of your display would be 1.1ms @ 8MHz SPI clock.   These are theoretical calculations.   It is easy to measure if you need to.

Incidentally,  the SSD1306 will run happily at speeds faster than SPI = 8MHz but I2C is limited to about 500kHz.

 

David.

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

Thanks David,

 

Explainations like that makes it so much easier to understand. Thank you greatly for putting in the effort to help. I think I will get a couple of SPI versions and have a play.

 

I have been playing with the loops and I am learning more at a very fast rate. Also learning some very bad habits too.

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

You're up early for a chilly morning!

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

Chilly morning????? OH. It still says I am in Broadford. I have been in Cairns for the last 2 years. 18 here at the moment. Shorts and a Tshirt. Bloody hard life.

 

What part of Melbourne are you in?

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

Bayside. Cairns is rather displaced from Broadford.

 

Have you met with the local identity Ray Hall?

Pages