Ciao, sto cercando di capire come si sviluppa una libreria partendo dal datasheet di un determinato componente.
Ho pensato quindi di riscrivermi la libreria per comandare l'LCD, ma sto avendo qualche problema con l'inizializzazione.
Per prima cosa vorrei inizializzare l'LCD per farlo funzionare a 4 bit.
Guardando questo post, Display LCD HD44780: reset software vedo che è stata usata questa routine:
// Reset, 4 bits operation:
delay(20);
command(0x30); // function set: 8 bits
delay(10);
command(0x30); // function set: 8 bits
delay(10);
command(0x30); // function set: 8 bits
delay(10);
command(0x20); // function set: 4 bits
command(0x28); // function set: 4 bits, 1 line, 5x8 dots
command(0x0C); // display control: turn display on, cursor off, no blinking
command(0x06); // entry mode set: increment automatically, display shift, right shift
clear();
Il problema è che non capisco come mai siano state fatte quelle scelte, perché dal datasheet , io leggo(o forse capisco?) tutt'altro.
Prima cosa, nel post viene detto questo "Eseguendo un reset software ora non c'è più alcun problema, è sufficiente inserire nel source file LiquidCrystal.cpp il reset software raccomandato alle pgg. 40 e 41 prima di inizializzare." ma a quelle pagine viene mostrata l'inizializzazione usata dal circuito di reset interno, che però funziona solo se la tensione di alimentazione ha determinate caratteristiche; mentre l'inizializzazione software viene documentata poco più sotto, a pag. 45 e 46 ed è diversa...
Detto questo, i timing usati qui sopra risultano errati, o meglio mi sembrano molto più alti del necessario e anche la sequenza di comandi mi pare errata.
La mia sequenza:
digitalWrite(LCD_E, LOW); // Si assicura che Enable sia 0
digitalWrite(LCD_RS, LOW); // Abilita RS per comando
delayMicroseconds(42000); // Dopo l'alimentazione, aspetta un minimo di 40 ms (datasheet fig.24 pag 46)
lcdWriteH(3); // scrive 0011 su DB7,DB6,DB5,SB4 (datasheet fig.24 pag 46)
delayMicroseconds(4500); // aspetta un min di 4,1ms (datasheet fig.24 pag 46)
lcdWriteH(3);
delayMicroseconds(150); // aspetta minimo 100us (datasheet fig.24 pag 46)
lcdWriteH(3);
lcdWriteH(2); // scrive 0010 su DB7,DB6,DB5,SB4 (datasheet fig.24 pag 46)
// Now is 4 bit mode
lcdSetFunction(0, 1, 0); // 4 bit, 2 lines, 5x8 fonts
lcdSetDisplay(0,0,0); // display off, no cursor, no blink
lcdClear();
lcdSetMode(1,0); // move cursor right, no display shift
Se stampo su seriale i bit che mando come comando risultano perfettamente uguali a quelli del datasheet.
NOTA: dopo ogni write c'è ovviamente un impulso su Enable.
DB7|DB6|DB5|DB4
0|0|1|1|
0|0|1|1|
0|0|1|1|
0|0|1|0|
-----------------
0|0|1|0|
1|0|0|0|
-----------------
0|0|0|0|
1|0|0|0|
-----------------
0|0|0|0|
0|0|0|1|
-----------------
0|0|0|0|
0|1|1|0|
-----------------
Non capisco però come mai non funziona, lo schermo si comporta in modo random, eppure mi sembra di aver seguito quello che il datasheet dice.
Le funzioni che uso per mandare i comandi o dati all'lcd sono corrette, perché se uso l'inizializzazione della libreria LiquidCrystal, poi posso scrivere quello che voglio sull'lcd con i miei metodi.
Guardando la libreria LiquidCrystal, vedo che l'inizializzazione è simile alla mia, per i 4bit:
// this is according to the hitachi HD44780 datasheet
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
write4bits(0x03);
delayMicroseconds(4500); // wait min 4.1ms
// second try
write4bits(0x03);
delayMicroseconds(4500); // wait min 4.1ms
// third go!
write4bits(0x03);
delayMicroseconds(150);
// finally, set to 4-bit interface
write4bits(0x02);
anche qui non capisco alcune scelte fatte:
- Come mai aspetta per ben due volte 4500us quando invece il datasheet dice di attendere prima almeno 4100us e poi solo 100us?
- Coma mai dopo il terzo comando 0x3 aspetta nuovamente 150us quando il datasheet invece non fa riferimento a nessun tempo di attesa prima di mandare il comando 0x2?
Con questo post non voglio assolutamente dire che le scelte fatte qui sopra siano sbagliate, anzi, voglio proprio capire come mai siano state fatte, da dove posso capire leggendo solamente la documentazione dell'HD44780 come poter prendere certe decisioni invece che altre.
Probabilmente mi sta sfuggendo qualcosa...