Periferni način rada (UART)
Što ovaj primjer prikazuje
Koristite Inkplate kao zaslon za drugi uređaj. S ovom skicom ne pišete nikakav kôd za crtanje: preko serijskog porta šaljete kratke tekstualne naredbe, a Inkplate crta oblike i tekst, prikazuje slike s microSD kartice i javlja napon baterije. Budući da su naredbe običan tekst preko UART-a, njima može upravljati svaka platforma koja može pisati na serijski port.
Komentari u skici navode postavke: 115200 baud, standardni paritet, a svaka naredba završava znakovima \n i \r. Naredbe možete slati preko USB porta ili izravnim spajanjem na pinove TX i RX ESP32 čipa. Skica također navodi da se zbog sporosti UART-a ne preporučuje crtanje velikog broja pojedinačnih piksela; bitmape i slike učitajte na microSD karticu i crtajte ih s nje. Svaki Inkplate ima ovaj način rada od tvornice.
Format naredbi
Svaka naredba sastoji se od znaka #, znaka naredbe, argumenata u okruglim zagradama i znaka * na kraju, na primjer #8(10,10,100,50,0)*. Brojevi se pišu u decimalnom zapisu i odvajaju zarezima. Na zaslonu se ništa ne prikazuje dok nakon naredbi za crtanje ne pošaljete #L(1)*, što je isto kao poziv funkcije display().
| Naredba | Argumenti | Funkcija koju poziva |
|---|---|---|
#?(…)* | nema | Odgovara OK |
#0(x,y,c)* | položaj, boja | drawPixel |
#1(x1,y1,x2,y2,c)* | dvije krajnje točke, boja | drawLine |
#2(x,y,l,c)* | početak, duljina, boja | drawFastVLine |
#3(x,y,l,c)* | početak, duljina, boja | drawFastHLine |
#4(x,y,w,h,c)* | gornji lijevi kut, veličina, boja | drawRect |
#5(x,y,r,c)* | središte, polumjer, boja | drawCircle |
#6(x1,y1,x2,y2,x3,y3,c)* | tri vrha, boja | drawTriangle |
#7(x,y,w,h,r,c)* | gornji lijevi kut, veličina, polumjer kuta, boja | drawRoundRect |
#8(x,y,w,h,c)* | gornji lijevi kut, veličina, boja | fillRect |
#9(x,y,r,c)* | središte, polumjer, boja | fillCircle |
#A(x1,y1,x2,y2,x3,y3,c)* | tri vrha, boja | fillTriangle |
#B(x,y,w,h,r,c)* | gornji lijevi kut, veličina, polumjer kuta, boja | fillRoundRect |
#C("hex")* | tekst kao heksadecimalni parovi bajtova u navodnicima | print |
#D(s)* | veličina teksta | setTextSize |
#E(x,y)* | položaj kursora | setCursor |
#F(T)* ili #F(F)* | T za uključeno prelamanje, F za isključeno | setTextWrap |
#G(r)* | rotacija, koriste se samo najniža dva bita | setRotation |
#H(x,y,"hex")* | položaj, naziv datoteke kao heksadecimalni parovi bajtova u navodnicima | image.drawBitmapFromSd |
#K(1)* | 1 | clearDisplay |
#L(1)* | 1 | display |
#M(a,b,c)* | tri broja koja se čitaju, a ne koriste | display |
#P(?)* | ? | Odgovara #P( napon baterije )* iz funkcije readBattery |
#S(x,y,"hex")* | položaj, naziv datoteke kao heksadecimalni parovi bajtova u navodnicima | image.draw |
#T(x1,y1,x2,y2,c,t)* | dvije krajnje točke, boja, debljina | drawThickLine |
#U(rx,ry,xc,yc,c)* | polumjeri, središte, boja | drawElipse |
#V(rx,ry,xc,yc,c)* | polumjeri, središte, boja | fillElipse |
Tekst i nazivi datoteka šalju se kao heksadecimalni parovi: svaki par znamenki postaje jedan znak, pa je Hi zapisano kao 4869. Za #H i #S skica inicijalizira microSD karticu, crta datoteku i odgovara s #H(, nakon čega slijedi rezultat i )*; kada se kartica ne može inicijalizirati, odgovara #H(-1)*. Naredba #S također odgovara s #H(, kako je zapisano u kôdu.
Primjer koda
#include <Inkplate.h>
Inkplate inkplate;
#define BUFFER_SIZE 1000
char commandBuffer[BUFFER_SIZE + 1];
char strTemp[2001];
void setup()
{
inkplate.begin();
Serial.begin(115200);
memset(commandBuffer, 0, BUFFER_SIZE);
}
void loop()
{
// put your main code here, to run repeatedly:
if (Serial.available())
{
while (Serial.available())
{
for (int i = 0; i < (BUFFER_SIZE - 1); i++)
{
commandBuffer[i] = commandBuffer[i + 1];
}
commandBuffer[BUFFER_SIZE - 1] = Serial.read();
}
}
char *s = NULL;
char *e = NULL;
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (commandBuffer[i] == '#' && s == NULL)
s = &commandBuffer[i];
if (commandBuffer[i] == '*' && e == NULL)
e = &commandBuffer[i];
}
if (s != NULL && e != NULL)
{
if ((e - s) > 0)
{
int x, x1, x2, y, y1, y2, x3, y3, l, c, w, h, r, n, rx, ry, xc, yc;
char b;
char temp[150];
switch (*(s + 1))
{
case '?':
Serial.print("OK");
break;
case '0':
sscanf(s + 3, "%d,%d,%d", &x, &y, &c);
inkplate.drawPixel(x, y, c);
break;
case '1':
sscanf(s + 3, "%d,%d,%d,%d,%d", &x1, &y1, &x2, &y2, &c);
inkplate.drawLine(x1, y1, x2, y2, c);
break;
case '2':
sscanf(s + 3, "%d,%d,%d,%d", &x, &y, &l, &c);
inkplate.drawFastVLine(x, y, l, c);
break;
case '3':
sscanf(s + 3, "%d,%d,%d,%d", &x, &y, &l, &c);
inkplate.drawFastHLine(x, y, l, c);
break;
case '4':
sscanf(s + 3, "%d,%d,%d,%d,%d", &x, &y, &w, &h, &c);
inkplate.drawRect(x, y, w, h, c);
break;
case '5':
sscanf(s + 3, "%d,%d,%d,%d", &x, &y, &r, &c);
inkplate.drawCircle(x, y, r, c);
break;
case '6':
sscanf(s + 3, "%d,%d,%d,%d,%d,%d,%d", &x1, &y1, &x2, &y2, &x3, &y3, &c);
inkplate.drawTriangle(x1, y1, x2, y2, x3, y3, c);
break;
case '7':
sscanf(s + 3, "%d,%d,%d,%d,%d,%d", &x, &y, &w, &h, &r, &c);
inkplate.drawRoundRect(x, y, w, h, r, c);
break;
case '8':
sscanf(s + 3, "%d,%d,%d,%d,%d", &x, &y, &w, &h, &c);
inkplate.fillRect(x, y, w, h, c);
break;
case '9':
sscanf(s + 3, "%d,%d,%d,%d", &x, &y, &r, &c);
inkplate.fillCircle(x, y, r, c);
break;
case 'A':
sscanf(s + 3, "%d,%d,%d,%d,%d,%d,%d", &x1, &y1, &x2, &y2, &x3, &y3, &c);
inkplate.fillTriangle(x1, y1, x2, y2, x3, y3, c);
break;
case 'B':
sscanf(s + 3, "%d,%d,%d,%d,%d,%d", &x, &y, &w, &h, &r, &c);
inkplate.fillRoundRect(x, y, w, h, r, c);
break;
case 'C':
sscanf(s + 3, "\"%2000[^\"]\"", strTemp);
n = strlen(strTemp);
for (int i = 0; i < n; i++)
{
strTemp[i] = toupper(strTemp[i]);
}
for (int i = 0; i < n; i += 2)
{
strTemp[i / 2] = (hexToChar(strTemp[i]) << 4) | (hexToChar(strTemp[i + 1]) & 0x0F);
}
strTemp[n / 2] = 0;
inkplate.print(strTemp);
break;
case 'D':
sscanf(s + 3, "%d", &c);
inkplate.setTextSize(c);
break;
case 'E':
sscanf(s + 3, "%d,%d", &x, &y);
inkplate.setCursor(x, y);
break;
case 'F':
sscanf(s + 3, "%c", &b);
if (b == 'T')
inkplate.setTextWrap(true);
if (b == 'F')
inkplate.setTextWrap(false);
break;
case 'G':
sscanf(s + 3, "%d", &c);
c &= 3;
inkplate.setRotation(c);
break;
case 'H':
sscanf(s + 3, "%d,%d,\"%149[^\"]\"", &x, &y, strTemp);
n = strlen(strTemp);
for (int i = 0; i < n; i++)
{
strTemp[i] = toupper(strTemp[i]);
}
for (int i = 0; i < n; i += 2)
{
strTemp[i / 2] = (hexToChar(strTemp[i]) << 4) | (hexToChar(strTemp[i + 1]) & 0x0F);
}
strTemp[n / 2] = 0;
r = inkplate.sdCardInit();
if (r)
{
r = inkplate.image.drawBitmapFromSd(strTemp, x, y);
Serial.print("#H(");
Serial.print(r, DEC);
Serial.println(")*");
Serial.flush();
}
else
{
Serial.println("#H(-1)*");
Serial.flush();
}
break;
case 'K':
sscanf(s + 3, "%c", &b);
if (b == '1')
{
inkplate.clearDisplay();
}
break;
case 'L':
sscanf(s + 3, "%c", &b);
if (b == '1')
{
inkplate.display();
}
break;
case 'M':
sscanf(s + 3, "%d,%d,%d", &y1, &x2, &y2);
inkplate.display();
break;
case 'P':
sscanf(s + 3, "%c", &b);
if (b == '?')
{
Serial.print("#P(");
Serial.print(inkplate.readBattery(), 2);
Serial.println(")*");
Serial.flush();
}
break;
case 'S':
sscanf(s + 3, "%d,%d,\"%149[^\"]\"", &x, &y, strTemp);
n = strlen(strTemp);
for (int i = 0; i < n; i++)
{
strTemp[i] = toupper(strTemp[i]);
}
for (int i = 0; i < n; i += 2)
{
strTemp[i / 2] = (hexToChar(strTemp[i]) << 4) | (hexToChar(strTemp[i + 1]) & 0x0F);
}
strTemp[n / 2] = 0;
r = inkplate.sdCardInit();
if (r)
{
r = inkplate.image.draw(strTemp, x, y);
Serial.print("#H(");
Serial.print(r, DEC);
Serial.println(")*");
Serial.flush();
}
else
{
Serial.println("#H(-1)*");
Serial.flush();
}
break;
case 'T':
int t;
sscanf(s + 3, "%d,%d,%d,%d,%d,%d", &x1, &y1, &x2, &y2, &c, &t);
inkplate.drawThickLine(x1, y1, x2, y2, c, t);
break;
case 'U':
sscanf(s + 3, "%d,%d,%d,%d,%d", &rx, &ry, &xc, &yc, &c);
inkplate.drawElipse(rx, ry, xc, yc, c);
break;
case 'V':
sscanf(s + 3, "%d,%d,%d,%d,%d", &rx, &ry, &xc, &yc, &c);
inkplate.fillElipse(rx, ry, xc, yc, c);
break;
}
*s = 0;
*e = 0;
}
}
}
int hexToChar(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return -1;
}
Korištene funkcije
Inkplate()returns NoneStvara objekt Inkplate. Inkplate 7SPECTRA ima samo jedan način rada sa šest boja, pa konstruktor ne prima argument načina rada.
ReturnsKonstruktor; nema povratne vrijednosti.
inkplate.begin()returns voidInicijalizira biblioteku, periferiju i međuspremnik slike. Pozovite je jednom u setup().
ReturnsNišta.
inkplate.drawPixel(int16_t x, int16_t y, uint16_t color)returns voidPostavlja jedan piksel u međuspremniku slike. Naredba 0.
ReturnsNišta.
inkplate.drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)returns voidCrta liniju između dvije točke. Naredba 1. Iz klase Adafruit GFX na kojoj se biblioteka temelji.
ReturnsNišta.
inkplate.drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)returns voidCrta okomitu liniju zadane duljine. Naredba 2.
ReturnsNišta.
inkplate.drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)returns voidCrta vodoravnu liniju zadane duljine. Naredba 3.
ReturnsNišta.
inkplate.drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)returns voidCrta obrub pravokutnika. Naredba 4.
ReturnsNišta.
inkplate.drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)returns voidCrta obrub kruga. Naredba 5.
ReturnsNišta.
inkplate.drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)returns voidCrta obrub trokuta. Naredba 6.
ReturnsNišta.
inkplate.drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)returns voidCrta obrub pravokutnika sa zaobljenim kutovima. Naredba 7.
ReturnsNišta.
inkplate.fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)returns voidCrta ispunjeni pravokutnik s gornjim lijevim kutom u točki (x, y). Naredba 8.
ReturnsNišta.
inkplate.fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)returns voidCrta ispunjeni krug. Naredba 9.
ReturnsNišta.
inkplate.fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)returns voidCrta ispunjeni trokut. Naredba A.
ReturnsNišta.
inkplate.fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)returns voidCrta ispunjeni pravokutnik sa zaobljenim kutovima. Naredba B.
ReturnsNišta.
inkplate.print(text)returns size_tIspisuje dekodirani tekst u međuspremnik slike na položaju kursora, kao Serial.print(). Naredba C.
ReturnsBroj ispisanih bajtova.
inkplate.setTextSize(uint8_t s)returns voidPostavlja povećanje teksta. Naredba D.
ReturnsNišta.
inkplate.setCursor(int16_t x, int16_t y)returns voidPostavlja mjesto na kojem počinje sljedeći ispisani tekst. Naredba E.
ReturnsNišta.
inkplate.setTextWrap(bool w)returns voidOdređuje hoće li se tekst koji ne stane u redak nastaviti u sljedećem retku. Naredba F.
ReturnsNišta.
inkplate.setRotation(uint8_t r)returns voidPostavlja rotaciju zaslona. Skica prosljeđuje samo najniža dva bita primljenog broja. Naredba G.
ReturnsNišta.
inkplate.sdCardInit()returns int16_tUključuje napajanje microSD kartice, pokreće njezinu SPI sabirnicu i montira karticu. Naredbe H i S pozivaju je prije čitanja datoteke.
Returns1 ako je kartica montirana, 0 ako nije.
inkplate.image.drawBitmapFromSd(const char *fileName, int x, int y, bool dither = 0, bool invert = 0)returns boolOtvara bitmapu na microSD kartici prema nazivu i crta je u međuspremnik slike s gornjim lijevim kutom u točki (x, y). Naredba H. Skica šalje rezultat natrag, 1 u slučaju uspjeha.
Returnstrue ako je bitmapa nacrtana.
inkplate.image.draw(const char *path, int x, int y, bool dither = 1, bool invert = 0)returns boolCrta slikovnu datoteku s microSD kartice na položaju x, y; biblioteka bira dekoder prema ekstenziji datoteke (bmp, dib, jpg, jpeg ili png). Naredba S.
Returnstrue ako je slika nacrtana.
inkplate.clearDisplay()returns voidIspunjava međuspremnik slike bijelom bojom. Ne mijenja zaslon. Naredba K.
ReturnsNišta.
inkplate.display(bool _leaveOn = 0)returns voidŠalje cijeli međuspremnik slike na zaslon i osvježava ga. Naredbe L i M.
ReturnsNišta.
inkplate.readBattery()returns doubleMjeri napon baterije. Skica ga šalje natrag s dvije decimale. Naredba P.
ReturnsNapon baterije u voltima.
inkplate.drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness)returns voidCrta liniju zadane debljine između dvije točke. Naredba T.
ReturnsNišta.
inkplate.drawElipse(int rx, int ry, int xc, int yc, int c)returns voidCrta obrub elipse s polumjerima rx i ry oko središta (xc, yc). Naziv je u biblioteci napisan upravo ovako. Naredba U.
ReturnsNišta.
inkplate.fillElipse(int rx, int ry, int xc, int yc, int c)returns voidCrta ispunjenu elipsu s polumjerima rx i ry oko središta (xc, yc). Naredba V.
ReturnsNišta.
Serial.available()returns intArduino core: broj bajtova koji čekaju u prijemnom međuspremniku serijskog porta. Skica ih sve čita u svoj međuspremnik naredbi.
ReturnsBroj bajtova.
Serial.read()returns intArduino core: čita jedan bajt sa serijskog porta.
ReturnsBajt ili -1 ako nijedan nije dostupan.
Serial.print(value, format)returns size_tArduino core: zapisuje vrijednost na serijski port. Skica ga koristi za odgovore. DEC ispisuje broj u decimalnom zapisu.
ReturnsBroj zapisanih bajtova.
Serial.println(value)returns size_tArduino core: kao Serial.print(), nakon čega slijedi prijelaz u novi redak.
ReturnsBroj zapisanih bajtova.
Serial.flush()returns voidArduino core: čeka dok se sve zapisano ne pošalje. Skica ga poziva nakon svakog odgovora.
ReturnsNišta.
Što očekivati
Nakon prijenosa zaslon ostaje nepromijenjen dok ne pošaljete naredbe. Pošaljite #?(…)* i Inkplate odgovara OK. Pošaljite naredbe za crtanje, a zatim #L(1)*, i zaslon se osvježava s rezultatom. Pošaljite #P(?)* i odgovorit će s #P(, naponom baterije s dvije decimale te )*.
🔗Otvorite cjeloviti primjer
examples/Inkplate7SPECTRA/Diagnostics/Inkplate7SPECTRA_Peripheral_Mode