Forum: Mikrocontroller und Digitale Elektronik Größere Schriftart für Crius OLED


von Stefan S. (kami)


Lesenswert?

Hi zusammen,

ich habe hier an einem Atmega328 mit Arduino ein 128x64 Crius OLED per 
I2C angeschlossen. Das Display läuft mit folgendem Code super aber die 
Fonts sind mir auf dem Display zu klein. Zurzeit habe ich 16 Zeichen auf 
8 Reihen. Ich würde aber gern etwas größere Zeichen einfügen. Kann mir 
jemand sagen wie ich das hinkriege? Kenne mich mit Fonts und so nicht 
aus.

Gruß kami
1
#include <avr/pgmspace.h>
2
#include <avr/io.h>
3
4
#define OLED_address  0x3c
5
#define INTERNAL_I2C_PULLUPS
6
7
//---------------FONT + GRAPHIC-----------------------------//
8
9
char buffer[8];
10
unsigned char fill_OLED=0x55;
11
unsigned char empty_string[]="               ";
12
unsigned char empty_string2[]="Test1          ";
13
unsigned char empty_string3[]="Test2          ";
14
//unsigned char myFont[][8] = {
15
prog_uchar myFont[][8] PROGMEM ={
16
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
18
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
19
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
20
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
21
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
22
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
23
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
24
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
25
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
26
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
27
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
28
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
29
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
30
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
31
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
32
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
33
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
34
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
35
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
36
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
37
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
38
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
39
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
40
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
41
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
42
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
43
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
44
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
45
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
46
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
47
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
48
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
49
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
50
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
51
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
52
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
53
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
54
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
55
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
56
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
57
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
58
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
59
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
60
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
61
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
62
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
63
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
64
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
65
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
66
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
67
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
68
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
69
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
70
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
71
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
72
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
73
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
74
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
75
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
76
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
77
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
78
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
79
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
80
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
81
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
82
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
83
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
84
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
85
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
86
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
87
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
88
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
89
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
90
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
91
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
92
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
93
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
94
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
95
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
96
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
97
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
98
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
99
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
100
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
101
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
102
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
103
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
104
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
105
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
106
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
107
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
108
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
109
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
110
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
111
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00} 
112
};
113
114
//==========================================================//
115
116
117
void setup()
118
{
119
  
120
  i2c_init();
121
  init_OLED();
122
  delay(10);
123
  clear_display();
124
  delay(50);
125
126
  sendcommand(0x20);            //Set Memory Addressing Mode
127
  sendcommand(0x02);            //Set Memory Addressing Mode ab Page addressing mode(RESET)  
128
129
  sendcommand(0xa6);            //Set Normal Display (default)
130
  
131
132
  
133
  
134
}
135
136
void loop() {
137
138
139
clear_display();
140
  //====================SHOW FONTS ARRAY[1-4]=======================//
141
  setXY(2,0);
142
143
  sendStr((unsigned char *)empty_string2);
144
  setXY(4,0);
145
146
  sendStr((unsigned char *)empty_string3);
147
  
148
  
149
150
 
151
 delay(2000);
152
153
 
154
}
155
156
157
// OLED
158
159
void sendcommand(unsigned char com)
160
{
161
  i2c_OLED_send_cmd(com);  
162
  /*
163
  Wire.beginTransmission(OLED_address);     //begin transmitting
164
  Wire.write(0x80);                          //command mode
165
  Wire.write(com);
166
  Wire.endTransmission();                    // stop transmitting
167
  */
168
}
169
170
//==========================================================//
171
void clear_display(void)
172
{
173
  unsigned char i,k;
174
  for(k=0;k<8;k++)
175
  {  
176
    setXY(k,0);    
177
    {
178
      for(i=0;i<128;i++)     //clear all COL
179
      {
180
        SendChar(0);         //clear all COL
181
        //delay(10);
182
      }
183
    }
184
  }
185
}
186
187
//==========================================================//
188
void clear_line(int line)
189
{
190
  unsigned char i;
191
  
192
    setXY(line,0);    
193
    {
194
      for(i=0;i<128;i++)     //clear all COL
195
      {
196
        SendChar(0);         //clear all COL
197
        //delay(10);
198
      }
199
    }
200
  
201
}
202
//==========================================================//
203
void SendChar(unsigned char data)
204
{
205
  i2c_OLED_send_byte(data);
206
  /*
207
  Wire.beginTransmission(OLED_address); // begin transmitting
208
  Wire.write(0x40);//data mode
209
  Wire.write(data);
210
  Wire.endTransmission();    // stop transmitting
211
  */
212
}
213
214
//==========================================================//
215
void setXY(unsigned char row,unsigned char col)
216
{
217
  sendcommand(0xb0+row);                //set page address
218
  sendcommand(0x00+(8*col&0x0f));       //set low col address
219
  sendcommand(0x10+((8*col>>4)&0x0f));  //set high col address
220
}
221
222
223
//==========================================================//
224
void sendStr(unsigned char *string)
225
{
226
  unsigned char i=0;
227
  //setXY(0,0);    
228
  while(*string)
229
  {
230
    for(i=0;i<8;i++)
231
    {
232
      //SendChar(myFont[*string-0x20][i]);
233
      SendChar(pgm_read_word(&myFont[*string-0x20][i]));
234
     
235
      //delay(10);
236
    }
237
    *string++;
238
  }
239
}
240
241
//==========================================================//
242
void init_OLED(void)
243
{
244
i2c_OLED_init();
245
246
}
247
248
void  i2c_OLED_init(void){
249
  i2c_OLED_send_cmd(0xae);    //display off
250
  i2c_OLED_send_cmd(0x2e);    //deactivate scrolling
251
  i2c_OLED_send_cmd(0xa4);          //SET All pixels OFF
252
//  i2c_OLED_send_cmd(0xa5);            //SET ALL pixels ON
253
  delay(50);
254
  i2c_OLED_send_cmd(0x20);            //Set Memory Addressing Mode
255
  i2c_OLED_send_cmd(0x02);            //Set Memory Addressing Mode to Page addressing mode(RESET)
256
//  i2c_OLED_send_cmd(0xa0);      //colum address 0 mapped to SEG0 (POR)*** wires at bottom
257
  i2c_OLED_send_cmd(0xa1);    //colum address 127 mapped to SEG0 (POR) ** wires at top of board
258
//  i2c_OLED_send_cmd(0xC0);            // Scan from Right to Left (POR)         *** wires at bottom
259
  i2c_OLED_send_cmd(0xC8);          // Scan from Left to Right               ** wires at top
260
  i2c_OLED_send_cmd(0xa6);            // Set WHITE chars on BLACK backround
261
262
 // i2c_OLED_send_cmd(0xa7);            // Set BLACK chars on WHITE backround
263
  i2c_OLED_send_cmd(0x81);            // 81 Setup CONTRAST CONTROL, following byte is the contrast Value
264
  i2c_OLED_send_cmd(0xff);            // af contrast value between 1 ( == dull) to 256 ( == bright)
265
  delay(20);
266
  i2c_OLED_send_cmd(0xaf);          //display on
267
  delay(20);
268
}
269
270
271
// ************************************************************************************************************
272
// I2C general functions
273
// ************************************************************************************************************
274
275
static uint32_t neutralizeTime = 0;
276
static int16_t  i2c_errors_count = 0;
277
278
#define I2C_SPEED 100000L     //100kHz normal mode, this value must be used for a genuine WMP
279
280
#define I2C_PULLUPS_ENABLE         PORTC |= 1<<4; PORTC |= 1<<5;   // PIN A4&A5 (SDA&SCL)
281
#define I2C_PULLUPS_DISABLE        PORTC &= ~(1<<4); PORTC &= ~(1<<5);
282
283
void i2c_init(void) {
284
  #if defined(INTERNAL_I2C_PULLUPS)
285
    I2C_PULLUPS_ENABLE
286
  #else
287
    I2C_PULLUPS_DISABLE
288
  #endif
289
  TWSR = 0;                                    // no prescaler => prescaler = 1
290
  TWBR = ((F_CPU / I2C_SPEED) - 16) / 2;   // change the I2C clock rate
291
  TWCR = 1<<TWEN;                              // enable twi module, no interrupt
292
}
293
294
void i2c_rep_start(uint8_t address) {
295
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) ; // send REPEAT START condition
296
  waitTransmissionI2C();                       // wait until transmission completed
