Peripheral Mode (UART)
Was dieses Beispiel zeigt
Verwenden Sie Inkplate als Display für ein anderes Gerät. Mit diesem Sketch schreiben Sie keinen Zeichencode: Sie senden kurze Textbefehle über die serielle Schnittstelle, und Inkplate zeichnet Formen und Text, zeigt Bilder von der microSD-Karte an und meldet die Batteriespannung. Da die Befehle als reiner Text über UART übertragen werden, kann jede Plattform, die auf eine serielle Schnittstelle schreiben kann, den Bildschirm steuern.
Die Kommentare im Sketch nennen die Einstellungen: 115200 Baud, Standardparität, jeder Befehl endet sowohl mit \n als auch mit \r. Sie können die Befehle über den USB-Anschluss senden oder direkt an die TX- und RX-Pins des ESP32 anschließen. Der Sketch weist außerdem darauf hin, dass es wegen der geringen Geschwindigkeit von UART nicht empfohlen wird, viele einzelne Pixel zu zeichnen; laden Sie stattdessen Bitmaps und Bilder auf die microSD-Karte und zeichnen Sie sie von dort. Jedes Inkplate wird werkseitig mit diesem Modus ausgeliefert.
Befehlsformat
Jeder Befehl besteht aus #, einem Befehlszeichen, den Argumenten in runden Klammern und * am Ende, zum Beispiel #8(10,10,100,50,0)*. Zahlen werden dezimal geschrieben und durch Kommas getrennt. Auf dem Bildschirm wird nichts angezeigt, bis Sie nach den Zeichenbefehlen #L(1)* senden, was dem Aufruf von display() entspricht.
| Befehl | Argumente | Aufgerufene Funktion |
|---|---|---|
#?(…)* | keine | Antwortet mit OK |
#0(x,y,c)* | Position, Farbe | drawPixel |
#1(x1,y1,x2,y2,c)* | zwei Endpunkte, Farbe | drawLine |
#2(x,y,l,c)* | Start, Länge, Farbe | drawFastVLine |
#3(x,y,l,c)* | Start, Länge, Farbe | drawFastHLine |
#4(x,y,w,h,c)* | obere linke Ecke, Größe, Farbe | drawRect |
#5(x,y,r,c)* | Mittelpunkt, Radius, Farbe | drawCircle |
#6(x1,y1,x2,y2,x3,y3,c)* | drei Eckpunkte, Farbe | drawTriangle |
#7(x,y,w,h,r,c)* | obere linke Ecke, Größe, Eckenradius, Farbe | drawRoundRect |
#8(x,y,w,h,c)* | obere linke Ecke, Größe, Farbe | fillRect |
#9(x,y,r,c)* | Mittelpunkt, Radius, Farbe | fillCircle |
#A(x1,y1,x2,y2,x3,y3,c)* | drei Eckpunkte, Farbe | fillTriangle |
#B(x,y,w,h,r,c)* | obere linke Ecke, Größe, Eckenradius, Farbe | fillRoundRect |
#C("hex")* | Text als hexadezimale Bytepaare in Anführungszeichen | print |
#D(s)* | Textgröße | setTextSize |
#E(x,y)* | Cursorposition | setCursor |
#F(T)* or #F(F)* | T für Zeilenumbruch ein, F für aus | setTextWrap |
#G(r)* | Rotation, nur die niedrigsten zwei Bits werden verwendet | setRotation |
#H(x,y,"hex")* | Position, Dateiname als hexadezimale Bytepaare in Anführungszeichen | image.drawBitmapFromSd |
#K(1)* | 1 | clearDisplay |
#L(1)* | 1 | display |
#M(a,b,c)* | drei Zahlen, die gelesen und nicht verwendet werden | display |
#P(?)* | ? | Antwortet mit #P( Batteriespannung )* von readBattery |
#S(x,y,"hex")* | Position, Dateiname als hexadezimale Bytepaare in Anführungszeichen | image.draw |
#T(x1,y1,x2,y2,c,t)* | zwei Endpunkte, Farbe, Dicke | drawThickLine |
#U(rx,ry,xc,yc,c)* | Radien, Mittelpunkt, Farbe | drawElipse |
#V(rx,ry,xc,yc,c)* | Radien, Mittelpunkt, Farbe | fillElipse |
Text und Dateinamen werden als hexadezimale Paare gesendet: Jedes Ziffernpaar wird zu einem Zeichen, also ist Hi gleich 4869. Bei #H und #S initialisiert der Sketch die microSD-Karte, zeichnet die Datei und antwortet mit #H(, gefolgt vom Ergebnis und )*; wenn die Karte nicht initialisiert werden kann, antwortet er mit #H(-1)*. Auch der Befehl #S antwortet mit #H(, so wie es der Code schreibt.
Beispielcode
#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;
}
Verwendete Funktionen
Inkplate()returns NoneErstellt das Inkplate-Objekt. Inkplate 7SPECTRA hat einen einzigen Sechs-Farben-Modus, daher benötigt der Konstruktor kein Modus-Argument.
ReturnsKonstruktor; kein Rückgabewert.
inkplate.begin()returns voidInitialisiert die Bibliothek, die Peripherie und den Framebuffer. Rufen Sie sie einmal in setup() auf.
ReturnsNichts.
inkplate.drawPixel(int16_t x, int16_t y, uint16_t color)returns voidSetzt ein Pixel im Framebuffer. Befehl 0.
ReturnsNichts.
inkplate.drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)returns voidZeichnet eine Linie zwischen zwei Punkten. Befehl 1. Aus der Klasse Adafruit GFX, auf der die Bibliothek aufbaut.
ReturnsNichts.
inkplate.drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)returns voidZeichnet eine vertikale Linie der angegebenen Länge. Befehl 2.
ReturnsNichts.
inkplate.drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)returns voidZeichnet eine horizontale Linie der angegebenen Länge. Befehl 3.
ReturnsNichts.
inkplate.drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)returns voidZeichnet den Umriss eines Rechtecks. Befehl 4.
ReturnsNichts.
inkplate.drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)returns voidZeichnet den Umriss eines Kreises. Befehl 5.
ReturnsNichts.
inkplate.drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)returns voidZeichnet den Umriss eines Dreiecks. Befehl 6.
ReturnsNichts.
inkplate.drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)returns voidZeichnet den Umriss eines Rechtecks mit abgerundeten Ecken. Befehl 7.
ReturnsNichts.
inkplate.fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)returns voidZeichnet ein gefülltes Rechteck mit der oberen linken Ecke bei (x, y). Befehl 8.
ReturnsNichts.
inkplate.fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)returns voidZeichnet einen gefüllten Kreis. Befehl 9.
ReturnsNichts.
inkplate.fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)returns voidZeichnet ein gefülltes Dreieck. Befehl A.
ReturnsNichts.
inkplate.fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)returns voidZeichnet ein gefülltes Rechteck mit abgerundeten Ecken. Befehl B.
ReturnsNichts.
inkplate.print(text)returns size_tGibt den dekodierten Text an der Cursorposition in den Framebuffer aus, wie Serial.print(). Befehl C.
ReturnsAnzahl der ausgegebenen Bytes.
inkplate.setTextSize(uint8_t s)returns voidLegt die Textvergrößerung fest. Befehl D.
ReturnsNichts.
inkplate.setCursor(int16_t x, int16_t y)returns voidLegt fest, wo der nächste ausgegebene Text beginnt. Befehl E.
ReturnsNichts.
inkplate.setTextWrap(bool w)returns voidLegt fest, ob Text, der nicht in eine Zeile passt, in der nächsten Zeile fortgesetzt wird. Befehl F.
ReturnsNichts.
inkplate.setRotation(uint8_t r)returns voidLegt die Bildschirmrotation fest. Der Sketch übergibt nur die niedrigsten zwei Bits der empfangenen Zahl. Befehl G.
ReturnsNichts.
inkplate.sdCardInit()returns int16_tSchaltet die Versorgung der microSD-Karte ein, startet ihren SPI-Bus und bindet die Karte ein. Die Befehle H und S rufen sie auf, bevor sie eine Datei lesen.
Returns1, wenn die Karte eingebunden wurde, 0, wenn nicht.
inkplate.image.drawBitmapFromSd(const char *fileName, int x, int y, bool dither = 0, bool invert = 0)returns boolÖffnet eine Bitmap-Datei auf der microSD-Karte anhand des Namens und zeichnet sie mit der oberen linken Ecke bei (x, y) in den Framebuffer. Befehl H. Der Sketch sendet das Ergebnis zurück, 1 bei Erfolg.
Returnstrue, wenn die Bitmap gezeichnet wurde.
inkplate.image.draw(const char *path, int x, int y, bool dither = 1, bool invert = 0)returns boolZeichnet eine Bilddatei von der microSD-Karte bei x, y; die Bibliothek wählt den Decoder anhand der Dateiendung (bmp, dib, jpg, jpeg oder png). Befehl S.
Returnstrue, wenn das Bild gezeichnet wurde.
inkplate.clearDisplay()returns voidFüllt den Framebuffer mit Weiß. Das Panel wird dabei nicht verändert. Befehl K.
ReturnsNichts.
inkplate.display(bool _leaveOn = 0)returns voidSendet den gesamten Framebuffer an das Panel und aktualisiert es. Befehle L und M.
ReturnsNichts.
inkplate.readBattery()returns doubleMisst die Batteriespannung. Der Sketch sendet sie mit zwei Nachkommastellen zurück. Befehl P.
ReturnsDie Batteriespannung in Volt.
inkplate.drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness)returns voidZeichnet eine Linie der angegebenen Dicke zwischen zwei Punkten. Befehl T.
ReturnsNichts.
inkplate.drawElipse(int rx, int ry, int xc, int yc, int c)returns voidZeichnet den Umriss einer Ellipse mit den Radien rx und ry um den Mittelpunkt (xc, yc). Der Name wird in der Bibliothek so geschrieben. Befehl U.
ReturnsNichts.
inkplate.fillElipse(int rx, int ry, int xc, int yc, int c)returns voidZeichnet eine gefüllte Ellipse mit den Radien rx und ry um den Mittelpunkt (xc, yc). Befehl V.
ReturnsNichts.
Serial.available()returns intArduino-Core: die Anzahl der Bytes, die im seriellen Empfangspuffer warten. Der Sketch liest sie alle in seinen Befehlspuffer.
ReturnsAnzahl der Bytes.
Serial.read()returns intArduino-Core: liest ein Byte von der seriellen Schnittstelle.
ReturnsDas Byte oder -1, wenn keines verfügbar ist.
Serial.print(value, format)returns size_tArduino-Core: schreibt einen Wert auf die serielle Schnittstelle. Der Sketch verwendet es für die Antworten. DEC gibt eine Zahl dezimal aus.
ReturnsAnzahl der geschriebenen Bytes.
Serial.println(value)returns size_tArduino-Core: wie Serial.print(), gefolgt von einem Zeilenumbruch.
ReturnsAnzahl der geschriebenen Bytes.
Serial.flush()returns voidArduino-Core: wartet, bis alles Geschriebene gesendet wurde. Der Sketch ruft es nach jeder Antwort auf.
ReturnsNichts.
Was Sie erwarten können
Nach dem Hochladen bleibt der Bildschirm unverändert, bis Sie Befehle senden. Senden Sie #?(…)*, und Inkplate antwortet mit OK. Senden Sie Zeichenbefehle und danach #L(1)*, dann wird der Bildschirm mit dem Ergebnis aktualisiert. Senden Sie #P(?)*, und er antwortet mit #P( und der Batteriespannung mit zwei Nachkommastellen, dann )*.
🔗Vollständiges Beispiel öffnen
examples/Inkplate7SPECTRA/Diagnostics/Inkplate7SPECTRA_Peripheral_Mode