ATTiny85 Connects to I2C OLED Display - Great Things Can Be Small

About: Electronics is great! http://CoPiino.cc

Intro: ATTiny85 Connects to I2C OLED Display - Great Things Can Be Small

I recently came across a tiny OLED display which I also used for another project. This time I thought a tiny display can be driven by an [AT]Tiny processor :).

The vision is - "create a tiny gaming machine"

Well the first step is taken. At least something is happening on the display. Feel free to suggest a game idea.


Parts we need

  • ATTiny85 break out board - CoPiino Connectable BrainZ from ebay ($6)
  • OLED Display with SSD1306 driver from ebay ($5)
  • AVR Programmer USBasp from ebay ($4)
  • 5V/3.3V regulated voltage source
  • some jumper wires
  • Arduino IDE

Attention: The display module I used had an operation range from +3.3V to +5V. So I could easily connect +5V. You need to carefully check if your display also supports +5V otherwise use a regulated +3.3V power source !!

Edit:

  • uploaded additional target project => demo for font and icons
  • uploaded some pictures for font and icons

Step 1: Soldering the Board

The CoPiino Connectable BrainZ comes as soldering kit. So it needs some soldering. All parts are through-hole and can be soldered old fashioned with soldering iron.

Scope of supply:

  • PCB 21x28mm with M3 fixing hole
  • 1x ATTiny85-20PU
  • 1x LED 3mm yellow
  • 1x Resistor 1k
  • 3x Resistors 4.7k
  • 2x Capacitors 100nF
  • 1x pin header angled 1x4
  • 1x pin header angled 1x5
  • 1x Straight header
  • 2x3 (AVR ISP)
  • 1x Receptacle angled 1x4

It took me 20mins to solder all parts.

Step 2: Programming the CoPiino Connectable BrainZ

This step is pretty forward. The required source code is attached to this step. All files need be extracted.

Included files are

  • ATTiny_OLED_Bouncing_Ball.ino
  • SSD1306_minimal.cpp
  • SSD1306_minimal.h
  • TinyWireM.cpp
  • TinyWireM.h
  • USI_TWI_Master.cpp
  • USI_TWI_Master.h

1. With the Arduino IDE we open the ATTiny_OLED_Bouncing_Ball.ino

2. We need to use the menu "Sketch" - "Add File ... " and add all other files one by one

3. Connect the CoPiino Connectable BrainZ to the USBasp (see notes below)

4. Connect USBasp preferably to a USB hub

5. Arduino IDE: Compile and Upload

6. Check for completed Upload

7. Disconnect USB

8. done

notes:

For connecting the USBasp to the CoPiino Connectable BrainZ we apply these pin connections

ISP10PIN to ISP6PIN

Pin 9 to 1 [MISO]

Pin 2 to 2 [VCC]

Pin 7 to 3 [SCK]

Pin 1 to 4 [MOSI]

Pin 5 to 5 [RST]

Pin 2 to 6 [GND]

Step 3: Connect and Run

The display will be connected through I2C / TWI which are the signales SDA/SCL. Additionally we draw VCC and GND from the CoPiino Connectable BrainZ to the display. So all toghether we have 4 single cables between display and BrainZ.

Attention: The display module I used had an operation range from +3.3V to +5V. So I could easily connect +5V. You need to carefully check if your display also supports +5V otherwise use a regulated +3.3V power source !!

We then use our 5V/3.3V regulated power source and inject GND and VCC into the appropriate pins at the BrainZ module.

You will be enlightened by the nice moving ball in a grid on the display.

Congrats!

Now its time to make the next step. Any gaming idea that can be implemented?

5 People Made This Project!

Recommendations

  • Audio Contest 2018

    Audio Contest 2018
  • Metalworking Contest

    Metalworking Contest
  • Tiny Home Contest

    Tiny Home Contest

53 Discussions

0
None
VolosR

1 year ago

Can you help me please. I have 128x32 display conected to Attiny85 and your library works, but text is very hard to read beacouse diferent screen size. Can you help me modify your library to fit 128x32 screen OLED display. Tnx

3 replies
0
None
tswaehnVolosR

Reply 8 months ago

What is the display model number?

0
None
tswaehnVolosR

Reply 1 year ago

