Mathematica-like environment on the mbed using USB keyboard input, VGA output, and a thermal printer.

Dependencies:   mbed Thermal 4DGL-uLCD-SE USBHost_Modified uVGAIII

Committer:
zrussell3
Date:
Thu Dec 13 07:49:27 2018 +0000
Revision:
3:2b6951038d5b
Parent:
2:d97e71edb2b3
Child:
4:b79d152dec32
Added bitmaps, printing, and plots

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zrussell3 0:824466ffa6da 1 #include "mbed.h"
zrussell3 0:824466ffa6da 2 #include "Thermal.h"
zrussell3 3:2b6951038d5b 3 #include "uLCD_4DGL.h"
zrussell3 0:824466ffa6da 4 #include "USBHostKeyboard.h"
zrussell3 0:824466ffa6da 5 #include "uVGAIII.h"
zrussell3 0:824466ffa6da 6
zrussell3 3:2b6951038d5b 7 #include <math.h>
zrussell3 2:d97e71edb2b3 8
zrussell3 0:824466ffa6da 9 #define SIZE_X 480
zrussell3 0:824466ffa6da 10 #define SIZE_Y 800
zrussell3 0:824466ffa6da 11
zrussell3 0:824466ffa6da 12 // Debugging LEDs
zrussell3 0:824466ffa6da 13 DigitalOut led(LED1);
zrussell3 0:824466ffa6da 14 DigitalOut led2(LED2);
zrussell3 0:824466ffa6da 15 DigitalOut led3(LED3);
zrussell3 0:824466ffa6da 16 DigitalOut led4(LED4);
zrussell3 0:824466ffa6da 17
zrussell3 0:824466ffa6da 18 uVGAIII ecran(p9,p10,p11); // serial tx, serial rx, reset pin;
zrussell3 2:d97e71edb2b3 19 uLCD_4DGL uLCD(p13,p14,p12); // serial tx, serial rx, reset pin;
zrussell3 0:824466ffa6da 20 Thermal printer(p28, p27, 19200);
zrussell3 0:824466ffa6da 21
zrussell3 3:2b6951038d5b 22 // Variables to track cursor location on VGA
zrussell3 0:824466ffa6da 23 int verticalCursor = 2;
zrussell3 0:824466ffa6da 24 int horizontalCursor = 0;
zrussell3 0:824466ffa6da 25
zrussell3 3:2b6951038d5b 26 // Variables to hold user input & index
zrussell3 0:824466ffa6da 27 char currentLine[48];
zrussell3 0:824466ffa6da 28 int currentLineIndex = 0;
zrussell3 0:824466ffa6da 29
zrussell3 3:2b6951038d5b 30 // Variables to track graph bitmaps
zrussell3 2:d97e71edb2b3 31 unsigned char bitmap[5000];
zrussell3 2:d97e71edb2b3 32 char temp[8];
zrussell3 2:d97e71edb2b3 33
zrussell3 3:2b6951038d5b 34 // Mutexes for displays
zrussell3 3:2b6951038d5b 35 Mutex VGA_Lock;
zrussell3 3:2b6951038d5b 36 Mutex LCD_Lock;
zrussell3 3:2b6951038d5b 37
zrussell3 2:d97e71edb2b3 38 char getPixel(int x, int y, int bk) {
zrussell3 3:2b6951038d5b 39 LCD_Lock.lock();
zrussell3 3:2b6951038d5b 40 int r = uLCD.read_pixel(x, y);
zrussell3 3:2b6951038d5b 41 LCD_Lock.unlock();
zrussell3 3:2b6951038d5b 42
zrussell3 2:d97e71edb2b3 43 if (r == bk) //same as background
zrussell3 2:d97e71edb2b3 44 return '0';
zrussell3 2:d97e71edb2b3 45 else
zrussell3 2:d97e71edb2b3 46 return '1';
zrussell3 2:d97e71edb2b3 47 }
zrussell3 2:d97e71edb2b3 48
zrussell3 2:d97e71edb2b3 49 void makeBitmap() {
zrussell3 3:2b6951038d5b 50 LCD_Lock.lock();
zrussell3 3:2b6951038d5b 51 int bk = uLCD.read_pixel(127,127);
zrussell3 3:2b6951038d5b 52 LCD_Lock.unlock();
zrussell3 3:2b6951038d5b 53 for (int i = 0; i < 128*128/8; ++i) {
zrussell3 2:d97e71edb2b3 54 for (int j = 0; j < 8; ++j) { //get next 8 bits and put them in temp array
zrussell3 3:2b6951038d5b 55 //temp[2*j] = getPixel((i%32)*4+j,i/32,bk);
zrussell3 3:2b6951038d5b 56 //temp[2*j+1] = temp[2*j];
zrussell3 3:2b6951038d5b 57 temp[j] = getPixel((i%16)*8+j,i/16,bk);
zrussell3 2:d97e71edb2b3 58 }
zrussell3 2:d97e71edb2b3 59
zrussell3 2:d97e71edb2b3 60 //need to convert to 0b format
zrussell3 2:d97e71edb2b3 61 char * end;
zrussell3 2:d97e71edb2b3 62 long int value = strtol(temp, &end, 2);
zrussell3 3:2b6951038d5b 63 //bitmap[64*(i/32)+(i%32)] = value;
zrussell3 3:2b6951038d5b 64 //bitmap[64*(i/32)+(i%32)+32] = value;
zrussell3 2:d97e71edb2b3 65 bitmap[i] = value;
zrussell3 2:d97e71edb2b3 66 led3 = !led3;
zrussell3 2:d97e71edb2b3 67 }
zrussell3 3:2b6951038d5b 68 //printer.printf(bitmap);
zrussell3 3:2b6951038d5b 69 //printer.justify('C');
zrussell3 3:2b6951038d5b 70 printer.printBitmap(128,128,bitmap);
zrussell3 2:d97e71edb2b3 71 printer.feed(2);
zrussell3 2:d97e71edb2b3 72 }
zrussell3 2:d97e71edb2b3 73
zrussell3 3:2b6951038d5b 74
zrussell3 0:824466ffa6da 75 // hardcode plot x^2
zrussell3 3:2b6951038d5b 76 void plotx2()
zrussell3 3:2b6951038d5b 77 {
zrussell3 3:2b6951038d5b 78 LCD_Lock.lock();
zrussell3 3:2b6951038d5b 79 uLCD.cls();
zrussell3 3:2b6951038d5b 80 int xOffset = 0;
zrussell3 3:2b6951038d5b 81 int yOffset = 127;
zrussell3 3:2b6951038d5b 82 int pastX = 0;
zrussell3 3:2b6951038d5b 83 int pastY = 127;
zrussell3 3:2b6951038d5b 84 int currentX = 0;
zrussell3 3:2b6951038d5b 85 int currentY = 0;
zrussell3 3:2b6951038d5b 86
zrussell3 3:2b6951038d5b 87 for(double i = 0; i < 11; i++) {
zrussell3 3:2b6951038d5b 88 //evaluate();
zrussell3 3:2b6951038d5b 89 currentX = i*10 + xOffset;
zrussell3 3:2b6951038d5b 90 currentY = yOffset-(i*i);
zrussell3 3:2b6951038d5b 91 if(pastX == 0){
zrussell3 3:2b6951038d5b 92 pastX = currentX;
zrussell3 3:2b6951038d5b 93 pastY = currentY;
zrussell3 3:2b6951038d5b 94 continue;
zrussell3 3:2b6951038d5b 95 }
zrussell3 3:2b6951038d5b 96 uLCD.line(pastX, pastY, currentX, currentY, RED);
zrussell3 3:2b6951038d5b 97 uLCD.line(pastX, pastY+1, currentX, currentY+1, RED);
zrussell3 3:2b6951038d5b 98 uLCD.line(pastX, pastY-1, currentX, currentY-1, RED);
zrussell3 3:2b6951038d5b 99 pastX = currentX;
zrussell3 3:2b6951038d5b 100 pastY = currentY;
zrussell3 3:2b6951038d5b 101 }
zrussell3 3:2b6951038d5b 102 LCD_Lock.unlock();
zrussell3 3:2b6951038d5b 103 }
zrussell3 3:2b6951038d5b 104
zrussell3 3:2b6951038d5b 105 void plotsin()
zrussell3 3:2b6951038d5b 106 {
zrussell3 3:2b6951038d5b 107 LCD_Lock.lock();
zrussell3 3:2b6951038d5b 108 uLCD.cls();
zrussell3 3:2b6951038d5b 109 int xOffset = 0;
zrussell3 3:2b6951038d5b 110 int yOffset = 64;
zrussell3 3:2b6951038d5b 111 int pastX = 0;
zrussell3 3:2b6951038d5b 112 int pastY = 64;
zrussell3 3:2b6951038d5b 113 int currentX = 0;
zrussell3 3:2b6951038d5b 114 int currentY = 0;
zrussell3 3:2b6951038d5b 115
zrussell3 3:2b6951038d5b 116 for(double i = 0; i < 7; i+=.01) {
zrussell3 3:2b6951038d5b 117 //evaluate();
zrussell3 3:2b6951038d5b 118 currentX = i*16 + xOffset;
zrussell3 3:2b6951038d5b 119 currentY = yOffset-40*sin(i);
zrussell3 3:2b6951038d5b 120 if(pastX == 0){
zrussell3 3:2b6951038d5b 121 pastX = currentX;
zrussell3 3:2b6951038d5b 122 pastY = currentY;
zrussell3 3:2b6951038d5b 123 continue;
zrussell3 3:2b6951038d5b 124 }
zrussell3 3:2b6951038d5b 125 uLCD.line(pastX, pastY, currentX, currentY, RED);
zrussell3 3:2b6951038d5b 126 uLCD.line(pastX, pastY+1, currentX, currentY+1, RED);
zrussell3 3:2b6951038d5b 127 uLCD.line(pastX, pastY-1, currentX, currentY-1, RED);
zrussell3 3:2b6951038d5b 128 pastX = currentX;
zrussell3 3:2b6951038d5b 129 pastY = currentY;
zrussell3 3:2b6951038d5b 130 }
zrussell3 3:2b6951038d5b 131 LCD_Lock.unlock();
zrussell3 3:2b6951038d5b 132 }
zrussell3 3:2b6951038d5b 133
zrussell3 3:2b6951038d5b 134
zrussell3 3:2b6951038d5b 135 void plotx2vga(void const *)
zrussell3 0:824466ffa6da 136 {
zrussell3 0:824466ffa6da 137 int xOffset = 600;
zrussell3 3:2b6951038d5b 138 int yOffset = 401;
zrussell3 0:824466ffa6da 139 int pastX = 0;
zrussell3 0:824466ffa6da 140 int pastY = 0;
zrussell3 0:824466ffa6da 141 int currentX = 0;
zrussell3 0:824466ffa6da 142 int currentY = 0;
zrussell3 0:824466ffa6da 143
zrussell3 3:2b6951038d5b 144 VGA_Lock.lock();
zrussell3 3:2b6951038d5b 145
zrussell3 3:2b6951038d5b 146 for(double i = -20; i < 21; i++) {
zrussell3 3:2b6951038d5b 147 led4 = !led4;
zrussell3 3:2b6951038d5b 148 //evaluate(); // Where evaluate would go...if we could parse input
zrussell3 3:2b6951038d5b 149 currentX = i*9 + xOffset;
zrussell3 0:824466ffa6da 150 currentY = yOffset-(i*i);
zrussell3 0:824466ffa6da 151 if(pastX == 0){
zrussell3 0:824466ffa6da 152 pastX = currentX;
zrussell3 0:824466ffa6da 153 pastY = currentY;
zrussell3 0:824466ffa6da 154 continue;
zrussell3 0:824466ffa6da 155 }
zrussell3 2:d97e71edb2b3 156 ecran.line(pastX, pastY, currentX, currentY, RED);
zrussell3 0:824466ffa6da 157 pastX = currentX;
zrussell3 0:824466ffa6da 158 pastY = currentY;
zrussell3 0:824466ffa6da 159 }
zrussell3 3:2b6951038d5b 160
zrussell3 3:2b6951038d5b 161 VGA_Lock.unlock();
zrussell3 3:2b6951038d5b 162
zrussell3 0:824466ffa6da 163 while(1) {
zrussell3 3:2b6951038d5b 164 Thread::wait(500);
zrussell3 0:824466ffa6da 165 }
zrussell3 3:2b6951038d5b 166
zrussell3 3:2b6951038d5b 167 }
zrussell3 2:d97e71edb2b3 168
zrussell3 0:824466ffa6da 169
zrussell3 0:824466ffa6da 170 void onKeyCode(uint8_t key, uint8_t modifier) {
zrussell3 0:824466ffa6da 171
zrussell3 0:824466ffa6da 172 led3 = 1;
zrussell3 0:824466ffa6da 173
zrussell3 3:2b6951038d5b 174 // Skip spaces, empty spaces
zrussell3 3:2b6951038d5b 175 if(key == 0 || key == 0x20) {
zrussell3 0:824466ffa6da 176 led3 = 0;
zrussell3 0:824466ffa6da 177 return;
zrussell3 0:824466ffa6da 178 }
zrussell3 0:824466ffa6da 179
zrussell3 3:2b6951038d5b 180 VGA_Lock.lock();
zrussell3 3:2b6951038d5b 181
zrussell3 0:824466ffa6da 182 // Handle newline
zrussell3 0:824466ffa6da 183 if(key == 0x0A) {
zrussell3 0:824466ffa6da 184
zrussell3 0:824466ffa6da 185 // Check if going off end of screen
zrussell3 0:824466ffa6da 186 if(verticalCursor > 37) {
zrussell3 0:824466ffa6da 187 ecran.filled_rectangle(0, 0 , 399, 480, DGREY);
zrussell3 0:824466ffa6da 188 verticalCursor = 0;
zrussell3 0:824466ffa6da 189 } else {
zrussell3 0:824466ffa6da 190 // Move cursor to newline
zrussell3 0:824466ffa6da 191 verticalCursor+=2;
zrussell3 0:824466ffa6da 192 }
zrussell3 0:824466ffa6da 193
zrussell3 0:824466ffa6da 194 horizontalCursor = 0;
zrussell3 0:824466ffa6da 195
zrussell3 0:824466ffa6da 196 ecran.move_cursor(verticalCursor, horizontalCursor);
zrussell3 0:824466ffa6da 197
zrussell3 0:824466ffa6da 198 ecran.puts(currentLine);
zrussell3 2:d97e71edb2b3 199
zrussell3 0:824466ffa6da 200 printer.printf(currentLine);
zrussell3 0:824466ffa6da 201 printer.feed(2);
zrussell3 0:824466ffa6da 202
zrussell3 0:824466ffa6da 203 for(size_t i = 0; i < 48; i++) {
zrussell3 0:824466ffa6da 204 currentLine[i] = NULL;
zrussell3 0:824466ffa6da 205 }
zrussell3 0:824466ffa6da 206
zrussell3 0:824466ffa6da 207 currentLineIndex = 0;
zrussell3 0:824466ffa6da 208
zrussell3 3:2b6951038d5b 209 VGA_Lock.unlock();
zrussell3 3:2b6951038d5b 210
zrussell3 0:824466ffa6da 211 led3 = 0;
zrussell3 0:824466ffa6da 212 return;
zrussell3 0:824466ffa6da 213 }
zrussell3 0:824466ffa6da 214
zrussell3 0:824466ffa6da 215 if(key == 0x08)
zrussell3 0:824466ffa6da 216 {
zrussell3 0:824466ffa6da 217 if(currentLineIndex != 0)
zrussell3 0:824466ffa6da 218 {
zrussell3 0:824466ffa6da 219 currentLineIndex--;
zrussell3 0:824466ffa6da 220 currentLine[currentLineIndex] = NULL;
zrussell3 0:824466ffa6da 221 }
zrussell3 0:824466ffa6da 222 led3 = 0;
zrussell3 3:2b6951038d5b 223
zrussell3 3:2b6951038d5b 224 VGA_Lock.unlock();
zrussell3 3:2b6951038d5b 225
zrussell3 0:824466ffa6da 226 return;
zrussell3 0:824466ffa6da 227 }
zrussell3 0:824466ffa6da 228
zrussell3 0:824466ffa6da 229 // Append character to curret line string
zrussell3 0:824466ffa6da 230 currentLine[currentLineIndex] = (char)key;
zrussell3 0:824466ffa6da 231
zrussell3 0:824466ffa6da 232 if(currentLineIndex < 47) {
zrussell3 0:824466ffa6da 233 currentLineIndex++;
zrussell3 0:824466ffa6da 234 }
zrussell3 0:824466ffa6da 235
zrussell3 3:2b6951038d5b 236 VGA_Lock.unlock();
zrussell3 3:2b6951038d5b 237
zrussell3 0:824466ffa6da 238 led3 = 0;
zrussell3 0:824466ffa6da 239 }
zrussell3 0:824466ffa6da 240
zrussell3 0:824466ffa6da 241 void keyboard_task(void const *) {
zrussell3 0:824466ffa6da 242
zrussell3 0:824466ffa6da 243 USBHostKeyboard keyboard;
zrussell3 0:824466ffa6da 244
zrussell3 0:824466ffa6da 245 while(1) {
zrussell3 0:824466ffa6da 246 // try to connect a USB keyboard
zrussell3 0:824466ffa6da 247 while(!keyboard.connect()) {
zrussell3 3:2b6951038d5b 248 Thread::wait(200);
zrussell3 0:824466ffa6da 249 }
zrussell3 0:824466ffa6da 250
zrussell3 0:824466ffa6da 251 if(keyboard.connected()) led2 = 1;
zrussell3 0:824466ffa6da 252
zrussell3 0:824466ffa6da 253 // When connected, attach handler called on keyboard event
zrussell3 0:824466ffa6da 254 keyboard.attach(onKeyCode);
zrussell3 0:824466ffa6da 255
zrussell3 0:824466ffa6da 256 // Wait until the keyboard is disconnected
zrussell3 0:824466ffa6da 257 while(keyboard.connected())
zrussell3 3:2b6951038d5b 258 Thread::wait(500);
zrussell3 0:824466ffa6da 259
zrussell3 0:824466ffa6da 260 led2 = 0;
zrussell3 0:824466ffa6da 261 }
zrussell3 0:824466ffa6da 262 }
zrussell3 0:824466ffa6da 263
zrussell3 3:2b6951038d5b 264 void LCD_Plots(void const *) {
zrussell3 3:2b6951038d5b 265 // Draw plots & print
zrussell3 3:2b6951038d5b 266 plotx2();
zrussell3 3:2b6951038d5b 267 makeBitmap();
zrussell3 3:2b6951038d5b 268 led3 = 1;
zrussell3 3:2b6951038d5b 269 plotsin();
zrussell3 3:2b6951038d5b 270 makeBitmap();
zrussell3 3:2b6951038d5b 271 led3 = 1;
zrussell3 3:2b6951038d5b 272
zrussell3 3:2b6951038d5b 273 while(1) {
zrussell3 3:2b6951038d5b 274 Thread::wait(300);
zrussell3 3:2b6951038d5b 275 }
zrussell3 3:2b6951038d5b 276 }
zrussell3 3:2b6951038d5b 277
zrussell3 2:d97e71edb2b3 278 int main() {
zrussell3 2:d97e71edb2b3 279 led = 1;
zrussell3 3:2b6951038d5b 280
zrussell3 3:2b6951038d5b 281 // Set up uLCD
zrussell3 3:2b6951038d5b 282 uLCD.baudrate(300000);
zrussell3 3:2b6951038d5b 283 uLCD.background_color(BLACK);
zrussell3 3:2b6951038d5b 284
zrussell3 3:2b6951038d5b 285 // Set up VGA display
zrussell3 0:824466ffa6da 286 ecran.baudrate(300000);
zrussell3 0:824466ffa6da 287 ecran.screen_mode(LANDSCAPE);
zrussell3 0:824466ffa6da 288 ecran.graphics_parameters(RESOLUTION, 2);
zrussell3 0:824466ffa6da 289 ecran.touch_status();
zrussell3 2:d97e71edb2b3 290 ecran.background_color(DGREY);
zrussell3 0:824466ffa6da 291 ecran.cls();
zrussell3 0:824466ffa6da 292
zrussell3 0:824466ffa6da 293 ecran.move_cursor(0, 0);
zrussell3 0:824466ffa6da 294 ecran.char_width('d');
zrussell3 0:824466ffa6da 295 ecran.char_height('d');
zrussell3 0:824466ffa6da 296 ecran.text_fgd_color(WHITE);
zrussell3 0:824466ffa6da 297 ecran.text_bgd_color(DGREY);
zrussell3 0:824466ffa6da 298 ecran.puts("Booting up...");
zrussell3 0:824466ffa6da 299
zrussell3 3:2b6951038d5b 300 ecran.filled_rectangle(398,0,402,480,RED);
zrussell3 0:824466ffa6da 301
zrussell3 0:824466ffa6da 302 // Use old style threading
zrussell3 3:2b6951038d5b 303 Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4);
zrussell3 0:824466ffa6da 304
zrussell3 3:2b6951038d5b 305 // Launch VGA plot through thread
zrussell3 3:2b6951038d5b 306 Thread vgaPlot(plotx2vga, NULL, osPriorityNormal, 256 * 4);
zrussell3 3:2b6951038d5b 307
zrussell3 3:2b6951038d5b 308 plotx2();
zrussell3 2:d97e71edb2b3 309 makeBitmap();
zrussell3 2:d97e71edb2b3 310 led3 = 1;
zrussell3 3:2b6951038d5b 311 plotsin();
zrussell3 3:2b6951038d5b 312 makeBitmap();
zrussell3 3:2b6951038d5b 313 led3 = 1;
zrussell3 3:2b6951038d5b 314
zrussell3 3:2b6951038d5b 315 // Launch LCD plots with thread
zrussell3 3:2b6951038d5b 316 // Thread lcdPlots(LCD_Plots, NULL, osPriorityNormal, 256 * 4);
zrussell3 0:824466ffa6da 317
zrussell3 0:824466ffa6da 318 // Clear currentLine array before using
zrussell3 0:824466ffa6da 319 for(size_t i = 0; i < 48; i++) {
zrussell3 0:824466ffa6da 320 currentLine[i] = NULL;
zrussell3 0:824466ffa6da 321 }
zrussell3 0:824466ffa6da 322
zrussell3 3:2b6951038d5b 323 VGA_Lock.lock();
zrussell3 3:2b6951038d5b 324 ecran.move_cursor(2, 0);
zrussell3 3:2b6951038d5b 325 ecran.puts("Ready!");
zrussell3 3:2b6951038d5b 326 VGA_Lock.unlock();
zrussell3 2:d97e71edb2b3 327
zrussell3 0:824466ffa6da 328 while(1) {
zrussell3 0:824466ffa6da 329 led=!led;
zrussell3 3:2b6951038d5b 330 Thread::wait(600); // Wait .6s in main thread
zrussell3 0:824466ffa6da 331 }
zrussell3 0:824466ffa6da 332 }