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
main.cpp
00001 #include "mbed.h" 00002 #include "Thermal.h" 00003 #include "uLCD_4DGL.h" 00004 #include "USBHostKeyboard.h" 00005 #include "uVGAIII.h" 00006 00007 extern "C" struct node* scanner(const char* es); 00008 extern "C" float eval_expr(struct node* node, float x_value); 00009 00010 #include <math.h> 00011 00012 #define SIZE_X 480 00013 #define SIZE_Y 800 00014 00015 // Debugging LEDs 00016 DigitalOut led(LED1); 00017 DigitalOut led2(LED2); 00018 DigitalOut led3(LED3); 00019 DigitalOut led4(LED4); 00020 00021 uVGAIII ecran(p9,p10,p11); // serial tx, serial rx, reset pin; 00022 uLCD_4DGL uLCD(p13,p14,p12); // serial tx, serial rx, reset pin; 00023 Thermal printer(p28, p27, 19200); 00024 00025 // Variables to track cursor location on VGA 00026 int verticalCursor = 2; 00027 int horizontalCursor = 0; 00028 00029 // Variables to hold user input & index 00030 char currentLine[48]; 00031 int currentLineIndex = 0; 00032 00033 // Variables to track graph bitmaps 00034 unsigned char bitmap[5000]; 00035 char temp[8]; 00036 00037 // Mutexes for displays 00038 Mutex VGA_Lock; 00039 Mutex LCD_Lock; 00040 00041 char getPixel(int x, int y, int bk) { 00042 LCD_Lock.lock(); 00043 int r = uLCD.read_pixel(x, y); 00044 LCD_Lock.unlock(); 00045 00046 if (r == bk) //same as background 00047 return '0'; 00048 else 00049 return '1'; 00050 } 00051 00052 void makeBitmap() { 00053 LCD_Lock.lock(); 00054 int bk = uLCD.read_pixel(127,127); 00055 LCD_Lock.unlock(); 00056 for (int i = 0; i < 128*128/8; ++i) { 00057 for (int j = 0; j < 8; ++j) { //get next 8 bits and put them in temp array 00058 //temp[2*j] = getPixel((i%32)*4+j,i/32,bk); 00059 //temp[2*j+1] = temp[2*j]; 00060 temp[j] = getPixel((i%16)*8+j,i/16,bk); 00061 } 00062 00063 //need to convert to 0b format 00064 char * end; 00065 long int value = strtol(temp, &end, 2); 00066 //bitmap[64*(i/32)+(i%32)] = value; 00067 //bitmap[64*(i/32)+(i%32)+32] = value; 00068 bitmap[i] = value; 00069 led3 = !led3; 00070 } 00071 //printer.printf(bitmap); 00072 //printer.justify('C'); 00073 printer.printBitmap(128,128,bitmap); 00074 printer.feed(2); 00075 } 00076 00077 00078 // hardcode plot x^2 00079 void plotx2() 00080 { 00081 LCD_Lock.lock(); 00082 uLCD.cls(); 00083 int xOffset = 0; 00084 int yOffset = 127; 00085 int pastX = 0; 00086 int pastY = 127; 00087 int currentX = 0; 00088 int currentY = 0; 00089 00090 for(double i = 0; i < 11; i++) { 00091 //evaluate(); 00092 currentX = i*10 + xOffset; 00093 currentY = yOffset-(i*i); 00094 if(pastX == 0){ 00095 pastX = currentX; 00096 pastY = currentY; 00097 continue; 00098 } 00099 uLCD.line(pastX, pastY, currentX, currentY, RED); 00100 uLCD.line(pastX, pastY+1, currentX, currentY+1, RED); 00101 uLCD.line(pastX, pastY-1, currentX, currentY-1, RED); 00102 pastX = currentX; 00103 pastY = currentY; 00104 } 00105 LCD_Lock.unlock(); 00106 } 00107 00108 void plotsin() 00109 { 00110 LCD_Lock.lock(); 00111 uLCD.cls(); 00112 int xOffset = 0; 00113 int yOffset = 64; 00114 int pastX = 0; 00115 int pastY = 64; 00116 int currentX = 0; 00117 int currentY = 0; 00118 00119 for(double i = 0; i < 7; i+=.01) { 00120 //evaluate(); 00121 currentX = i*16 + xOffset; 00122 currentY = yOffset-40*sin(i); 00123 if(pastX == 0){ 00124 pastX = currentX; 00125 pastY = currentY; 00126 continue; 00127 } 00128 uLCD.line(pastX, pastY, currentX, currentY, RED); 00129 uLCD.line(pastX, pastY+1, currentX, currentY+1, RED); 00130 uLCD.line(pastX, pastY-1, currentX, currentY-1, RED); 00131 pastX = currentX; 00132 pastY = currentY; 00133 } 00134 LCD_Lock.unlock(); 00135 } 00136 00137 00138 void plotx2vga(void const *) 00139 { 00140 int xOffset = 600; 00141 int yOffset = 401; 00142 int pastX = 0; 00143 int pastY = 0; 00144 int currentX = 0; 00145 int currentY = 0; 00146 00147 VGA_Lock.lock(); 00148 00149 for(double i = -20; i < 21; i++) { 00150 led4 = !led4; 00151 //evaluate(); // Where evaluate would go...if we could parse input 00152 currentX = i*9 + xOffset; 00153 currentY = yOffset-(i*i); 00154 if(pastX == 0){ 00155 pastX = currentX; 00156 pastY = currentY; 00157 continue; 00158 } 00159 ecran.line(pastX, pastY, currentX, currentY, RED); 00160 pastX = currentX; 00161 pastY = currentY; 00162 } 00163 00164 VGA_Lock.unlock(); 00165 00166 while(1) { 00167 Thread::wait(500); 00168 } 00169 00170 } 00171 00172 00173 void onKeyCode(uint8_t key, uint8_t modifier) { 00174 00175 led3 = 1; 00176 00177 // Skip spaces, empty spaces 00178 if(key == 0 || key == 0x20) { 00179 led3 = 0; 00180 return; 00181 } 00182 00183 VGA_Lock.lock(); 00184 00185 // Handle newline 00186 if(key == 0x0A) { 00187 00188 // Check if going off end of screen 00189 if(verticalCursor > 37) { 00190 ecran.filled_rectangle(0, 0 , 399, 480, DGREY); 00191 verticalCursor = 0; 00192 } else { 00193 // Move cursor to newline 00194 verticalCursor+=2; 00195 } 00196 00197 horizontalCursor = 0; 00198 00199 ecran.move_cursor(verticalCursor, horizontalCursor); 00200 00201 ecran.puts(currentLine); 00202 00203 printer.printf(currentLine); 00204 printer.feed(2); 00205 00206 struct node* expr = scanner(currentLine); 00207 float val = eval_expr(expr, 3.0); 00208 uLCD.printf("Evaluate: %f \n",val); 00209 00210 for(size_t i = 0; i < 48; i++) { 00211 currentLine[i] = NULL; 00212 } 00213 00214 currentLineIndex = 0; 00215 00216 VGA_Lock.unlock(); 00217 00218 led3 = 0; 00219 return; 00220 } 00221 00222 if(key == 0x08) 00223 { 00224 if(currentLineIndex != 0) 00225 { 00226 currentLineIndex--; 00227 currentLine[currentLineIndex] = NULL; 00228 } 00229 led3 = 0; 00230 00231 VGA_Lock.unlock(); 00232 00233 return; 00234 } 00235 00236 // Append character to curret line string 00237 currentLine[currentLineIndex] = (char)key; 00238 00239 if(currentLineIndex < 47) { 00240 currentLineIndex++; 00241 } 00242 00243 VGA_Lock.unlock(); 00244 00245 led3 = 0; 00246 } 00247 00248 void keyboard_task(void const *) { 00249 00250 USBHostKeyboard keyboard; 00251 00252 while(1) { 00253 // try to connect a USB keyboard 00254 while(!keyboard.connect()) { 00255 Thread::wait(200); 00256 } 00257 00258 if(keyboard.connected()) led2 = 1; 00259 00260 // When connected, attach handler called on keyboard event 00261 keyboard.attach(onKeyCode); 00262 00263 // Wait until the keyboard is disconnected 00264 while(keyboard.connected()) 00265 Thread::wait(500); 00266 00267 led2 = 0; 00268 } 00269 } 00270 00271 int main() { 00272 led = 1; 00273 00274 // Set up uLCD 00275 uLCD.baudrate(300000); 00276 uLCD.background_color(BLACK); 00277 00278 // Set up VGA display 00279 ecran.baudrate(300000); 00280 ecran.screen_mode(LANDSCAPE); 00281 ecran.graphics_parameters(RESOLUTION, 2); 00282 ecran.touch_status(); 00283 ecran.background_color(DGREY); 00284 ecran.cls(); 00285 00286 ecran.move_cursor(0, 0); 00287 ecran.char_width('d'); 00288 ecran.char_height('d'); 00289 ecran.text_fgd_color(WHITE); 00290 ecran.text_bgd_color(DGREY); 00291 ecran.puts("Booting up..."); 00292 00293 ecran.filled_rectangle(398,0,402,480,RED); 00294 00295 // Use old style threading 00296 Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4); 00297 00298 // Launch VGA plot through thread 00299 Thread vgaPlot(plotx2vga, NULL, osPriorityNormal, 256 * 4); 00300 00301 plotx2(); 00302 makeBitmap(); 00303 led3 = 1; 00304 plotsin(); 00305 makeBitmap(); 00306 led3 = 1; 00307 00308 // Clear currentLine array before using 00309 for(size_t i = 0; i < 48; i++) { 00310 currentLine[i] = NULL; 00311 } 00312 00313 VGA_Lock.lock(); 00314 ecran.move_cursor(2, 0); 00315 ecran.puts("Ready!"); 00316 VGA_Lock.unlock(); 00317 00318 static const char es[] = "1 + 2 ^ 3 * 4 + 5 * x"; 00319 struct node* expr = scanner(es); 00320 float val = eval_expr(expr, 3.0); 00321 00322 while(1) { 00323 led=!led; 00324 Thread::wait(600); // Wait .6s in main thread 00325 } 00326 }
Generated on Mon Aug 15 2022 23:52:04 by 1.7.2