Hi,
Sure, we can do. Please send a picture,what it looks like.

0
None
AlexFW

1 year ago

Hi, I have had a lot of success with your library on ATtiny85. Now I'm trying to get it to work on the ATtiny84 as well. I cannot compile any sketches that work on tiny85 because for some reason the lines of code with the USI are not working. I thought that since tiny84 and tiny85 both use a USI rather than physical I2C support this should work... The error message is below. Thanks!

/var/folders/tr/zp_0970j0ld4_wq_yx8vnw_r0000gn/T/arduino_build_400141/sketch/USI_TWI_Master.cpp: In function 'void USI_TWI_Master_Initialise()':

USI_TWI_Master.cpp:52: error: 'PORT_USI' was not declared in this scope

PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.

^

USI_TWI_Master.cpp:52: error: 'PIN_USI_SDA' was not declared in this scope

PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.

^

USI_TWI_Master.cpp:53: error: 'PIN_USI_SCL' was not declared in this scope

PORT_USI |= (1<<PIN_USI_SCL); // Enable pullup on SCL, to set high as released state.

^

USI_TWI_Master.cpp:55: error: 'DDR_USI' was not declared in this scope

DDR_USI |= (1<<PIN_USI_SCL); // Enable SCL as output.

^

/var/folders/tr/zp_0970j0ld4_wq_yx8vnw_r0000gn/T/arduino_build_400141/sketch/USI_TWI_Master.cpp: In function 'unsigned char USI_TWI_Start_Transceiver_With_Data(unsigned char*, unsigned char)':

USI_TWI_Master.cpp:200: error: 'PORT_USI' was not declared in this scope

PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.

^

USI_TWI_Master.cpp:200: error: 'PIN_USI_SCL' was not declared in this scope

PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.

^

USI_TWI_Master.cpp:205: error: 'DDR_USI' was not declared in this scope

DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.

^

USI_TWI_Master.cpp:205: error: 'PIN_USI_SDA' was not declared in this scope

DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.

^

USI_TWI_Master.cpp:238: error: 'DDR_USI' was not declared in this scope

DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.

^

USI_TWI_Master.cpp:238: error: 'PIN_USI_SDA' was not declared in this scope

DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.

^

/var/folders/tr/zp_0970j0ld4_wq_yx8vnw_r0000gn/T/arduino_build_400141/sketch/USI_TWI_Master.cpp: In function 'unsigned char USI_TWI_Master_Transfer(unsigned char)':

USI_TWI_Master.cpp:280: error: 'PIN_USI' was not declared in this scope

while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.

^

USI_TWI_Master.cpp:280: error: 'PIN_USI_SCL' was not declared in this scope

while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.

^

USI_TWI_Master.cpp:288: error: 'DDR_USI' was not declared in this scope

DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.

^

USI_TWI_Master.cpp:288: error: 'PIN_USI_SDA' was not declared in this scope

DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.

^

/var/folders/tr/zp_0970j0ld4_wq_yx8vnw_r0000gn/T/arduino_build_400141/sketch/USI_TWI_Master.cpp: In function 'unsigned char USI_TWI_Master_Start()':

USI_TWI_Master.cpp:298: error: 'PORT_USI' was not declared in this scope

PORT_USI |= (1<<PIN_USI_SCL); // Release SCL.

5 replies
0
None
tswaehnAlexFW

Reply 1 year ago

Hi Alex,

thanks for you message. I pretty much thing you have your fingers at absolute correct location. Its only about the definition of pinnings for the serial transfer unit. I know a lot about TINY85, but not yet had much to do with the TINY84. BUT I guess its just a matter of naming, ...

0
None
tswaehntswaehn

Reply 1 year ago

Hi Alex,

