Add processing screenshot viewer

This commit is contained in:
Bodmer 2017-02-28 22:13:16 +00:00
parent cd356bb6c5
commit 3314530bbb
6 changed files with 906 additions and 23 deletions

View File

@ -1,23 +0,0 @@
This ILIScreenshotViewer.exe file is part of the Arduino ILI9341_due library.
A set of compatible functions is included in the "ESP8266_uncannyEyes" example.
The original library licence conditions that apply to the software in this folder are:
Copyright (c) 2014 Marek Buriak
Sources can be found at https://github.com/marekburiak/ILI9341_Due.
ILI9341_due is free software you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.
ILI9341_due is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ILI9341_due. If not, see <http://www.gnu.org/licenses/>.

Binary file not shown.

View File

@ -0,0 +1,285 @@
// This is a Processing sketch, see https://processing.org/ to download the IDE
// The sketch is a client that requests TFT screenshots from an Arduino board.
// The arduino must call a screenshot server function to respond with pixels.
// It has been created to work with the TFT_eSPI library here:
// https://github.com/Bodmer/TFT_eSPI
// The library provides a member function that reads the RGB values of screen pixels
// and an example TFT_Screen_Capture
// Captured images are stored in the sketch folder, use "Sketch" menu option
// "Show Sketch Folder" or press Ctrl+K
// Created by: Bodmer 27/1/17
// MIT licence applies, all text above must be included in derivative works
import processing.serial.*;
Serial serial; // Create an instance called serial
// ###########################################################################################
// # These are the values to change for a particular setup #
// #
int serial_port = 1; // Use enumerated value from list provided when sketch is run #
int serial_baud_rate = 921600; // Maximum tested is 921600 #
// #
int tft_width = 240; // TFT width in portrait orientation #
int tft_height = 320; // TFT height #
//int tft_width = 320; // TFT width in landscape orientation #
//int tft_height = 240; // TFT height #
// #
// Change the image file type saved here, comment out all but one #
//String image_type = ".jpg"; // #
String image_type = ".png"; // #
//String image_type = ".bmp"; // #
//String image_type = ".tif"; // #
// #
boolean save_border = true; // Save the image with a border #
int border = 5; // Border pixel width #
boolean fade = false; // Fade out image after saving #
// #
int max_images = 10; // Maximum of numbered saved images before over-writing files #
// #
// # End of the values to change for a particular setup #
// ###########################################################################################
int serialCount = 0; // Count of colour bytes arriving
int bgcolor = 255; // Background color
PImage img, tft_img;
color light_blue = color(50, 128, 255);
int[] rgb = new int[6]; // Buffer for the RGB colour bytes
int indexRed = 0; // Colour byte index in the array
int indexGreen = 1;
int indexBlue = 2;
long end = 10; // Whether we've heard from the microcontroller
int n = 0; // Whether we've heard from the microcontroller
boolean got_image = false;
int x_offset = (500 - tft_width) /2; // Image offsets in the window
int y_offset = 20; //
int xpos, ypos; // Pixel position
int beginTime = 0;
int pixelWaitTime = 100; // Wait a maximum of 100ms gap for image pixels to arrive
int lastPixelTime = 0; // Time that "image send" command was sent
int state = 0; // State machine current state
int progress_bar = 0;
int pixel_count = 0;
float percentage = 0;
int drawLoopCount = 0;
void setup() {
size(500, 540); // Stage size, could handle 480 pixel scrren
noStroke(); // No border on the next thing drawn
img = createImage(500, 540, ARGB);
for (int i = 0; i < img.pixels.length; i++) {
float a = map(i, 0, img.pixels.length, 255, 0);
img.pixels[i] = color(0, 153, 204, a);
}
tft_img = createImage(tft_width, tft_height, ARGB);
for (int i = 0; i < tft_img.pixels.length; i++) {
tft_img.pixels[i] = color(0, 0, 0, 255);
}
frameRate(5000); // High frame rate so draw() loops fast
xpos = 0;
ypos = 0;
// Print a list of the available serial ports
println("-----------------------");
println("Available Serial Ports:");
println("-----------------------");
printArray(Serial.list());
println("-----------------------");
print("Port currently used: [");
print(serial_port);
println("]");
String portName = Serial.list()[serial_port];
delay(1000);
serial = new Serial(this, portName, serial_baud_rate);
state = 99;
}
void draw() {
drawLoopCount++;
switch(state) {
case 0: // Init varaibles, send start request
tint(255, 255);
textAlign(CENTER);
textSize(20);
println("");
//println("Clearing pipe...");
beginTime = millis() + 200;
while ( millis() < beginTime )
{
serial.read();
}
println("Ready to receive image");
serial.write("S");
xpos = 0;
ypos = 0;
serialCount = 0;
progress_bar = 0;
pixel_count = 0;
percentage = 0;
drawLoopCount = 0;
lastPixelTime = millis() + 1000;
state = 1;
break;
case 1: // Console message, give server some time
println("Requesting image");
delay(10);
state = 2;
break;
case 2: // Get size and set start time for render time report
// To do: Read image size info, currently hard coded
beginTime = millis();
state = 3;
break;
case 3: // Request pixels and reder them
if ( serial.available() > 0 ) {
// Add the latest byte from the serial port to array:
while (serial.available()>0)
{
rgb[serialCount] = serial.read();
serialCount++;
// If we have 3 colour bytes:
if (serialCount >= 3 ) {
serialCount = 0;
pixel_count++;
stroke(rgb[indexRed], rgb[indexGreen], rgb[indexBlue]);
point(xpos + x_offset, ypos + y_offset);
lastPixelTime = millis();
xpos++;
if (xpos >= tft_width) {
xpos = 0;
print(".");
progress_bar++;
if (progress_bar >31)
{
progress_bar = 0;
percentage = 0.5 + 100 * pixel_count/(0.001 + tft_width * tft_height);
if (percentage > 100) percentage = 100;
println(" [ " + (int)percentage + "% ]");
}
ypos++;
if (ypos>=tft_height) {
ypos = 0;
println("Image fetch time = " + (millis()-beginTime)/1000.0 + " s");
state = 5;
}
}
}
}
} else
{
if (millis() > (lastPixelTime + pixelWaitTime))
{
println("");
System.err.println("No response, trying again...");
state = 4;
} else
{
// Request 64 more pixels (ESP8266 buffer size)
serial.write("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
serial.write("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
}
}
break;
case 4: // Time-out, flush serial buffer
println();
//println("Clearing serial pipe after a time-out");
int clearTime = millis() + 50;
while ( millis() < clearTime )
{
serial.read();
}
state = 0;
break;
case 5: // Save the image tot he sketch folder
println();
String filename = "tft_screen_" + n + image_type;
println("Saving image as \"" + filename); // Does not execute
if (save_border)
{
PImage partialSave = get(x_offset - border, y_offset - border, tft_width + 2*border, tft_height + 2*border);
partialSave.save(filename);
} else {
PImage partialSave = get(x_offset, y_offset, tft_width, tft_height);
partialSave.save(filename);
}
n = n + 1;
if (n>9) n = 0;
drawLoopCount = 0; // Reset value ready for counting in step 6
state = 6;
break;
case 6: // Fade the old image if enabled
delay(10);
if (fade)
{
tint(255, drawLoopCount);
image(tft_img, x_offset, y_offset);
}
if (drawLoopCount > 50) state = 0; // Wait for fade to end
break;
case 99: // Draw image viewer window
textAlign(CENTER);
textSize(20);
background(bgcolor);
image(img, 0, 0);
fill(0);
text("Bodmer's TFT image viewer", width/2, height-10);
stroke(0, 0, 0);
rect(x_offset - border, y_offset - border, tft_width - 1 + 2*border, tft_height - 1 + 2*border);
fill(100);
rect(x_offset, y_offset, tft_width-1, tft_height-1);
state = 0;
break;
default:
println("");
System.err.println("Error state reached - check sketch!");
break;
}
}

View File

@ -0,0 +1,165 @@
/*
This example draws rainbow colours on the screen, adds text in various
fast rendering fonts and then sends the TFT screen to a PC over the serial
port to a processing sketch.
This sketch uses the GLCD, 2, 4, 6 fonts.
Make sure all the display driver and pin comnenctions are correct by
editting the User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
//TFT_eSPI tft = TFT_eSPI(240, 320); // Could invoke custom library declaring width and height
unsigned long targetTime = 0;
byte red = 31;
byte green = 0;
byte blue = 0;
byte state = 0;
unsigned int colour = red << 11; // Colour order is RGB 5+6+5 bits each
void setup(void) {
Serial.begin(921600);
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
targetTime = millis() + 1000;
}
void loop() {
if (targetTime < millis()) {
targetTime = millis() + 4000;
rainbow_fill(); // Fill the screen with rainbow colours
// The standard AdaFruit font still works as before
tft.setTextColor(TFT_BLACK); // Background is not defined so it is transparent
tft.setCursor (60, 5);
tft.setTextFont(0); // Select font 0 which is the Adafruit font
tft.print("Original Adafruit font!");
//tft.drawString("Original Adafruit font!",60,5,1);
// The new larger fonts do not need to use the .setCursor call, coords are embedded
tft.setTextColor(TFT_BLACK); // Do not plot the background colour
// Overlay the black text on top of the rainbow plot (the advantage of not drawing the backgorund colour!)
tft.drawCentreString("Font size 2", 120, 14, 2); // Draw text centre at position 120, 14 using font 2
tft.drawCentreString("Font size 4", 120, 30, 4); // Draw text centre at position 120, 30 using font 4
tft.drawCentreString("12.34", 120, 54, 6); // Draw text centre at position 120, 54 using font 6
tft.drawCentreString("12.34 is in font size 6", 120, 92, 2); // Draw text centre at position 120, 92 using font 2
// Note the x position is the top of the font!
// draw a floating point number
float pi = 3.14159; // Value to print
int precision = 3; // Number of digits after decimal point
int xpos = 90; // x position
int ypos = 110; // y position
int font = 2; // font number 2
xpos += tft.drawFloat(pi, precision, xpos, ypos, font); // Draw rounded number and return new xpos delta for next print position
tft.drawString(" is pi", xpos, ypos, font); // Continue printing from new x position
tft.setTextSize(1); // We are using a size multiplier of 1
tft.setTextColor(TFT_BLACK); // Set text colour to black, no background (so transparent)
tft.setCursor(36, 150, 4); // Set cursor to x = 36, y = 150 and use font 4
tft.println("Transparent..."); // As we use println, the cursor moves to the next line
tft.setCursor(30, 175); // Set cursor to x = 30, y = 175
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set text colour to white and background to black
tft.println(" White on black ");
tft.setTextFont(4); // Select font 4 without moving cursor
tft.setCursor(50, 210); // Set cursor to x = 50, y = 210 without changing the font
tft.setTextColor(TFT_WHITE);
// By using #TFT print we can use all the formatting features like printing HEX
tft.print(57005, HEX); // Cursor does no move to next line
tft.println(48879, HEX); // print and move cursor to next line
tft.setTextColor(TFT_GREEN, TFT_BLACK); // This time we will use green text on a black background
tft.setTextFont(2); // Select font 2
// An easier way to position text and blank old text is to set the datum and use width padding
tft.setTextDatum(BC_DATUM); // Bottom centre for text datum
tft.setTextPadding(241); // Pad text to full screen wdth (240 pixels + 1 spare for +/-1 position rounding)
tft.drawString("Ode to a Small Lump of Green Putty", 120, 300 - 32);
tft.drawString("I Found in My Armpit One Midsummer", 120, 300 - 16);
tft.drawString("Morning", 120, 300);
tft.setTextDatum(TL_DATUM); // Reset to top left for text datum
screenServer();
}
}
// Fill screen with a rainbow pattern
void rainbow_fill()
{
// The colours and state are not initialised so the start colour changes each time the funtion is called
for (int i = 319; i >= 0; i--) {
// This is a "state machine" that ramps up/down the colour brightnesses in sequence
switch (state) {
case 0:
green ++;
if (green == 64) {
green = 63;
state = 1;
}
break;
case 1:
red--;
if (red == 255) {
red = 0;
state = 2;
}
break;
case 2:
blue ++;
if (blue == 32) {
blue = 31;
state = 3;
}
break;
case 3:
green --;
if (green == 255) {
green = 0;
state = 4;
}
break;
case 4:
red ++;
if (red == 32) {
red = 31;
state = 5;
}
break;
case 5:
blue --;
if (blue == 255) {
blue = 0;
state = 0;
}
break;
}
colour = red << 11 | green << 5 | blue;
// Draw a line 1 pixel wide in the selected colour
tft.drawFastHLine(0, i, tft.width(), colour); // in this example tft.width() returns the pixel width of the display
}
}

View File

@ -0,0 +1,304 @@
// Below is a copy of the processing sketch that can be used to capture the images
// The sketch beow is NOT and Arduino IDE sketch!
// Copy the sketch content below and remove the /* and */ at the beginning and end.
// The sketch runs in Processing version 3.3, it can be downloaded here:
// https://processing.org/download/
// When the sketch is loaded in Processing, save it as "Screenshot_Client", and click
// the run triangle. Then check the serial port list in the console report, edit the
// Processing sketch to use the right port by changing the port number allocated in
// "int serial_port = X;" at line 26 (see line 43 below)
// The Arduino IDE and Processing will share a serial port, make sure only one
// program tries to use the port at any time. Processing may "freeze" otherwise.
/* <<<<<<<<<<<<<<<<<<<<<<<<< REMOVE THIS LINE <<<<<<<<<<<<<<<<<<<<<<<<<
// This is a Processing sketch, see https://processing.org/ to download the IDE
// The sketch is a client that requests TFT screenshots from an Arduino board.
// The arduino must call a screenshot server function to respond with pixels.
// It has been created to work with the TFT_eSPI library here:
// https://github.com/Bodmer/TFT_eSPI
// The library provides a member function that reads the RGB values of screen pixels
// and an example TFT_Screen_Capture
// Captured images are stored in the Processing sketch folder, use "Sketch" menu option
// "Show Sketch Folder" or press Ctrl+K in the Processing IDE.
// Created by: Bodmer 27/1/17
// MIT licence applies, all text above must be included in derivative works
import processing.serial.*;
Serial serial; // Create an instance called serial
// ###########################################################################################
// # These are the values to change for a particular setup #
// #
int serial_port = 0; // Use enumerated value from list provided when sketch is run #
int serial_baud_rate = 921600; // Maximum tested is 921600 #
// #
int tft_width = 240; // TFT width in portrait orientation #
int tft_height = 320; // TFT height #
//int tft_width = 320; // TFT width in landscape orientation #
//int tft_height = 240; // TFT height #
// #
// Change the image file type saved here, comment out all but one #
//String image_type = ".jpg"; // #
String image_type = ".png"; // #
//String image_type = ".bmp"; // #
//String image_type = ".tif"; // #
// #
boolean save_border = true; // Save the image with a border #
int border = 5; // Border pixel width #
boolean fade = false; // Fade out image after saving #
// #
int max_images = 10; // Maximum of numbered saved images before over-writing files #
// #
// # End of the values to change for a particular setup #
// ###########################################################################################
int serialCount = 0; // Count of colour bytes arriving
int bgcolor = 255; // Background color
PImage img, tft_img;
color light_blue = color(50, 128, 255);
int[] rgb = new int[6]; // Buffer for the RGB colour bytes
int indexRed = 0; // Colour byte index in the array
int indexGreen = 1;
int indexBlue = 2;
long end = 10; // Whether we've heard from the microcontroller
int n = 0; // Whether we've heard from the microcontroller
boolean got_image = false;
int x_offset = (500 - tft_width) /2; // Image offsets in the window
int y_offset = 20; //
int xpos, ypos; // Pixel position
int beginTime = 0;
int pixelWaitTime = 100; // Wait a maximum of 100ms gap for image pixels to arrive
int lastPixelTime = 0; // Time that "image send" command was sent
int state = 0; // State machine current state
int progress_bar = 0;
int pixel_count = 0;
float percentage = 0;
int drawLoopCount = 0;
void setup() {
size(500, 540); // Stage size, could handle 480 pixel scrren
noStroke(); // No border on the next thing drawn
img = createImage(500, 540, ARGB);
for (int i = 0; i < img.pixels.length; i++) {
float a = map(i, 0, img.pixels.length, 255, 0);
img.pixels[i] = color(0, 153, 204, a);
}
tft_img = createImage(tft_width, tft_height, ARGB);
for (int i = 0; i < tft_img.pixels.length; i++) {
tft_img.pixels[i] = color(0, 0, 0, 255);
}
frameRate(5000); // High frame rate so draw() loops fast
xpos = 0;
ypos = 0;
// Print a list of the available serial ports
println("-----------------------");
println("Available Serial Ports:");
println("-----------------------");
printArray(Serial.list());
println("-----------------------");
print("Port currently used: [");
print(serial_port);
println("]");
String portName = Serial.list()[serial_port];
delay(1000);
serial = new Serial(this, portName, serial_baud_rate);
state = 99;
}
void draw() {
drawLoopCount++;
switch(state) {
case 0: // Init varaibles, send start request
tint(255, 255);
textAlign(CENTER);
textSize(20);
println("");
//println("Clearing pipe...");
beginTime = millis() + 200;
while ( millis() < beginTime )
{
serial.read();
}
println("Ready to receive image");
serial.write("S");
xpos = 0;
ypos = 0;
serialCount = 0;
progress_bar = 0;
pixel_count = 0;
percentage = 0;
drawLoopCount = 0;
lastPixelTime = millis() + 1000;
state = 1;
break;
case 1: // Console message, give server some time
println("Requesting image");
delay(10);
state = 2;
break;
case 2: // Get size and set start time for render time report
// To do: Read image size info, currently hard coded
beginTime = millis();
state = 3;
break;
case 3: // Request pixels and reder them
if ( serial.available() > 0 ) {
// Add the latest byte from the serial port to array:
while (serial.available()>0)
{
rgb[serialCount] = serial.read();
serialCount++;
// If we have 3 colour bytes:
if (serialCount >= 3 ) {
serialCount = 0;
pixel_count++;
stroke(rgb[indexRed], rgb[indexGreen], rgb[indexBlue]);
point(xpos + x_offset, ypos + y_offset);
lastPixelTime = millis();
xpos++;
if (xpos >= tft_width) {
xpos = 0;
print(".");
progress_bar++;
if (progress_bar >31)
{
progress_bar = 0;
percentage = 0.5 + 100 * pixel_count/(0.001 + tft_width * tft_height);
if (percentage > 100) percentage = 100;
println(" [ " + (int)percentage + "% ]");
}
ypos++;
if (ypos>=tft_height) {
ypos = 0;
println("Image fetch time = " + (millis()-beginTime)/1000.0 + " s");
state = 5;
}
}
}
}
} else
{
if (millis() > (lastPixelTime + pixelWaitTime))
{
println("");
System.err.println("No response, trying again...");
state = 4;
} else
{
// Request 64 more pixels (ESP8266 buffer size)
serial.write("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
serial.write("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
}
}
break;
case 4: // Time-out, flush serial buffer
println();
//println("Clearing serial pipe after a time-out");
int clearTime = millis() + 50;
while ( millis() < clearTime )
{
serial.read();
}
state = 0;
break;
case 5: // Save the image tot he sketch folder
println();
String filename = "tft_screen_" + n + image_type;
println("Saving image as \"" + filename); // Does not execute
if (save_border)
{
PImage partialSave = get(x_offset - border, y_offset - border, tft_width + 2*border, tft_height + 2*border);
partialSave.save(filename);
} else {
PImage partialSave = get(x_offset, y_offset, tft_width, tft_height);
partialSave.save(filename);
}
n = n + 1;
if (n>9) n = 0;
drawLoopCount = 0; // Reset value ready for counting in step 6
state = 6;
break;
case 6: // Fade the old image if enabled
delay(10);
if (fade)
{
tint(255, drawLoopCount);
image(tft_img, x_offset, y_offset);
}
if (drawLoopCount > 50) state = 0; // Wait for fade to end
break;
case 99: // Draw image viewer window
textAlign(CENTER);
textSize(20);
background(bgcolor);
image(img, 0, 0);
fill(0);
text("Bodmer's TFT image viewer", width/2, height-10);
stroke(0, 0, 0);
rect(x_offset - border, y_offset - border, tft_width - 1 + 2*border, tft_height - 1 + 2*border);
fill(100);
rect(x_offset, y_offset, tft_width-1, tft_height-1);
state = 0;
break;
default:
println("");
System.err.println("Error state reached - check sketch!");
break;
}
}
*/ // <<<<<<<<<<<<<<<<<<<<<<<<< REMOVE THIS LINE <<<<<<<<<<<<<<<<<<<<<<<<<

View File

@ -0,0 +1,152 @@
// 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 capy 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;
}