Author Topic: SSD1306 OLED support small enough for Tiny86 Ported  (Read 18372 times)

defragster

  • Sr. Member
  • ****
  • Posts: 467
SSD1306 OLED support small enough for Tiny86 Ported
« on: January 11, 2015, 02:22:09 am »
I found this library http://tinusaur.org/2014/08/29/c-library-for-attiny85-to-work-with-ssd1306-controlled-oled-display/

Video of sample on this page: http://tinusaur.org/projects/ssd1306xled/comment-page-1/#comment-164

Tonight I ported the AVR code to CPP & Arduino Library.  I got the full simple sample running on my DigiSpark Pro in under half the space and under a quarter the RAM - running at 10 bytes with no text!

It came from: https://bitbucket.org/tinusaur/ssd1306xled/overview

I don't see any restrictions on use or sharing - I'll try to confirm and post it - maybe it can replace the other library I ported that is so FAT!

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #1 on: January 11, 2015, 12:58:47 pm »
From Bulgaria - Good news on the sharing: http://tinusaur.org/projects/ssd1306xled/

Neven Boyanov says:    2015-01-11 at 21:02   
 
Hey defragster, great news!

Please, feel free to share you port. In fact, I will be glad if you do. I haven’t chosen a license for the source code yet but it should be more like BSD or LGPL so the only thing I can ask is mention me and my library within your derivative and as a favor have a reference to this website. If you have any concerns – let me know.

And a link to a BMP converter for image files: http://en.radzio.dxp.pl/bitmap_converter/

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #2 on: January 11, 2015, 07:46:05 pm »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #3 on: January 11, 2015, 11:25:55 pm »
Side by side video of new and old OLED libraries.  The one running 4 times faster is the one that takes half the code space and 10 versus 90 bytes of RAM - it also doesn't exhibit garbage dots on the screen - this fast loop has been running about 22 hours on another PRO:

https://onedrive.live.com/redir?resid=5BE3704DEF865242!4109&authkey=!ABtqNkFSPAq9zlQ&ithint=video%2cmp4

This is the hopefully new 1.5.8C ssd1306xled versus the current MicrOled library in use.  You see the Smile complete 2 cycles versus 8 of the animated WHITE screen wipe that is the start of the ssd1306xled loop.  Both put up some text twice and put up BMP's twice so it is a similar work cycle.

By the way when I ran the OLD library on my UNO it ran twice as fast as the pro - much smoother and no screen bugs.  Something about the false/software I2C interface was holding it back and also injecting some garbage.  This implementation is 'apparently' superior in many ways.

If anyone looks into the GitHub code there is a working sample and if placed in your path as follows it should work.
Quote
...\Digistump_Arduino\hardware\digistump\avr\libraries\ssd1306xled

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #4 on: January 12, 2015, 03:53:21 am »
Started with this on my updated Serial debug OLED - The library doesn't have standard system support for print() - so no already included number print conversions - okay for my serial debugger as it just prints what it gets.

A problem on the old display was running beyond the screen bottom would put it into "HUD" mode - upside down and mirrored.  So the characters needed counting before or while printing - this makes that hands on easier.

It can print strings and characters, set screen position for those functions that don't include that (based on font 6x6 or 8x16).  Clear screen is fast. But making up functions when needed will take back the 'free space' gained.  It cannot print F() stored strings - but it also stores image data in PROGMEM, so that might offer a place for strings.  F() made the CDC library fail to print them when RAM or 'something' got tight - and Digistump got the idea that printing them slowly helped - but I found they worked fast or not at all near 290-300 bytes RAM.

Might end up replacing the I2C command code from MicrOled with this as it has some alternative to Wire library that shows huge speed efficiency.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #5 on: January 12, 2015, 07:14:56 pm »
This worked for CDC sort of like an none macro version of F() [not sure if it is otherwise different]:
Code: [Select]
const char HEADER[]  PROGMEM  = { "-A--B---C----D-----E=A==B===C====D=====E"};
__FlashStringHelper* HP_columns = (__FlashStringHelper*)HEADER;
_

It does not work to send to OLED - like F() doesn't - in place of a string.

I got this to work and it saves RAM - not sure it is optimal yet:
Code: [Select]
const char P_line1[] PROGMEM = "String 0";
const char P_Hello[] PROGMEM = "Hello World";
const char P_Tinu[] PROGMEM = "Tinusaur";
const char P_Pro[] PROGMEM = "DigiSpark Pro!";
const char P_Test[] PROGMEM = "testing 1 2 3";
char PszBuff[21];
#define GetPsz( x ) (strcpy_P(PszBuff, (char*)x))  // 5242  and 114 RAM

