Zum Hauptinhalt springen

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.

BefehlArgumenteAufgerufene Funktion
#?(…)*keineAntwortet mit OK
#0(x,y,c)*Position, FarbedrawPixel
#1(x1,y1,x2,y2,c)*zwei Endpunkte, FarbedrawLine
#2(x,y,l,c)*Start, Länge, FarbedrawFastVLine
#3(x,y,l,c)*Start, Länge, FarbedrawFastHLine
#4(x,y,w,h,c)*obere linke Ecke, Größe, FarbedrawRect
#5(x,y,r,c)*Mittelpunkt, Radius, FarbedrawCircle
#6(x1,y1,x2,y2,x3,y3,c)*drei Eckpunkte, FarbedrawTriangle
#7(x,y,w,h,r,c)*obere linke Ecke, Größe, Eckenradius, FarbedrawRoundRect
#8(x,y,w,h,c)*obere linke Ecke, Größe, FarbefillRect
#9(x,y,r,c)*Mittelpunkt, Radius, FarbefillCircle
#A(x1,y1,x2,y2,x3,y3,c)*drei Eckpunkte, FarbefillTriangle
#B(x,y,w,h,r,c)*obere linke Ecke, Größe, Eckenradius, FarbefillRoundRect
#C("hex")*Text als hexadezimale Bytepaare in Anführungszeichenprint
#D(s)*TextgrößesetTextSize
#E(x,y)*CursorpositionsetCursor
#F(T)* or #F(F)*T für Zeilenumbruch ein, F für aussetTextWrap
#G(r)*Rotation, nur die niedrigsten zwei Bits werden verwendetsetRotation
#H(x,y,"hex")*Position, Dateiname als hexadezimale Bytepaare in Anführungszeichenimage.drawBitmapFromSd
#K(1)*1clearDisplay
#L(1)*1display
#M(a,b,c)*drei Zahlen, die gelesen und nicht verwendet werdendisplay
#P(?)*?Antwortet mit #P( Batteriespannung )* von readBattery
#S(x,y,"hex")*Position, Dateiname als hexadezimale Bytepaare in Anführungszeichenimage.draw
#T(x1,y1,x2,y2,c,t)*zwei Endpunkte, Farbe, DickedrawThickLine
#U(rx,ry,xc,yc,c)*Radien, Mittelpunkt, FarbedrawElipse
#V(rx,ry,xc,yc,c)*Radien, Mittelpunkt, FarbefillElipse

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​

Select Board
Inkplate7SPECTRA_Peripheral_Mode.ino
#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 None

Erstellt 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 void

Initialisiert 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 void

Setzt 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet den Umriss eines Rechtecks. Befehl 4.

ReturnsNichts.

inkplate.drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)returns void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet 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 void

Zeichnet ein gefülltes Rechteck mit abgerundeten Ecken. Befehl B.

ReturnsNichts.

inkplate.print(text)returns size_t

Gibt 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 void

Legt die Textvergrößerung fest. Befehl D.

ReturnsNichts.

inkplate.setCursor(int16_t x, int16_t y)returns void

Legt fest, wo der nächste ausgegebene Text beginnt. Befehl E.

ReturnsNichts.

inkplate.setTextWrap(bool w)returns void

Legt 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 void

Legt die Bildschirmrotation fest. Der Sketch übergibt nur die niedrigsten zwei Bits der empfangenen Zahl. Befehl G.

ReturnsNichts.

inkplate.sdCardInit()returns int16_t

Schaltet 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 bool

Zeichnet 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 void

Füllt den Framebuffer mit Weiß. Das Panel wird dabei nicht verändert. Befehl K.

ReturnsNichts.

inkplate.display(bool _leaveOn = 0)returns void

Sendet den gesamten Framebuffer an das Panel und aktualisiert es. Befehle L und M.

ReturnsNichts.

inkplate.readBattery()returns double

Misst 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 void

Zeichnet eine Linie der angegebenen Dicke zwischen zwei Punkten. Befehl T.

ReturnsNichts.

inkplate.drawElipse(int rx, int ry, int xc, int yc, int c)returns void

Zeichnet 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 void

Zeichnet eine gefüllte Ellipse mit den Radien rx und ry um den Mittelpunkt (xc, yc). Befehl V.

ReturnsNichts.

Serial.available()returns int

Arduino-Core: die Anzahl der Bytes, die im seriellen Empfangspuffer warten. Der Sketch liest sie alle in seinen Befehlspuffer.

ReturnsAnzahl der Bytes.

Serial.read()returns int

Arduino-Core: liest ein Byte von der seriellen Schnittstelle.

ReturnsDas Byte oder -1, wenn keines verfügbar ist.

Serial.print(value, format)returns size_t

Arduino-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_t

Arduino-Core: wie Serial.print(), gefolgt von einem Zeilenumbruch.

ReturnsAnzahl der geschriebenen Bytes.

Serial.flush()returns void

Arduino-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

→