UPDATE: Please check the most recent post about this library at /tag/ssd1306xled
I recently bought an OLED display 128×64 from eBay (http://www.ebay.com/sch/i.html?_nkw=OLED+128) – very inexpensive (about 4 euro) but when I finally received it I was surprised to see how small it was – I was expecting something that looked more like the Nokia 3310 LCD. So I thought – this is perfect for the Tinusaur Project. The 128×64 OLED is controlled by an SSD1306 circuit and could be interfaced over I²C. The first challenge that I faced was that all existing libraries that I found were for Arduino boards … and I wrote my own based, of course, on existing code – the SSD1306xLED library.
SSD1306xLED is a C library for working with the SSD1306 display driver to control dot matrix OLED/PLED 128×64 displays. It is intended to be used with the Tinusaur board but should also work with any other board based on ATtiny85 or similar microcontroller – ATtiny45/ATtiny25, even ATtiny13.
The code could be divided into 3 pieces: (1) communication over I²C with the SSD1306; (2) sending graphical commands to the display; (3) high-level functions such as printing characters.
The I²C communication part is based on modified IIC_wtihout_ACK library that is available on the Internet but its original website (http://www.14blog.com/archives/1358) is no longer functional. Basically, it made it work on ATtiny85 and Tinusaur.
The SSD1306xLED library still needs work and improvements.
The main location for the library is SSD1306xLED page.
The source code along with very simple example is available on Bitbucket at this address: https://bitbucket.org/tinusaur/ssd1306xled
Neven, Thanks for your good work. I’m interfacing your SSD1306 C library to a simple thermometer on an 85 using Atmel Studio 7. I’m trying to invoke the 8X16 font for numbers. I see the 8X16 routines are commented as “DOES NOT WORK”. Do you have any suggestions for what I can do to patch this? Maybe this has already been solved elsewhere?
Currently I’m debuging how the 6×8 font works. I tried a parallel structure for 8X16 and it worked for Strings. Now I’m trying to invoke the padding routine for numbers. Not making very good progress for days now. Thanks again!
Hi Craig,
Thanks for the good words.
I have not worked on this library for about 2 years but if I remember correctly the 8×16 font is double height. For some reason, it did not work back then.
Did you try the ssd1306_string_font8x16xy function?
Hi Neven,
Thanks for the response and Happy New Year to you too.
Iâm away from home and not able to get to my boards or records. I have found a condensed library that works for very large font on the SSD1306 and works for the Attiny85 per https://www.youtube.com/watch?v=mKPKQm0uPBQ That project was in ArduinoIDE and I think I converted it to a C project in Atmel Studio 7 IDE. I will follow-up with your new Bitbucket reference when I get a chance and can get back to that project. Attiny85 and the SSD1306 â what a great tiny combination!
Craig
The routine for printing number has been moved to another library and extended with more functionality.
https://bitbucket.org/tinusaur/tinyavrlib
TinyAVRLib / tinyavrlib / num2str.c
Hi Neven,
Thanks for the response and Happy New Year to you too.
I’m away from home and not able to get to my boards or records. I have found a condensed library that works for very large font on the SSD1306 and works for the Attiny85 per https://www.youtube.com/watch?v=mKPKQm0uPBQ That project was in ArduinoIDE and I think I converted it to a C project in Atmel Studio 7 IDE. I will follow-up with your new Bitbucket reference when I get a chance and can get back to that project. Attiny85 and the SSD1306 – what a great tiny combination!
Craig
Neven, I’m back at it. So I think I see how this works. Yes, I had used the ssd1306_string_font8x16xy function successfully because of your helpful example program. If I understand this correctly to implement the 8X16 font for numbers I need to change the numbers to strings with num2str. The 6X8 font treats numbers and strings with one routine for numbers and one for strings and the 8X16 sends both numbers and strings to the same string routine, right? Is there an example that demonstrates this?
Neven, I now can print numbers in the larger font. I tried to treat the numbers like strings after the int2decascii conversion. This required changing a few of your routines. My main routine looks a bit different too. I think I tried to mimic the code pattern in your 6X8 number handler, only with the double routine needed to bridge two “pages” (rows) of the SSD1306 for the larger font. Maybe this helps others using your code:
From main I call ssd1306_string_font8x16 with screen location arguements 6, 0.
_____________________________
ssd1306_string_font8x16(6, 0, ssd1306_numdec_buffer);
_____________________________
Then, I parse the characters out in this routine before sending to the
ssd1306_char_font8x16 routine.
_____________________________
void ssd1306_string_font8x16(uint8_t jx,uint8_t jy, const char s[]) { // S[] is the character array
while (*s) {
ssd1306_char_font8x16(*s++,jx,jy);
jx += 1;
}
}
_____________________________
Some of the variables have changed a bit from what you were using.
_____________________________
void ssd1306_char_font8x16(char ch, uint8_t x, uint8_t y) {
uint8_t c = ch – 32;
x = 1+(8*x); //x dimension control for character positioning
ssd1306_setpos(x, y);
ssd1306_send_data_start();
for (uint8_t i = 0; i < 8; i++) {
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i])); //Upper half of one digit
} //[c * 16 + i] – selects the font element from the font table
ssd1306_send_data_stop();
ssd1306_setpos(x, y+1); //Second half
ssd1306_send_data_start();
for (uint8_t i = 0; i < 8; i++) {
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i + 8])); //Lower half of one digit
}
ssd1306_send_data_stop();
}
_______________________________
Hope it helps someone.