according to the web the naming is different from Tiny85 to Tiny84. Additionally some registers are missing. Porting the programs from Tiny85 to Tiny84 seems to be more than re-compiling - unfortunately. :(

0
None
AlexFWtswaehn

Reply 1 year ago

Thanks for your response. Adding those pin definitions for (__AVR_ATtiny84__) | defined(__AVR_ATtiny44__) worked perfectly. It actually does look like direct ports of previous sketches are possible. Since the definitions you provided are independent of the ATtiny core in use it should work with any core, right?

0
None
tswaehnAlexFW

Reply 1 year ago

yes, this should work generally to port code from ATiny85 to ATiny84.

0
None
tswaehnAlexFW

Reply 1 year ago

Did you try to use these renames?

#if defined(__AVR_ATtiny84__) | defined(__AVR_ATtiny44__)

#define DDR_USI DDRA

#define PORT_USI PORTA

#define PIN_USI PINA

#define PORT_USI_SDA PORTA6

#define PORT_USI_SCL PORTA4

#define PIN_USI_SDA PINA6

#define PIN_USI_SCL PINA4

#endif

0
None
codebeat

1 year ago

Update: I discover there is a memory leak (or something else) in the library or code that freeze the attiny85 after approx one hour of running the code. Anyone else experienced this?

1 reply
0
None
tswaehncodebeat

Reply 1 year ago

This can also be some electrics communication issue and lockup :)

0
None
codebeat

1 year ago

Thank you for the nice and easy to understand code. I ordered some
displays (white and blue) to use on a DigiSpark and a DigiSpark clone.
It seems to be a little different and you need to add some pull up
resistors (the 4.7K ones) to get it to work. I solder these two
resistors onto the display board (to the data header pins, between +5V
and the data header pins) directly. On the DigiSpark you must use P0 and
P2 as I2C data lines, P0=SDA and P2=SLC/SLK.

To speed up screen updates (processor speed), to get the full speed potentional out of it, I use this code:

void setMaxClockSpeed()
{
// Examine Page 33
CLKPR = 0x80; // Setup CLKPCE to be receptive
CLKPR = 0x00; // No scalar

// Maximum clock speeds!
PLLCSR = _BV(PLLE) | _BV( PCKE );
OSCCAL = 0xff;
}

You can call this at the setup routine and the animation is twice the speed! Pretty amazing stuff.

0
None
ceptimus

1 year ago

Hi. Thanks for excellent tutorial. I'd already got a simple 'blink' sketch running on my ATtiny85. When I connected the OLED and tried your code it all worked perfectly first try. Saved me hours struggling how to configure the TinyWireM library to run at 16MHz and then figuring out how to use it with the SSD1306. :)

1 reply
0
None
tswaehnceptimus

Reply 1 year ago

Thank that's nice to hear!

Let me know what cool things you are doing with it.

0
None
AlexFW

1 year ago

Hi - great tutorial. I got it working.

Now I'm struggling to get images to display correctly. Can you describe your workflow for making the byte arrays? Whenever I use http://manytools.org/hacker-tools/image-to-byte-array/ to make my own I always get a random assortment of pixels in the correct size. I have figured out that the width is the width in pixels and the height is the height in pixels/8.

4 replies
0
None
tswaehnAlexFW

Reply 1 year ago

Hi Alex,
Yeah that's right. It can be tricky to display images. It usually something with byte order and endianess.

The ssd1306 is configured that way
(1) As far as I remember the first byte starts top left corner.
(2) the display reads bytes from left to right
(3) the display reads lines from top to bottom

So basically we need a byte stream in that order - that's it

(4) I am unsure about byte endianess - I think it was byte0 - bit7 that sits on pixel (0,0) - so this should be LSB first.

Hope that helps at least a little :)

Let me know how things are and if a deeper look from my side can be of some help here.

0
None
AlexFWtswaehn

Reply 1 year ago

I've tried tons of different image to hex array converters, but none of them seem to function. All of them display a seemingly random assortment of pixels, except for solid white or solid black images, which makes sense. I've tried both the methods listed here: https://learn.adafruit.com/mini-thermal-receipt-printer/bitmap-printing , as well as a few online converters. All display the pixels in an incorrect order, which leads me to believe that the order they're encoded is not as you listed. Can you please share what tool you used to convert the images to hex arrays?

0
None
AlexFWAlexFW

Reply 1 year ago

Aha! I've finally gotten it! Every single tutorial and page I've ever seen says the image orientation needs to be horizontal for the OLED to display it correctly. Out of desperation I tried vertical orientation ONCE and it appears to be working.

0
None
tswaehnAlexFW

Reply 1 year ago

that's great that you got it working. I did use some Linux tool, but remember to have changed the bit order from MSB to LSB.

If you can,... send some pictures - would be great!!