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 20:27:21 2018 +0000
Revision:
6:646d22295054
Parent:
4:b79d152dec32
Implemented parsing

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