153 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			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;
 | |
| }
 | |
| 
 |