diff --git a/Tools/ILIScreenshotViewer licence information.txt b/Tools/ILIScreenshotViewer licence information.txt
deleted file mode 100644
index 2c9f877..0000000
--- a/Tools/ILIScreenshotViewer licence information.txt
+++ /dev/null
@@ -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 .
diff --git a/Tools/ILIScreenshotViewer.exe b/Tools/ILIScreenshotViewer.exe
deleted file mode 100644
index d9f4ed9..0000000
Binary files a/Tools/ILIScreenshotViewer.exe and /dev/null differ
diff --git a/Tools/Screenshot_client/Screenshot_client.pde b/Tools/Screenshot_client/Screenshot_client.pde
new file mode 100644
index 0000000..22f6afd
--- /dev/null
+++ b/Tools/Screenshot_client/Screenshot_client.pde
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/examples/ILI9341/TFT_Screen_Capture/TFT_Screen_Capture.ino b/examples/ILI9341/TFT_Screen_Capture/TFT_Screen_Capture.ino
new file mode 100644
index 0000000..ceed295
--- /dev/null
+++ b/examples/ILI9341/TFT_Screen_Capture/TFT_Screen_Capture.ino
@@ -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 // Hardware-specific library
+#include
+
+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
+ }
+}
+
+
+
diff --git a/examples/ILI9341/TFT_Screen_Capture/processing_sketch.ino b/examples/ILI9341/TFT_Screen_Capture/processing_sketch.ino
new file mode 100644
index 0000000..4fafcbd
--- /dev/null
+++ b/examples/ILI9341/TFT_Screen_Capture/processing_sketch.ino
@@ -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 <<<<<<<<<<<<<<<<<<<<<<<<<
diff --git a/examples/ILI9341/TFT_Screen_Capture/screenServer.ino b/examples/ILI9341/TFT_Screen_Capture/screenServer.ino
new file mode 100644
index 0000000..53a8dc0
--- /dev/null
+++ b/examples/ILI9341/TFT_Screen_Capture/screenServer.ino
@@ -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;
+}
+