Skip to content

Commit bd28d2b

Browse files
committed
Add OLED I2C display example
1 parent f1b7e29 commit bd28d2b

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/***********************************************************************|
2+
| TinyWSoftware i2c master library for ATtiny13 |
3+
| |
4+
| i2c_oled.ino (by Dhiru Kholia - VU3CER) |
5+
| |
6+
| Based on https://github.com/wagiminator/ATtiny13-TinyOLEDdemo (by |
7+
| Stefan Wagner - wagiminator) |
8+
| |
9+
| In this example we drive a 0.96" OLED Display Module over I2C. |
10+
| |
11+
| SERIAL REMINDER |
12+
| The baud rate is ignored on the ATtiny13 due to using a simplified |
13+
| serial. The baud rate used is dependent on the processor speed. |
14+
| Note that you can specify a custom baud rate if the following ones |
15+
| does not fit your application. |
16+
| |
17+
| THESE CLOCKS USES 115200 BAUD: THIS CLOCK USES 57600 BAUD: |
18+
| 20 MHz, 16 MHz, 9.6 MHz, 8 MHz 4.8 MHz |
19+
| THESE CLOCKS USES 19200 BAUD: THIS CLOCK USES 9600 BAUD: |
20+
| 1.2 MHz, 1 MHz 600 KHz |
21+
| |
22+
| If you get garbage output: |
23+
| 1. Check baud rate as above |
24+
| 2. Check if you have anything else connected to TX/RX like an LED |
25+
| 3. Check OSCCAL (see MicroCore OSCCAL tuner example) |
26+
|***********************************************************************/
27+
28+
#include <TinyWire.h>
29+
30+
// We have to define which pins to use for SDA and SCL
31+
const uint8_t TinyWire::SCL = 3;
32+
const uint8_t TinyWire::SDA = 4;
33+
34+
// Sets the i2c clock speed in [Hz]
35+
// Use MAX_SPEED for the highest possible clock speed
36+
const uint32_t TinyWire::FREQ = 100000;
37+
38+
// OLED definitions
39+
#define OLED_ADDR 0x3C // OLED write address - for '0.96" OLED Display Module'
40+
#define OLED_CMD_MODE 0x00 // set command mode
41+
#define OLED_DAT_MODE 0x40 // set data mode
42+
#define OLED_INIT_LEN 14 // 12: no screen flip, 14: screen flip
43+
44+
// OLED init settings
45+
const uint8_t OLED_INIT_CMD[] PROGMEM = {
46+
0xA8, 0x1F, // set multiplex (HEIGHT-1): 0x1F for 128x32, 0x3F for 128x64
47+
0x22, 0x00, 0x03, // set min and max page
48+
0x20, 0x00, // set horizontal memory addressing mode
49+
0xDA, 0x02, // set COM pins hardware configuration to sequential
50+
0x8D, 0x14, // enable charge pump
51+
0xAF, // switch on OLED
52+
0xA1, 0xC8 // flip the screen
53+
};
54+
55+
// standard ASCII 5x8 font (adapted from Neven Boyanov and Stephen Denne)
56+
const uint8_t OLED_FONT[] PROGMEM = {
57+
0x00, 0x00, 0x00, 0x00, 0x00, // 0
58+
0x00, 0x00, 0x2f, 0x00, 0x00, // ! 1
59+
0x00, 0x07, 0x00, 0x07, 0x00, // " 2
60+
0x14, 0x7f, 0x14, 0x7f, 0x14, // # 3
61+
0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 4
62+
0x62, 0x64, 0x08, 0x13, 0x23, // % 5
63+
0x36, 0x49, 0x55, 0x22, 0x50, // & 6
64+
0x00, 0x05, 0x03, 0x00, 0x00, // ' 7
65+
0x00, 0x1c, 0x22, 0x41, 0x00, // ( 8
66+
0x00, 0x41, 0x22, 0x1c, 0x00, // ) 9
67+
0x14, 0x08, 0x3E, 0x08, 0x14, // * 10
68+
0x08, 0x08, 0x3E, 0x08, 0x08, // + 11
69+
0x00, 0x00, 0xA0, 0x60, 0x00, // , 12
70+
0x08, 0x08, 0x08, 0x08, 0x08, // - 13
71+
0x00, 0x60, 0x60, 0x00, 0x00, // . 14
72+
0x20, 0x10, 0x08, 0x04, 0x02, // / 15
73+
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16
74+
0x00, 0x42, 0x7F, 0x40, 0x00, // 1 17
75+
0x42, 0x61, 0x51, 0x49, 0x46, // 2 18
76+
0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19
77+
0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20
78+
0x27, 0x45, 0x45, 0x45, 0x39, // 5 21
79+
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22
80+
0x01, 0x71, 0x09, 0x05, 0x03, // 7 23
81+
0x36, 0x49, 0x49, 0x49, 0x36, // 8 24
82+
0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25
83+
0x00, 0x36, 0x36, 0x00, 0x00, // : 26
84+
0x00, 0x56, 0x36, 0x00, 0x00, // ; 27
85+
0x08, 0x14, 0x22, 0x41, 0x00, // < 28
86+
0x14, 0x14, 0x14, 0x14, 0x14, // = 29
87+
0x00, 0x41, 0x22, 0x14, 0x08, // > 30
88+
0x02, 0x01, 0x51, 0x09, 0x06, // ? 31
89+
0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32
90+
0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33
91+
0x7F, 0x49, 0x49, 0x49, 0x36, // B 34
92+
0x3E, 0x41, 0x41, 0x41, 0x22, // C 35
93+
0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36
94+
0x7F, 0x49, 0x49, 0x49, 0x41, // E 37
95+
0x7F, 0x09, 0x09, 0x09, 0x01, // F 38
96+
0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39
97+
0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40
98+
0x00, 0x41, 0x7F, 0x41, 0x00, // I 41
99+
0x20, 0x40, 0x41, 0x3F, 0x01, // J 42
100+
0x7F, 0x08, 0x14, 0x22, 0x41, // K 43
101+
0x7F, 0x40, 0x40, 0x40, 0x40, // L 44
102+
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45
103+
0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46
104+
0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47
105+
0x7F, 0x09, 0x09, 0x09, 0x06, // P 48
106+
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49
107+
0x7F, 0x09, 0x19, 0x29, 0x46, // R 50
108+
0x46, 0x49, 0x49, 0x49, 0x31, // S 51
109+
0x01, 0x01, 0x7F, 0x01, 0x01, // T 52
110+
0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53
111+
0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54
112+
0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55
113+
0x63, 0x14, 0x08, 0x14, 0x63, // X 56
114+
0x07, 0x08, 0x70, 0x08, 0x07, // Y 57
115+
0x61, 0x51, 0x49, 0x45, 0x43, // Z 58
116+
0x00, 0x7F, 0x41, 0x41, 0x00, // [ 59
117+
0x02, 0x04, 0x08, 0x10, 0x20, // \ 60
118+
0x00, 0x41, 0x41, 0x7F, 0x00, // ] 61
119+
0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62
120+
0x40, 0x40, 0x40, 0x40, 0x40 // _ 63
121+
};
122+
123+
// messages to print on OLED
124+
const char Message1[] PROGMEM = "HELLO WORLD! :)";
125+
126+
// OLED init function
127+
void OLED_init(void) {
128+
Wire.beginTransmission(OLED_ADDR);
129+
Wire.write(OLED_CMD_MODE); // set command mode
130+
for (uint8_t i = 0; i < OLED_INIT_LEN; i++)
131+
Wire.write(pgm_read_byte(&OLED_INIT_CMD[i])); // send the command bytes
132+
Wire.endTransmission(); // initialize I2C first
133+
}
134+
135+
// OLED set vertical shift
136+
void OLED_shift(uint8_t ypos) {
137+
Wire.beginTransmission(OLED_ADDR); // start transmission to OLED
138+
Wire.write(OLED_CMD_MODE); // set command mode
139+
Wire.write(0xD3); // vertical shift command
140+
Wire.write(ypos); // set vertical shift value
141+
Wire.endTransmission(); // stop transmission
142+
}
143+
144+
// OLED print a character
145+
void OLED_printC(char ch) {
146+
uint16_t offset = ch - 32; // calculate position of character in font array
147+
offset += offset << 2; // -> offset = (ch - 32) * 5
148+
Wire.write(0x00); // print spacing between characters
149+
for (uint8_t i = 5; i; i--) Wire.write(pgm_read_byte(&OLED_FONT[offset++])); // print character
150+
}
151+
152+
// OLED print a string from program memory
153+
void OLED_printP(const char* p) {
154+
Wire.beginTransmission(OLED_ADDR); // start transmission to OLED
155+
Wire.write(OLED_DAT_MODE); // set data mode
156+
char ch = pgm_read_byte(p); // read first character from program memory
157+
while (ch != 0) { // repeat until string terminator
158+
OLED_printC(ch); // print character on OLED
159+
ch = pgm_read_byte(++p); // read next character
160+
}
161+
Wire.endTransmission(); // stop transmission
162+
}
163+
164+
// OLED set the cursor
165+
void OLED_cursor(uint8_t xpos, uint8_t ypos) {
166+
Wire.beginTransmission(OLED_ADDR); // start transmission to OLED
167+
Wire.write(OLED_CMD_MODE); // set command mode
168+
Wire.write(xpos & 0x0F); // set low nibble of start column
169+
Wire.write(0x10 | (xpos >> 4)); // set high nibble of start column
170+
Wire.write(0xB0 | (ypos & 0x07)); // set start page
171+
Wire.endTransmission(); // stop transmission
172+
}
173+
174+
// OLED clear screen
175+
void OLED_clear(void) {
176+
OLED_cursor(0, 0); // set cursor at upper left corner
177+
Wire.beginTransmission(OLED_ADDR); // start transmission to OLED
178+
Wire.write(OLED_DAT_MODE); // set data mode
179+
for (uint16_t i = 512; i; i--) Wire.write(0x00); // clear the screen
180+
Wire.endTransmission(); // stop transmission
181+
OLED_shift(0); // reset vertical shift
182+
}
183+
184+
void setup()
185+
{
186+
// No baudrate to select. See header for details
187+
Serial.begin();
188+
Serial.println(F("Check you OLED screen..."));
189+
OLED_init();
190+
}
191+
192+
void loop()
193+
{
194+
while (1) {
195+
OLED_clear(); // clear screen
196+
OLED_cursor(0, 0); // set cursor position
197+
OLED_printP(Message1); // print message 1
198+
delay(5000);
199+
}
200+
}

0 commit comments

Comments
 (0)