SSD1306.ssd1306_string_font6x8( GetPsz( P_Hello ));
SSD1306.ssd1306_char_f8x16(64, 0, GetPsz(P_Tinu ));
 
*use of strcpy_P seemed to bring in 150 bytes of code, it (like anything) requires the buffer (PszBuff[]) to pull into.  So F() will have to allocate a buffer on demand as well it seems - and something about F() was oddly breaking my CDC examples use of those string (while all else worked) when ram was pushing up to 300 bytes - maybe from that allocation.  Something else even in this usage is adding some RAM overhead that I didn't see yet.  I made this a #define after I made it a function and it seemed to be more code efficient as a #define:
Code: [Select]
char * GetPsz( const char * ccSz )
{ return strcpy_P(PszBuff, (char*)ccSz);}
« Last Edit: January 13, 2015, 12:41:26 pm by defragster »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #6 on: January 12, 2015, 09:29:43 pm »
F() is tied to print - you can probably import the print library into this - look at CDC for an idea of how to - that said, print library adds lots of overhead which is probably most of the RAM and Flash savings you see with this

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #7 on: January 13, 2015, 01:23:00 am »
This one is so small (2k minimal) it should run on DigiSpark Original if not bloated.

It must have it's own ATtiny wire code in for I2C to do writes - and based on the other OLED's spotty (literal dots) performance - larger size and slower screen control - it seems like it is doing some things very right.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #8 on: January 14, 2015, 02:17:19 am »
Seems there is an I2C conflict a an :( OLED update after setup for 9DOF example takes the display offline  :(

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #9 on: January 15, 2015, 12:26:24 am »
DigiStump rewriting with common wire interface - it is working it seems, may be in the pending release.

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #10 on: January 15, 2015, 09:04:18 am »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SSD1306 OLED support small enough for Tiny86 Ported
« Reply #11 on: January 15, 2015, 11:54:51 pm »
New library looking good - small RAM footprint - Code in my example near minimal with the large 8X16 fonts compiled out saves 1,700 bytes with F():

Quote
Sketch uses 4,636 bytes (31%) of program storage space. Maximum is 14,844 bytes.
Global variables use 57 bytes of dynamic memory.

Only small Font 6X8 and no F() usage:
Quote
Sketch uses 2,962 bytes (19%) of program storage space. Maximum is 14,844 bytes.
Global variables use 53 bytes of dynamic memory.

Using strcpy_P macro and one time re-usable RAM 21 byte buffer (for largest string) instead of F() only small fonts:
Quote
Sketch uses 3,012 bytes (20%) of program storage space. Maximum is 14,844 bytes.
Global variables use 74 bytes of dynamic memory.

With large and small font compiled in and F() used:
Quote
Sketch uses 6,336 bytes (42%) of program storage space. Maximum is 14,844 bytes.
Global variables use 57 bytes of dynamic memory.

Dropping F() takes out 1,674 bytes, this with large fonts:
Quote
Sketch uses 4,662 bytes (31%) of program storage space. Maximum is 14,844 bytes.
Global variables use 53 bytes of dynamic memory.



Code: [Select]
#include <DigisparkOLED.h>
#include <Wire.h>

void setup() {
  oled.begin();
  oled.setFont(FONT8X16);
  oled.println(millis());
}

byte bCursor = 0x20;
// the loop routine runs over and over again forever:
void loop() {
  oled.setCursor(0, 2); //top left
  oled.println(millis());
  oled.write(10);  // write NewLine [save 30 bytes over println]
  oled.print(F("NO Serial"));
  delay(1000);               // keep usb alive // can alos use SerialUSB.refresh();
  oled.write(bCursor = ~bCursor);  // Toggle 'SPACE' with some whitish char 223.
}

Code: [Select]
const char P_No_Serial[] PROGMEM = "No Serial";
char PszBuff[21];   // RAM buffer - but reusable for any string
#define GetPsz( x ) (strcpy_P(PszBuff, (char*)x))

oled.print(GetPsz(P_No_Serial)); 

.vs.

const char HEADER[]  PROGMEM  = { "NO Serial"};
__FlashStringHelper* No_Serial = (__FlashStringHelper*)HEADER;

oled.print(No_Serial);

.vs.
oled.print(F("NO Serial"));
« Last Edit: January 16, 2015, 12:37:29 am by defragster »