297
  TWDR = address;                              // send device address
298
  TWCR = (1<<TWINT) | (1<<TWEN);
299
  waitTransmissionI2C();                       // wail until transmission completed
300
}
301
302
void i2c_stop(void) {
303
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
304
  //  while(TWCR & (1<<TWSTO));                // <- can produce a blocking state with some WMP clones
305
}
306
307
void i2c_write(uint8_t data ) {  
308
  TWDR = data;                                 // send data to the previously addressed device
309
  TWCR = (1<<TWINT) | (1<<TWEN);
310
  waitTransmissionI2C();
311
}
312
313
uint8_t i2c_read(uint8_t ack) {
314
  TWCR = (1<<TWINT) | (1<<TWEN) | (ack? (1<<TWEA) : 0);
315
  waitTransmissionI2C();
316
  uint8_t r = TWDR;
317
  if (!ack) i2c_stop();
318
  return r;
319
}
320
321
uint8_t i2c_readAck() {
322
  return i2c_read(1);
323
}
324
325
uint8_t i2c_readNak(void) {
326
  return i2c_read(0);
327
}
328
329
void waitTransmissionI2C() {
330
  uint16_t count = 255;
331
  while (!(TWCR & (1<<TWINT))) {
332
    count--;
333
    if (count==0) {              //we are in a blocking state => we don't insist
334
      TWCR = 0;                  //and we force a reset on TWINT register
335
      neutralizeTime = micros(); //we take a timestamp here to neutralize the value during a short delay
336
      i2c_errors_count++;
337
      break;
338
    }
339
  }
340
}
341
void print_a_char(unsigned char ascii=0)
342
{
343
  unsigned char i=0;
344
  for(i=0;i<8;i++)
345
  {
346
    //SendChar(myFont[ascii-0x20][i]);
347
    SendChar(pgm_read_word(&myFont[ascii-0x20][i]));
348
  }
349
}
350
351
size_t i2c_read_to_buf(uint8_t add, void *buf, size_t size) {
352
  i2c_rep_start((add<<1) | 1);  // I2C read direction
353
  size_t bytes_read = 0;
354
  uint8_t *b = (uint8_t*)buf;
355
  while (size--) {
356
    /* acknowledge all but the final byte */
357
    *b++ = i2c_read(size > 0);
358
    /* TODO catch I2C errors here and abort */
359
    bytes_read++;
360
  }
361
  return bytes_read;
362
}
363
364
size_t i2c_read_reg_to_buf(uint8_t add, uint8_t reg, void *buf, size_t size) {
365
  i2c_rep_start(add<<1); // I2C write direction
366
  i2c_write(reg);        // register selection
367
  return i2c_read_to_buf(add, buf, size);
368
}
369
370
/* transform a series of bytes from big endian to little
371
   endian and vice versa. */
