305 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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   <<<<<<<<<<<<<<<<<<<<<<<<<
 |