Digital version of the classic game, with color selection.
Dependencies: 4DGL-uLCD-SE LSM9DS0 mbed-rtos mbed
main.cpp@0:98ea2d58b42a, 2015-10-20 (annotated)
- Committer:
- eshibut3
- Date:
- Tue Oct 20 23:03:34 2015 +0000
- Revision:
- 0:98ea2d58b42a
Initial commit. Three threads for erasing, color selection, and drawing on a digital Etch-A-Sketch.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
eshibut3 | 0:98ea2d58b42a | 1 | #include "mbed.h" |
eshibut3 | 0:98ea2d58b42a | 2 | #include "LSM9DS0.h" |
eshibut3 | 0:98ea2d58b42a | 3 | #include "rtos.h" |
eshibut3 | 0:98ea2d58b42a | 4 | #include "uLCD_4DGL.h" |
eshibut3 | 0:98ea2d58b42a | 5 | |
eshibut3 | 0:98ea2d58b42a | 6 | // SDO_XM and SDO_G are pulled up, so our addresses are: |
eshibut3 | 0:98ea2d58b42a | 7 | #define LSM9DS0_XM_ADDR 0x1D // Would be 0x1E if SDO_XM is LOW |
eshibut3 | 0:98ea2d58b42a | 8 | #define LSM9DS0_G_ADDR 0x6B // Would be 0x6A if SDO_G is LOW |
eshibut3 | 0:98ea2d58b42a | 9 | |
eshibut3 | 0:98ea2d58b42a | 10 | |
eshibut3 | 0:98ea2d58b42a | 11 | LSM9DS0 imu(p9, p10, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR); |
eshibut3 | 0:98ea2d58b42a | 12 | |
eshibut3 | 0:98ea2d58b42a | 13 | SPI shiftbrite(p5, p6, p7); |
eshibut3 | 0:98ea2d58b42a | 14 | Mutex color_lock; |
eshibut3 | 0:98ea2d58b42a | 15 | DigitalOut latch(p11); |
eshibut3 | 0:98ea2d58b42a | 16 | DigitalOut enable(p8); |
eshibut3 | 0:98ea2d58b42a | 17 | |
eshibut3 | 0:98ea2d58b42a | 18 | AnalogIn dial(p15); |
eshibut3 | 0:98ea2d58b42a | 19 | |
eshibut3 | 0:98ea2d58b42a | 20 | uLCD_4DGL lcd(p28, p27, p30); |
eshibut3 | 0:98ea2d58b42a | 21 | Mutex lcd_lock; |
eshibut3 | 0:98ea2d58b42a | 22 | |
eshibut3 | 0:98ea2d58b42a | 23 | //5-way switch |
eshibut3 | 0:98ea2d58b42a | 24 | DigitalIn right(p16); |
eshibut3 | 0:98ea2d58b42a | 25 | DigitalIn down(p17); |
eshibut3 | 0:98ea2d58b42a | 26 | DigitalIn left(p18); |
eshibut3 | 0:98ea2d58b42a | 27 | DigitalIn center(p19); |
eshibut3 | 0:98ea2d58b42a | 28 | DigitalIn up(p20); |
eshibut3 | 0:98ea2d58b42a | 29 | |
eshibut3 | 0:98ea2d58b42a | 30 | //Color selection |
eshibut3 | 0:98ea2d58b42a | 31 | int selector = 0; |
eshibut3 | 0:98ea2d58b42a | 32 | DigitalOut red_sel(LED1); |
eshibut3 | 0:98ea2d58b42a | 33 | DigitalOut green_sel(LED2); |
eshibut3 | 0:98ea2d58b42a | 34 | DigitalOut blue_sel(LED3); |
eshibut3 | 0:98ea2d58b42a | 35 | |
eshibut3 | 0:98ea2d58b42a | 36 | //current location on lcd NOTE: the 'pixel' drawn is actually 4 pixels (on a 64x64 grid) |
eshibut3 | 0:98ea2d58b42a | 37 | int pixel_x = 63; |
eshibut3 | 0:98ea2d58b42a | 38 | int pixel_y = 63; |
eshibut3 | 0:98ea2d58b42a | 39 | int color_value = 0x8A2BE2; |
eshibut3 | 0:98ea2d58b42a | 40 | |
eshibut3 | 0:98ea2d58b42a | 41 | //Thread checking for shaking (and clearing LCD if occuring) |
eshibut3 | 0:98ea2d58b42a | 42 | void erase_thread(void const*args) |
eshibut3 | 0:98ea2d58b42a | 43 | { |
eshibut3 | 0:98ea2d58b42a | 44 | while(true) { |
eshibut3 | 0:98ea2d58b42a | 45 | imu.readAccel(); |
eshibut3 | 0:98ea2d58b42a | 46 | printf("%.2f %.2f %.2f\n", imu.ax, imu.ay, imu.az); |
eshibut3 | 0:98ea2d58b42a | 47 | if (imu.ax > .20 || imu.ay > .20 || imu.az > 1.5) { |
eshibut3 | 0:98ea2d58b42a | 48 | lcd_lock.lock(); |
eshibut3 | 0:98ea2d58b42a | 49 | lcd.cls(); |
eshibut3 | 0:98ea2d58b42a | 50 | lcd_lock.unlock(); |
eshibut3 | 0:98ea2d58b42a | 51 | } |
eshibut3 | 0:98ea2d58b42a | 52 | Thread::wait(500); |
eshibut3 | 0:98ea2d58b42a | 53 | } |
eshibut3 | 0:98ea2d58b42a | 54 | } |
eshibut3 | 0:98ea2d58b42a | 55 | |
eshibut3 | 0:98ea2d58b42a | 56 | //Thread updating/changing the color |
eshibut3 | 0:98ea2d58b42a | 57 | void color_thread(void const*args) |
eshibut3 | 0:98ea2d58b42a | 58 | { |
eshibut3 | 0:98ea2d58b42a | 59 | red_sel=1; |
eshibut3 | 0:98ea2d58b42a | 60 | int red=0; |
eshibut3 | 0:98ea2d58b42a | 61 | int green=0; |
eshibut3 | 0:98ea2d58b42a | 62 | int blue=0; |
eshibut3 | 0:98ea2d58b42a | 63 | unsigned int high=0; |
eshibut3 | 0:98ea2d58b42a | 64 | unsigned int low=0; |
eshibut3 | 0:98ea2d58b42a | 65 | while(true) { |
eshibut3 | 0:98ea2d58b42a | 66 | //Figure out which color selector is being used |
eshibut3 | 0:98ea2d58b42a | 67 | if (!center) { |
eshibut3 | 0:98ea2d58b42a | 68 | selector = (selector==2)? 0: selector + 1; |
eshibut3 | 0:98ea2d58b42a | 69 | //Display selector |
eshibut3 | 0:98ea2d58b42a | 70 | red_sel = (selector==0); |
eshibut3 | 0:98ea2d58b42a | 71 | green_sel = (selector==1); |
eshibut3 | 0:98ea2d58b42a | 72 | blue_sel = (selector==2); |
eshibut3 | 0:98ea2d58b42a | 73 | } |
eshibut3 | 0:98ea2d58b42a | 74 | if (selector == 0) |
eshibut3 | 0:98ea2d58b42a | 75 | red = dial*0xFF; |
eshibut3 | 0:98ea2d58b42a | 76 | else if (selector == 1) |
eshibut3 | 0:98ea2d58b42a | 77 | green = dial*0xFF; |
eshibut3 | 0:98ea2d58b42a | 78 | else if (selector == 2) |
eshibut3 | 0:98ea2d58b42a | 79 | blue = dial*0xFF; |
eshibut3 | 0:98ea2d58b42a | 80 | high = (blue<<4) | ((red&0x3C0)>>6); |
eshibut3 | 0:98ea2d58b42a | 81 | low = (((red&0x3F)<<10)|(green)); |
eshibut3 | 0:98ea2d58b42a | 82 | shiftbrite.write(high); |
eshibut3 | 0:98ea2d58b42a | 83 | shiftbrite.write(low); |
eshibut3 | 0:98ea2d58b42a | 84 | latch=1; |
eshibut3 | 0:98ea2d58b42a | 85 | latch=0; |
eshibut3 | 0:98ea2d58b42a | 86 | color_lock.lock(); |
eshibut3 | 0:98ea2d58b42a | 87 | color_value = (red<<16)| (green<<8) | blue; |
eshibut3 | 0:98ea2d58b42a | 88 | color_lock.unlock(); |
eshibut3 | 0:98ea2d58b42a | 89 | Thread::wait(500); |
eshibut3 | 0:98ea2d58b42a | 90 | } |
eshibut3 | 0:98ea2d58b42a | 91 | |
eshibut3 | 0:98ea2d58b42a | 92 | } |
eshibut3 | 0:98ea2d58b42a | 93 | |
eshibut3 | 0:98ea2d58b42a | 94 | //Main thread reads in tactile switch, draws to LCD |
eshibut3 | 0:98ea2d58b42a | 95 | int main() |
eshibut3 | 0:98ea2d58b42a | 96 | { |
eshibut3 | 0:98ea2d58b42a | 97 | //Initializations and set-up |
eshibut3 | 0:98ea2d58b42a | 98 | imu.begin(); |
eshibut3 | 0:98ea2d58b42a | 99 | shiftbrite.format(16,0); |
eshibut3 | 0:98ea2d58b42a | 100 | shiftbrite.frequency(500000); |
eshibut3 | 0:98ea2d58b42a | 101 | enable=0; |
eshibut3 | 0:98ea2d58b42a | 102 | latch=0; |
eshibut3 | 0:98ea2d58b42a | 103 | wait(2); |
eshibut3 | 0:98ea2d58b42a | 104 | |
eshibut3 | 0:98ea2d58b42a | 105 | Thread eraser(erase_thread); |
eshibut3 | 0:98ea2d58b42a | 106 | Thread color(color_thread); |
eshibut3 | 0:98ea2d58b42a | 107 | bool no_movement = false; |
eshibut3 | 0:98ea2d58b42a | 108 | lcd_lock.lock(); |
eshibut3 | 0:98ea2d58b42a | 109 | lcd.background_color(0x606060); |
eshibut3 | 0:98ea2d58b42a | 110 | lcd.cls(); |
eshibut3 | 0:98ea2d58b42a | 111 | lcd_lock.unlock(); |
eshibut3 | 0:98ea2d58b42a | 112 | while(1) { |
eshibut3 | 0:98ea2d58b42a | 113 | no_movement = false; //flag indicating the joystick has been triggered |
eshibut3 | 0:98ea2d58b42a | 114 | if (!down && pixel_y != 0) |
eshibut3 | 0:98ea2d58b42a | 115 | pixel_y--; |
eshibut3 | 0:98ea2d58b42a | 116 | else if (!up && pixel_y!=63) |
eshibut3 | 0:98ea2d58b42a | 117 | pixel_y++; |
eshibut3 | 0:98ea2d58b42a | 118 | else if (!right && pixel_x!=0) |
eshibut3 | 0:98ea2d58b42a | 119 | pixel_x--; |
eshibut3 | 0:98ea2d58b42a | 120 | else if (!left && pixel_x!=63) |
eshibut3 | 0:98ea2d58b42a | 121 | pixel_x++; |
eshibut3 | 0:98ea2d58b42a | 122 | else |
eshibut3 | 0:98ea2d58b42a | 123 | no_movement = true; |
eshibut3 | 0:98ea2d58b42a | 124 | if (!no_movement) { // update the lcd screen |
eshibut3 | 0:98ea2d58b42a | 125 | lcd_lock.lock(); |
eshibut3 | 0:98ea2d58b42a | 126 | color_lock.lock(); |
eshibut3 | 0:98ea2d58b42a | 127 | lcd.filled_rectangle(pixel_x<<1, pixel_y<<1, (pixel_x<<1)+1, (pixel_y<<1)+1, color_value); |
eshibut3 | 0:98ea2d58b42a | 128 | color_lock.unlock(); |
eshibut3 | 0:98ea2d58b42a | 129 | lcd_lock.unlock(); |
eshibut3 | 0:98ea2d58b42a | 130 | } |
eshibut3 | 0:98ea2d58b42a | 131 | Thread::wait(100); |
eshibut3 | 0:98ea2d58b42a | 132 | } |
eshibut3 | 0:98ea2d58b42a | 133 | } |