├── LICENSE ├── README.md └── sketch └── UnoR4_Serial_Terminal └── UnoR4_Serial_Terminal.ino /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Naveen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nano_ESP32_Linux -------------------------------------------------------------------------------- /sketch/UnoR4_Serial_Terminal/UnoR4_Serial_Terminal.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SPI.h" 3 | #include "Adafruit_GFX.h" 4 | #include "Adafruit_ILI9341.h" 5 | 6 | #define CARDKB_I2C_ADDR 0x5F 7 | #define TEXT_WIDTH 8 8 | #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled 9 | #define BOTTOM_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen) 10 | #define TOP_FIXED_AREA 16 // Number of lines in top fixed area (lines counted from top of screen) 11 | #define YMAX 320 // Bottom of screen area 12 | 13 | // Arduino Uno R3/R4 14 | #define TFT_DC 9 15 | #define TFT_CS 10 16 | 17 | Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); 18 | 19 | // The initial y coordinate of the top of the scrolling area 20 | uint16_t yStart = TOP_FIXED_AREA; 21 | // yArea must be a integral multiple of TEXT_HEIGHT 22 | uint16_t yArea = YMAX - TOP_FIXED_AREA - BOTTOM_FIXED_AREA; 23 | // The initial y coordinate of the top of the bottom text line 24 | uint16_t yDraw = YMAX - BOTTOM_FIXED_AREA - TEXT_HEIGHT; 25 | 26 | // Keep track of the drawing x coordinate 27 | uint16_t xPos = 0; 28 | 29 | boolean escapeSeq = false; 30 | 31 | // We have to blank the top line each time the display is scrolled, but this takes up to 13 milliseconds 32 | // for a full width line, meanwhile the serial buffer may be filling... and overflowing 33 | // We can speed up scrolling of short text lines by just blanking the character we drew 34 | int blank[19]; // We keep all the strings pixel lengths to optimise the speed of the top line blanking 35 | 36 | void setup() 37 | { 38 | Serial.begin(115200); 39 | Serial1.begin(115200); 40 | 41 | Wire1.begin(); 42 | 43 | tft.begin(); 44 | tft.setRotation(0); // Must be 0 to work vertical scrolling correctly 45 | tft.fillScreen(ILI9341_BLACK); 46 | tft.setTextColor(ILI9341_BLACK, ILI9341_YELLOW); 47 | tft.fillRect(0, 0, 240, 16, ILI9341_YELLOW); 48 | tft.setTextSize(2); 49 | tft.print(" Nano ESP32 Linux"); 50 | tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); 51 | tft.setTextSize(1); 52 | tft.setScrollMargins(TOP_FIXED_AREA, BOTTOM_FIXED_AREA); 53 | 54 | for (byte i = 0; i < 18; i++) { 55 | blank[i] = 0; 56 | } 57 | } 58 | 59 | 60 | void loop(void) 61 | { 62 | while (Serial1.available()) { 63 | char c = Serial1.read(); 64 | // If it is a CR or we are near end of line then scroll one line 65 | if (c == '\r' || xPos > 231) { 66 | xPos = 0; 67 | yDraw = scroll_line(); // It can take 13ms to scroll and blank 16 pixel lines 68 | } 69 | 70 | // delete key 71 | if (c == 8) { 72 | xPos -= TEXT_WIDTH; 73 | Serial.print("\nDelete: "); 74 | //tft.drawChar(xPos, yDraw, 219, ILI9341_BLACK, ILI9341_BLACK , 1); 75 | tft.fillRect(xPos, yDraw, TEXT_WIDTH, TEXT_HEIGHT, ILI9341_BLACK); 76 | 77 | continue; 78 | } 79 | 80 | // start of ANSI Escape Sequence 81 | if (c == 27) { 82 | escapeSeq = true; 83 | } 84 | 85 | if (c > 31 && c < 128) { 86 | if (escapeSeq) { 87 | if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { 88 | escapeSeq = false; 89 | } 90 | continue; 91 | } 92 | tft.drawChar(xPos, yDraw, c, ILI9341_WHITE, ILI9341_BLACK , 1); 93 | xPos += TEXT_WIDTH; 94 | blank[(18 + (yStart - TOP_FIXED_AREA) / TEXT_HEIGHT) % 19] = xPos; // Keep a record of line lengths 95 | } 96 | } 97 | 98 | while (Serial.available()) { 99 | char c = Serial.read(); 100 | Serial1.print(c); 101 | } 102 | 103 | Wire1.requestFrom(CARDKB_I2C_ADDR, 1); 104 | 105 | while (Wire1.available()) { 106 | byte b = Wire1.read(); 107 | 108 | switch (b) { 109 | case 0xA8: // Fn+C 110 | Serial1.write(0x03); // Send Ctrl-C 111 | break; 112 | case 0x96: // Fn+P 113 | Serial1.write(0x10); // Send Ctrl-P 114 | break; 115 | case 0x90: // Fn+R 116 | Serial1.write(0x12); // Send Ctrl-R 117 | break; 118 | default: 119 | break; 120 | } 121 | 122 | char c = b; 123 | if (c != 0) { 124 | Serial1.print(c); 125 | Serial.print(c, HEX); 126 | } 127 | } 128 | } 129 | 130 | int scroll_line() { 131 | int yTemp = yStart; // Store the old yStart, this is where we draw the next line 132 | 133 | // Use the record of line lengths to optimise the rectangle size we need to erase the top line 134 | tft.fillRect(0, yStart, blank[(yStart - TOP_FIXED_AREA) / TEXT_HEIGHT], TEXT_HEIGHT, ILI9341_BLACK); 135 | 136 | // Change the top of the scroll area 137 | yStart += TEXT_HEIGHT; 138 | 139 | // The value must wrap around as the screen memory is a circular buffer 140 | if (yStart >= YMAX - BOTTOM_FIXED_AREA) { 141 | yStart = TOP_FIXED_AREA + (yStart - YMAX + BOTTOM_FIXED_AREA); 142 | } 143 | 144 | // Now we can scroll the display 145 | tft.scrollTo(yStart); 146 | 147 | return yTemp; 148 | } 149 | --------------------------------------------------------------------------------