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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }