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
- Committer:
- zrussell3
- Date:
- 2018-12-13
- Revision:
- 3:2b6951038d5b
- Parent:
- 2:d97e71edb2b3
- Child:
- 4:b79d152dec32
File content as of revision 3:2b6951038d5b:
#include "mbed.h" #include "Thermal.h" #include "uLCD_4DGL.h" #include "USBHostKeyboard.h" #include "uVGAIII.h" #include <math.h> #define SIZE_X 480 #define SIZE_Y 800 // Debugging LEDs DigitalOut led(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); uVGAIII ecran(p9,p10,p11); // serial tx, serial rx, reset pin; uLCD_4DGL uLCD(p13,p14,p12); // serial tx, serial rx, reset pin; Thermal printer(p28, p27, 19200); // Variables to track cursor location on VGA int verticalCursor = 2; int horizontalCursor = 0; // Variables to hold user input & index char currentLine[48]; int currentLineIndex = 0; // Variables to track graph bitmaps unsigned char bitmap[5000]; char temp[8]; // Mutexes for displays Mutex VGA_Lock; Mutex LCD_Lock; char getPixel(int x, int y, int bk) { LCD_Lock.lock(); int r = uLCD.read_pixel(x, y); LCD_Lock.unlock(); if (r == bk) //same as background return '0'; else return '1'; } void makeBitmap() { LCD_Lock.lock(); int bk = uLCD.read_pixel(127,127); LCD_Lock.unlock(); for (int i = 0; i < 128*128/8; ++i) { for (int j = 0; j < 8; ++j) { //get next 8 bits and put them in temp array //temp[2*j] = getPixel((i%32)*4+j,i/32,bk); //temp[2*j+1] = temp[2*j]; temp[j] = getPixel((i%16)*8+j,i/16,bk); } //need to convert to 0b format char * end; long int value = strtol(temp, &end, 2); //bitmap[64*(i/32)+(i%32)] = value; //bitmap[64*(i/32)+(i%32)+32] = value; bitmap[i] = value; led3 = !led3; } //printer.printf(bitmap); //printer.justify('C'); printer.printBitmap(128,128,bitmap); printer.feed(2); } // hardcode plot x^2 void plotx2() { LCD_Lock.lock(); uLCD.cls(); int xOffset = 0; int yOffset = 127; int pastX = 0; int pastY = 127; int currentX = 0; int currentY = 0; for(double i = 0; i < 11; i++) { //evaluate(); currentX = i*10 + xOffset; currentY = yOffset-(i*i); if(pastX == 0){ pastX = currentX; pastY = currentY; continue; } uLCD.line(pastX, pastY, currentX, currentY, RED); uLCD.line(pastX, pastY+1, currentX, currentY+1, RED); uLCD.line(pastX, pastY-1, currentX, currentY-1, RED); pastX = currentX; pastY = currentY; } LCD_Lock.unlock(); } void plotsin() { LCD_Lock.lock(); uLCD.cls(); int xOffset = 0; int yOffset = 64; int pastX = 0; int pastY = 64; int currentX = 0; int currentY = 0; for(double i = 0; i < 7; i+=.01) { //evaluate(); currentX = i*16 + xOffset; currentY = yOffset-40*sin(i); if(pastX == 0){ pastX = currentX; pastY = currentY; continue; } uLCD.line(pastX, pastY, currentX, currentY, RED); uLCD.line(pastX, pastY+1, currentX, currentY+1, RED); uLCD.line(pastX, pastY-1, currentX, currentY-1, RED); pastX = currentX; pastY = currentY; } LCD_Lock.unlock(); } void plotx2vga(void const *) { int xOffset = 600; int yOffset = 401; int pastX = 0; int pastY = 0; int currentX = 0; int currentY = 0; VGA_Lock.lock(); for(double i = -20; i < 21; i++) { led4 = !led4; //evaluate(); // Where evaluate would go...if we could parse input currentX = i*9 + xOffset; currentY = yOffset-(i*i); if(pastX == 0){ pastX = currentX; pastY = currentY; continue; } ecran.line(pastX, pastY, currentX, currentY, RED); pastX = currentX; pastY = currentY; } VGA_Lock.unlock(); while(1) { Thread::wait(500); } } void onKeyCode(uint8_t key, uint8_t modifier) { led3 = 1; // Skip spaces, empty spaces if(key == 0 || key == 0x20) { led3 = 0; return; } VGA_Lock.lock(); // Handle newline if(key == 0x0A) { // Check if going off end of screen if(verticalCursor > 37) { ecran.filled_rectangle(0, 0 , 399, 480, DGREY); verticalCursor = 0; } else { // Move cursor to newline verticalCursor+=2; } horizontalCursor = 0; ecran.move_cursor(verticalCursor, horizontalCursor); ecran.puts(currentLine); printer.printf(currentLine); printer.feed(2); for(size_t i = 0; i < 48; i++) { currentLine[i] = NULL; } currentLineIndex = 0; VGA_Lock.unlock(); led3 = 0; return; } if(key == 0x08) { if(currentLineIndex != 0) { currentLineIndex--; currentLine[currentLineIndex] = NULL; } led3 = 0; VGA_Lock.unlock(); return; } // Append character to curret line string currentLine[currentLineIndex] = (char)key; if(currentLineIndex < 47) { currentLineIndex++; } VGA_Lock.unlock(); led3 = 0; } void keyboard_task(void const *) { USBHostKeyboard keyboard; while(1) { // try to connect a USB keyboard while(!keyboard.connect()) { Thread::wait(200); } if(keyboard.connected()) led2 = 1; // When connected, attach handler called on keyboard event keyboard.attach(onKeyCode); // Wait until the keyboard is disconnected while(keyboard.connected()) Thread::wait(500); led2 = 0; } } void LCD_Plots(void const *) { // Draw plots & print plotx2(); makeBitmap(); led3 = 1; plotsin(); makeBitmap(); led3 = 1; while(1) { Thread::wait(300); } } int main() { led = 1; // Set up uLCD uLCD.baudrate(300000); uLCD.background_color(BLACK); // Set up VGA display ecran.baudrate(300000); ecran.screen_mode(LANDSCAPE); ecran.graphics_parameters(RESOLUTION, 2); ecran.touch_status(); ecran.background_color(DGREY); ecran.cls(); ecran.move_cursor(0, 0); ecran.char_width('d'); ecran.char_height('d'); ecran.text_fgd_color(WHITE); ecran.text_bgd_color(DGREY); ecran.puts("Booting up..."); ecran.filled_rectangle(398,0,402,480,RED); // Use old style threading Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4); // Launch VGA plot through thread Thread vgaPlot(plotx2vga, NULL, osPriorityNormal, 256 * 4); plotx2(); makeBitmap(); led3 = 1; plotsin(); makeBitmap(); led3 = 1; // Launch LCD plots with thread // Thread lcdPlots(LCD_Plots, NULL, osPriorityNormal, 256 * 4); // Clear currentLine array before using for(size_t i = 0; i < 48; i++) { currentLine[i] = NULL; } VGA_Lock.lock(); ecran.move_cursor(2, 0); ecran.puts("Ready!"); VGA_Lock.unlock(); while(1) { led=!led; Thread::wait(600); // Wait .6s in main thread } }