372
void swap_endianness(void *buf, size_t size) {
373
  /* we swap in-place, so we only have to
374
  * place _one_ element on a temporary tray
375
  */
376
  uint8_t tray;
377
  uint8_t *from;
378
  uint8_t *to;
379
  /* keep swapping until the pointers have assed each other */
380
  for (from = (uint8_t*)buf, to = &from[size-1]; from < to; from++, to--) {
381
    tray = *from;
382
    *from = *to;
383
    *to = tray;
384
  }
385
}
386
387
void i2c_writeReg(uint8_t add, uint8_t reg, uint8_t val) {
388
  i2c_rep_start(add<<1); // I2C write direction
389
  i2c_write(reg);        // register selection
390
  i2c_write(val);        // value to write in register
391
  i2c_stop();
392
}
393
394
395
void i2c_OLED_send_cmd(uint8_t command) {
396
  TWBR = ((F_CPU / 400000L) - 16) / 2; // change the I2C clock rate
397
  i2c_writeReg(OLED_address, 0x80, (uint8_t)command);
398
}
399
400
void i2c_OLED_send_byte(uint8_t val) {
401
  TWBR = ((F_CPU / 400000L) - 16) / 2; // change the I2C clock rate
402
  i2c_writeReg(OLED_address, 0x40, (uint8_t)val);
403
}

von Karl K. (leluno)


Lesenswert?

mit
1
    for(i=0;i<8;i++)
2
    {
3
      //SendChar(myFont[*string-0x20][i]);
4
      SendChar(pgm_read_word(&myFont[*string-0x20][i]));
5
        //delay(10);
6
    }

wird der font auf das display gezeichnet.

ein font-zeichen sieht in 2bit (3x5) so aus:
0b001,
0b011,
0b001,
0b001,
0b001,//1
Es wird bit für bit auf das display gezeichnet.

wenn du einen anderen Font nehmen willst, musst du die Funktion sendStr 
so anpassen, dass jedes Zeichen des neuen Fonts bitweise gezeichnet 
wird.

Am besten nimmst du dafür eine fertige lib.

von Stefan S. (kami)


Lesenswert?

Hi,

gibt es dafür irgendwelche fertigen libs?

Ich habe ein 128x64 Oled?

Gruß kami

von randy (Gast)


Lesenswert?

hallo,

ich verwende fuer meine crius display die u8glib:

http://code.google.com/p/u8glib/

dort kann man verschiedene fonts verwenden:

http://code.google.com/p/u8glib/wiki/fontsize

gruss,
-- randy

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.