| Exemples | Referència | Plaques | Recursos CITCEA | |
| Projectes | Programació | Perifèrics | Inici | |
| Enrere | ||||
Fins ara hem mostrat a la pantalla imatges fixes, predefinides, però tambés hi ha la possibilitat de dibuixar a la pantalla des del programa. Per poder dibuixar cal definir un espai de dibuix, conegut com a canvas, i reservar-li memòria.
Un cop tenim definit el canvas, hi podem representar el que vulguem (que quedarà guardat a la memòria) i després mostrar el canvas en la zona de la pantalla que desitgem.
Cal tenir en compte que els dibuixos que fem es basen en les coordenades del canvas, no en les de la pantalla.
Veiem un exemple que intenta mostrar com funciona el canvas. Recordem que la pantalla té 128 ⨯ 64 píxels i que la part blava mesura 128 ⨯ 48 píxels. Creem un canvas de 64 ⨯ 48, o sigui de la meitat de l'amplada de la part blava. El primer que fem és dibuixar un rectangle de tota la mida del canvas (així el veurem) però no el pintem de blau sinó que l'omplim amb un patró que ompli només el primer i el darrer píxel de cada grup vertical de 8, així veurem tot el canvas ple de ratlles horitzontals (a les posicions 0, 7, 8, 15, 16, etc.; fins a la 47). Aquest canvas el situem (funció blt) a la posició [0,16] (hem posat [0, 2] perquè el posicionament vertical del canvas és en paquets de vuit bits verticals (com ja hem vist en altres casos).
En una segona fase dibuixem quatre rectangles de 8 ⨯ 8, un a cada cantonada del canvas i tornem a mostrar el canvas a la mateixa posició; si no ho féssim, no veuríem el que hem dibuixat després de mostrar el canvas.
En una tercera fase esborrem la pantalla. Aquesta acció deixa la pantalla negra però no afecta al que tenim dibuixat a la memòria del canvas. Tot seguit escrivim dos textos en el canvas, però ara el mostrem a la meitat dreta de la part blava. Si no haguéssim esborrat la pantalla, ara veuríem l'aspecte anterior del canvas al costat esquerre i el nou al costat dret.
#include "ssd1306.h" #include "nano_gfx.h" #define cw 64 // Amplada del canvas #define ch 48 // Alçada del canvas
uint8_t memoCnv[cw*ch/8]; // Memòria per al canvas NanoCanvas canvas(cw, ch, memoCnv);
void setup(){
ssd1306_128x64_i2c_init();
ssd1306_clearScreen();
ssd1306_setFixedFont(ssd1306xled_font6x8);
}
void loop(){
ssd1306_clearScreen(); // Esborra la pantalla, no el canvas
canvas.clear(); // Esborra el canvas
canvas.fillRect(0, 0, 63, 47, 129); // Rectangle de tot el canvas
canvas.blt(0, 2); // DIbuixa el canvas ocupant la meitat esquerra de la part blava
delay(1000);
canvas.fillRect(0, 0, 7, 7, 255); // Rectangle 8x8 a la cantonada SE
canvas.fillRect(0, 40, 7, 47, 255); // Rectangle 8x8 a la cantonada IE
canvas.fillRect(56, 0, 63, 7, 255); // Rectangle 8x8 a la cantonada SD
canvas.fillRect(56, 40, 63, 47, 255); // Rectangle 8x8 a la cantonada ID
canvas.blt(0, 2);
delay(2000);
ssd1306_clearScreen(); // Esborra la pantalla, no el canvas
canvas.printFixed(16, 16, "Prova", STYLE_NORMAL);
canvas.printFixed2x(8, 24, "Test", STYLE_NORMAL);
canvas.blt(64, 2); // DIbuixa el canvas ocupant la meitat dreta de la part blava
ssd1306_printFixed(0, 0, "Rectangles", STYLE_NORMAL);
delay(3000);
}
Si en lloc de la funció fillRect emprem la funció drawRect (sense el patró, cinquè paràmetre) obtindrem només els contorns dels cinc rectangles.
Ara que ja hem vist com es comporta el canvas, anem a veure altres possibilitats de dibuix.
El programa següent dibuixa la paràbola y = 0,012 x2 - 10 amb uns eixos, posant el canvas de forma que ocupi tota la part blava.
#include "ssd1306.h" #include "nano_gfx.h" #define cw 128 // Amplada del canvas #define ch 48 // Alçada del canvas
uint8_t memoCnv[cw*ch/8]; // Memòria per al canvas NanoCanvas canvas(cw, ch, memoCnv);
void setup(){
ssd1306_128x64_i2c_init();
ssd1306_clearScreen();
ssd1306_setFixedFont(ssd1306xled_font6x8);
}
void loop(){
canvas.clear(); // Esborra el canvas
canvas.drawHLine(4, 24, 123);
canvas.drawVLine(64, 4, 43);
for(int x = -60; x < 60; x++){
int y = (int) (0.012 * x * x - 10);
canvas.putPixel(60 + x, 24 - y);
}
canvas.blt(0, 2);
ssd1306_printFixed(0, 0, "Dibuix de funcions", STYLE_NORMAL);
delay(3000);
}
En el canvas també hi podem incloure imatges i sprites, però en un lloc fix. En el següent programa posem dos sprites i una imatge, després invertim la visualització (canviar negre per blau).

En el programa següent hem representat els sprites del pop i el peix i també la imatge del got. En el cas de la imatge, que és la mateixa que hem fet servir abans, la codificació és diferent; ja que cada byte codifica vuit bits verticals. Per tant, l'hem de codificar de nou. A cada element tindrem un nombre binari en el qual el bit de menys pes representa la part superior i el de més pes la part inferior. Primer hi ha els vuit bytes que codifiquen la meitat superior del dibuix i després els que codifiquen l'altra meitat.
#include "ssd1306.h" #include "nano_gfx.h" #define cw 128 // Amplada del canvas #define ch 48 // Alçada del canvas
const uint8_t pop[8] PROGMEM = {
0b11000000,
0b00100000,
0b11010110,
0b00111101,
0b00111111,
0b11010110,
0b00100000,
0b11000000
};
const uint8_t peix[8] PROGMEM = {
0b00101000,
0b00010000,
0b00101000,
0b01000100,
0b01000100,
0b01001100,
0b00101000,
0b00010000
};
const uint8_t got[] PROGMEM = {
0b00000000, 0b00000000, 0b11110000, 0b00010000, // Part superior cols. 1 a 4
0b00010000, 0b10010000, 0b11010000, 0b01110000,
0b00110000, 0b00011000, 0b00011100, 0b11110110,
0b00000011, 0b00000001, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00011111, 0b11111110, // Part inferior cols. 1 a 4
0b11111111, 0b11111111, 0b11111110, 0b11111110,
0b11111110, 0b11111110, 0b11111110, 0b00011111,
0b00000000, 0b00000000, 0b00000000, 0b00000000
};
uint8_t memoCnv[cw*ch/8]; // Memòria per al canvas
NanoCanvas canvas(cw, ch, memoCnv);
void setup(){
ssd1306_128x64_i2c_init();
ssd1306_clearScreen();
ssd1306_setFixedFont(ssd1306xled_font6x8);
}
void loop(){
canvas.clear(); // Esborra el canvas
canvas.drawHLine(4, 24, 123);
canvas.drawVLine(64, 4, 43);
canvas.drawSpritePgm(20, 10, pop);
canvas.drawSprite(20, 30, peix);
canvas.drawBitmap(75, 6, 16, 16, got);
canvas.blt(0, 2);
ssd1306_printFixed(0, 0, "Sprites", STYLE_NORMAL);
delay(2000);
canvas.invert();
canvas.blt(0, 2);
delay(2000);
}
| Funció | Ús | Paràmetres | Comentaris |
| NanoCanvas nomCanvas | Crea un objecte canvas | Amplada del canvas (píxels) Alçada del canvas (píxels) Vector on guardarem el canvas |
Vector del tipus uint8_t Mida: amplada ⨯ alçada / 8 Cal la biblioteca nano_gfx |
| nomCanvas.width | Retorna l'amplada del canvas en píxels | ||
| nomCanvas.height | Retorna l'alçada del canvas en píxels | ||
| nomCanvas.buffer | Retorna el vector que conté el canvas | nomCanvas.buffer()[i] retorna la component i del vector |
|
| nomCanvas.clear | Esborra el contingut del canvas | No afecta al que es veu a la pantalla, fins que es torna a mostrar el canvas |
|
| nomCanvas.blt | Mostra el canvas a la pantalla | Posició x a la pantalla Posició y en múltiples de 8 |
|
| nomCanvas.printFixed | Escriu un text fix al canvas | Posició x Posició y Text (entre cometes) Estil |
Opcions d'estil: STYLE_NORMAL STYLE_BOLD STYLE_ITALIC |
| nomCanvas.printFixed2x | Escriu un text fix al canvas a mida doble | Posició x Posició y Text (entre cometes) Estil |
Opcions d'estil: STYLE_NORMAL STYLE_BOLD STYLE_ITALIC |
| nomCanvas.drawRect | Crea un rectangle buit | Posició x inicial Posició y inicial Posició x final Posició y final |
|
| nomCanvas.fillRect | Crea un rectangle farcit amb un patró | Posició x inicial Posició y inicial Posició x final Posició y final Patró (8 bits) [0 a 255] |
El patró correspon a 8 píxels verticals, on el bit menys significatiu és el píxel superior. Posant 0 no mostra el rectangle (ni les vores). Posant 255 pinta completament el rectangle. Un patró entre 0 i 255 donarà franges horitzontals |
| nomCanvas.drawHLine | Dibuixa una línia horitzontal | Posició x inicial Posició y Posició x final |
|
| nomCanvas.drawVLine | Dibuixa una línia vertical | Posició x Posició y inicial Posició y final |
|
| nomCanvas.putPixel | Pinta un píxel | Posició x Posició y |
|
| nomCanvas.drawSprite | Mostra l'sprite en el canvas | Posició x Posició y Vector de la imatge |
|
| nomCanvas.drawSpritePgm | Mostra l'sprite en el canvas | Posició x Posició y Vector de la imatge |
|
| nomCanvas.drawBitmap | Mostra una imatge fixa en el canvas | Posició x Posició y Amplada Alçada Vector de la imatge |
|
| nomCanvas.invert | Inverteix tots els píxels del canvas | Apaga els encesos i encén els apagats |

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.