TFT_eSPI/examples/ILI9341/TFT_Screen_Capture/screenServer.ino

153 lines
4.9 KiB
C++

// TFT screenshot server
// This is a sketch support tab containing function calls to read a screen image
// off a TFT and send it to a processing client sketch over the serial port.
// See the processing_sketch tab, it contains a copy of the processing sketch.
// Use a high baud rate, for an ESP8266:
/*
Serial.begin(921600);
*/
// 240 x 320 images take about 3.5s to transfer at 921600 baud(minimum is ~2.5s)
// This sketch has been created to work with the TFT_eSPI library here:
// https://github.com/Bodmer/TFT_eSPI
// Created by: Bodmer 27/1/17
// The MIT permissive free software license applies, include all text above in
// derivatives.
#define BAUD_RATE 250000 // Maximum Arduino IDE Serial Monitor rate
#define DUMP_BAUD_RATE 921600 // Rate used for screen dumps by ESP8266
#define PIXEL_TIMEOUT 100 // 100ms Time-out between pixel requests
#define START_TIMEOUT 10000 // 10s Maximum time to wait at start transfer
// Start a screen dump server (serial or network)
boolean screenServer(void)
{
Serial.end(); // Stop the serial port (clears buffers too)
Serial.begin(DUMP_BAUD_RATE); // Force baud rate to be high
yield();
boolean result = serialScreenServer(); // Screenshot serial port server
//boolean result = wifiDump(); // Screenshot WiFi UDP port server (WIP)
Serial.end(); // Stop the serial port (clears buffers too)
Serial.begin(BAUD_RATE); // Return baud rate to normal
yield();
//Serial.println();
//if (result) Serial.println(F("Screen dump passed :-)"));
//else Serial.println(F("Screen dump failed :-("));
return result;
}
// Screenshot serial port server (Processing sketch acts as client)
boolean serialScreenServer(void)
{
// Serial commands from client:
// 'S' to start the transfer process (To do: reply with width + height)
// 'R' or any character except 'X' to request pixel
// 'X' to abort and return immediately to caller
// Returned boolean values:
// true = image despatched OK
// false = time-out or abort command received
// Precautionary receive buffer garbage flush for 50ms
uint32_t clearTime = millis() + 50;
while ( millis() < clearTime ) {
Serial.read();
yield();
}
boolean wait = true;
uint32_t lastCmdTime = millis(); // Initialise start of command time-out
// Wait for the starting flag with a start time-out
while (wait)
{
yield();
// Check serial buffer
if (Serial.available() > 0) {
// Read the command byte
uint8_t cmd = Serial.read();
// If it is 'S' (start command) then clear the serial buffer for 100ms and stop waiting
if ( cmd == 'S' ) {
// Precautionary receive buffer garbage flush for 50ms
clearTime = millis() + 50;
while ( millis() < clearTime ) {
Serial.read();
yield();
}
wait = false; // No need to wait anymore
lastCmdTime = millis(); // Set last received command time
// Send screen size, not supported by processing sketch yet
//Serial.write('W');
//Serial.write(tft.width() >> 8);
//Serial.write(tft.width() & 0xFF);
//Serial.write('H');
//Serial.write(tft.height() >> 8);
//Serial.write(tft.height() & 0xFF);
//Serial.write('Y');
}
}
else
{
// Check for time-out
if ( millis() > lastCmdTime + START_TIMEOUT) return false;
}
}
uint8_t color[3]; // RGB color buffer for 1 pixel
// Send all the pixels on the whole screen (typically 5 seconds at 921600 baud)
for ( uint32_t y = 0; y < tft.height(); y++)
{
// Increment x by 2 as we send 2 pixels for every byte received
for ( uint32_t x = 0; x < tft.width(); x += 1)
{
yield();
// Wait here for serial data to arrive or a time-out elapses
while ( Serial.available() == 0 )
{
yield;
if ( millis() > lastCmdTime + PIXEL_TIMEOUT) return false;
}
// Serial data must be available to get here, read 1 byte and
// respond with N pixels, i.e. N x 3 RGB bytes
if ( Serial.read() == 'X' ) {
// X command byte means abort, so clear the buffer and return
clearTime = millis() + 50;
while ( millis() < clearTime ) Serial.read();
return false;
}
// Save arrival time of the read command (for later time-out check)
lastCmdTime = millis();
// Fetch data for N pixels starting at x,y
tft.readRectRGB(x, y, 1, 1, color);
// Send values to client
Serial.write(color[0]); // Pixel 1 red
Serial.write(color[1]); // Pixel 1 green
Serial.write(color[2]); // Pixel 1 blue
//Serial.write(color[3]); // Pixel 2 red
//Serial.write(color[4]); // Pixel 2 green
//Serial.write(color[5]); // Pixel 2 blue
}
}
// Receive buffer excess command flush for 50ms
clearTime = millis() + 50;
while ( millis() < clearTime ) Serial.read();
return true;
}