FRDM-KL25Z with Nokia 3110 type LCD display Using accelerometer to make movements

Dependencies:   MMA8451Q N3310LCD mbed

Fork of FRDM_MMA8451Q by mbed official

Revision:
8:857444086b3f
Parent:
5:bf5becf7469c
Child:
9:1afbf9010118
--- a/main.cpp	Tue Feb 19 23:46:45 2013 +0000
+++ b/main.cpp	Fri Mar 15 22:48:58 2013 +0000
@@ -1,18 +1,315 @@
 #include "mbed.h"
 #include "MMA8451Q.h"
+#include "N3310SPIConfig.h"
+#include "N3310LCD.h"
+#include "Joystick.h"
+#include "splash.h"
 
 #define MMA8451_I2C_ADDRESS (0x1d<<1)
+Serial pc(USBTX,USBRX);
 
-int main(void) {
-    MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
-    PwmOut rled(LED_RED);
-    PwmOut gled(LED_GREEN);
-    PwmOut bled(LED_BLUE);
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+// menu starting points
+#define MENU_X    10        // 0-83
+#define MENU_Y    0        // 0-5
+
+#define MENU_ITEMS 3
+
+int8_t blflag = 1;  // Backlight initially ON
+
+
+void about(N3310LCD* lcd, Joystick* jstick);
+void draw(N3310LCD* lcd, Joystick* jstick);
+void backlight(N3310LCD* lcd, Joystick* jstick);
+void waitforOKKey(N3310LCD* lcd, Joystick* jstick);
+uint8_t checkKeypressed( Joystick* jstick);
+
+// menu definition
+char menu_items[MENU_ITEMS][12] = {
+    "SKETCH",
+    "BACKLIGHT",
+    "ABOUT"
+};
+
+void (*menu_funcs[MENU_ITEMS])(N3310LCD*,Joystick*) = {
+    draw,
+    backlight,
+    about
+};
+
+
+void about(N3310LCD* lcd, Joystick* jstick)
+{
+    lcd->writeString(0, 0,  "mbed-a-sketch", NORMAL);
+    lcd->writeString(12, 1, "driven by", NORMAL);
+    lcd->writeString(10, 2, "KL25Z mbed", NORMAL);
+    lcd->writeString(0, 3,  "By AD Lindsay", NORMAL);
+}
+
+void backlight(N3310LCD* lcd, Joystick* jstick)
+{
+    lcd->writeString( 0, 1, "Toggle", NORMAL);
+    lcd->writeString( 0, 2, "Backlight", NORMAL);
+    if( blflag != 0 ) {
+        lcd->writeString( 60, 2, "Off", HIGHLIGHT);
+    } else {
+        lcd->writeString( 60, 2, "On", HIGHLIGHT);
+    }
+
+    int8_t i;
+    bool exitFlag = false;
+
+    while( !exitFlag ) {
+        for (int i = 0; i < NUM_KEYS; i++) {
+            if (jstick->getKeyState(i) != 0) {
+                jstick->resetKeyState(i);  // reset button flag
+                switch(i) {
+                    case CENTER_KEY:
+                        exitFlag = true;
+                        break;
+                    case UP_KEY:
+                    case DOWN_KEY:
+                        if( blflag != 0 ) {
+                            blflag=0;
+                            lcd->backlight( OFF );
+                        }   else {
+                            blflag = 1;
+                            lcd->backlight( ON );
+                        }
+                        lcd->writeString( 60, 2, (blflag != 0 ? (char*)"Off" : (char*)"On "), HIGHLIGHT);
+                        break;
+                }
+            }
+        }
+    }
+}
+
+
+void draw(N3310LCD* lcd, Joystick* jstick)
+{
+    MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS, false, 4);
+    lcd->cls();
+//    lcd->writeString(10, 2, "La", NORMAL);
+
+    // Draw a rectangle
+    lcd->drawRectangle(0,0,83,47, PIXEL_ON);
+
+    int8_t px = 42;
+    int8_t py = 24;
+    int8_t nx = px;
+    int8_t ny = py;
+
+    lcd->setPixel( px, py, PIXEL_ON );
+
+    float x, y; //, z;
+    float cValues[3] = { 0.0, 0.0, 0.0 };
+    int16_t xI, yI; //, zI;
+    int16_t xInc, yInc;
+
+    // Take 100 readings to get stable centre point
+
+    for( int i = 0; i < 100; i++ ) {
+        float axis[3] = { 0.0, 0.0, 0.0 };
+        acc.getAccAllAxis( axis );
+        cValues[0] += axis[0];
+        cValues[1] += axis[1];
+//        cValues[2] += axis[2];
+    }
+
+    cValues[0] /= 100.0;
+    cValues[1] /= 100.0;
+//    cValues[2] /= 100.0;
+//    pc.printf( "Steady State X: %f Y: %f Z: %f\n", cValues[0], cValues[1], cValues[2] );
+
+    // Exit on joystick pressed
+    bool exitFlag = false;
+    while ( !exitFlag ) {
+        uint8_t keyPress = checkKeypressed( jstick );
+        if( keyPress == CENTER_KEY )
+            exitFlag = true;
+
+        x = (acc.getAccX() - cValues[0]) * 100.0;
+        y = (acc.getAccY() - cValues[1]) * 100.0;
+//        z = (acc.getAccZ() - cValues[2]) * 100.0;
+//       pc.printf( "X: %f Y: %f Z: %f\n", x, y, z);
+
+        xI = (int16_t)(x);
+        yI = (int16_t)(y);
+//        zI = (int16_t)(z);
+        xInc = xI/10;
+        yInc = ((yI/10) * -1);
+
+        nx += xInc;
+        ny += yInc;
+
+        nx = MAX( 1, MIN( nx, 82 ) );
+        ny = MAX( 1, MIN( ny, 46 ) );
+
+        if( abs(xInc) > 1 || abs(yInc) > 1 ) {
+            // Draw line
+            lcd->drawLine((uint8_t)px, (uint8_t)py, (uint8_t)nx, (uint8_t)ny, PIXEL_ON);
+        } else {
+            // Plot pixel
+            lcd->setPixel( (uint8_t)nx, (uint8_t)ny, PIXEL_ON );
+        }
+
+        px = nx;
+        py = ny;
+
+//        pc.printf( "X: %d Y: %d Z: %d\n", xI, yI, zI);
+        wait(0.1);
+    }
+
+
+}
+
+
+
+
+void initMenu(N3310LCD* lcd)
+{
+    lcd->writeString(MENU_X, MENU_Y, menu_items[0], HIGHLIGHT );
+
+    for (int i = 1; i < MENU_ITEMS; i++) {
+        lcd->writeString(MENU_X, MENU_Y + i, menu_items[i], NORMAL);
+    }
+}
+
+void waitforOKKey(N3310LCD* lcd, Joystick* jstick)
+{
+    lcd->writeString(38, 5, "OK", HIGHLIGHT );
+
+    int key = 0xFF;
+    while (key != CENTER_KEY) {
+        for (int i = 0; i < NUM_KEYS; i++) {
+            if (jstick->getKeyState(i) !=0) {
+                jstick->resetKeyState(i);  // reset
+                if (CENTER_KEY == i) key = CENTER_KEY;
+            }
+        }
+    }
+}
+
+// Check if joystick is moved or pressed
+uint8_t checkKeypressed( Joystick* jstick)
+{
+    uint8_t key = 0xFF;
+
+    for(int i=0; i<NUM_KEYS; i++) {
+        if (jstick->getKeyState(i) !=0) {
+            jstick->resetKeyState(i);  // reset
+            if (CENTER_KEY == i) key = CENTER_KEY;
+        }
+    }
+    return key;
+}
+
+
+int main(void)
+{
+//    MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS, false, 4);
+    Joystick jstick(N3310SPIPort::AD0);
+    N3310LCD lcd(N3310SPIPort::MOSI, N3310SPIPort::MISO, N3310SPIPort::SCK,
+                 N3310SPIPort::CE, N3310SPIPort::DAT_CMD, N3310SPIPort::LCD_RST,
+                 N3310SPIPort::BL_ON);
+    lcd.init();
+    lcd.cls();
+    lcd.backlight(ON);
+
+    // demo stuff
+    // autoDemo(&lcd);
+
+    lcd.drawBitmap(0, 0, splash, 84, 48);
+    wait( 5 );
+    lcd.cls();
+
+    initMenu(&lcd);
+    int currentMenuItem = 0;
+    Ticker jstickPoll;
+    jstickPoll.attach(&jstick, &Joystick::updateADCKey, 0.01);    // check ever 10ms
 
     while (true) {
-        rled = 1.0 - abs(acc.getAccX());
-        gled = 1.0 - abs(acc.getAccY());
-        bled = 1.0 - abs(acc.getAccZ());
-        wait(0.1);
+        for (int i = 0; i < NUM_KEYS; i++) {
+            if (jstick.getKeyState(i) != 0) {
+                jstick.resetKeyState(i);  // reset button flag
+                switch(i) {
+                    case UP_KEY:
+                        // current item to normal display
+                        lcd.writeString(MENU_X, MENU_Y + currentMenuItem, menu_items[currentMenuItem], NORMAL);
+                        currentMenuItem -=1;
+                        if (currentMenuItem <0)  currentMenuItem = MENU_ITEMS -1;
+                        // next item to highlight display
+                        lcd.writeString(MENU_X, MENU_Y + currentMenuItem, menu_items[currentMenuItem], HIGHLIGHT);
+                        break;
+
+                    case DOWN_KEY:
+                        // current item to normal display
+                        lcd.writeString(MENU_X, MENU_Y + currentMenuItem, menu_items[currentMenuItem], NORMAL);
+                        currentMenuItem +=1;
+                        if(currentMenuItem >(MENU_ITEMS - 1))  currentMenuItem = 0;
+                        // next item to highlight display
+                        lcd.writeString(MENU_X, MENU_Y + currentMenuItem, menu_items[currentMenuItem], HIGHLIGHT);
+                        break;
+
+                    case LEFT_KEY:
+                        initMenu(&lcd);
+                        currentMenuItem = 0;
+                        break;
+
+                    case RIGHT_KEY:
+                        lcd.cls();
+                        (*menu_funcs[currentMenuItem])(&lcd, &jstick);
+                        waitforOKKey(&lcd, &jstick);
+                        lcd.cls();
+                        initMenu(&lcd);
+                        currentMenuItem = 0;
+                        break;
+                }
+            }
+        }
     }
+
+    /*
+    //    PwmOut rled(LED_RED);
+    //    PwmOut gled(LED_GREEN);
+    //    PwmOut bled(LED_BLUE);
+        float x, y, z;
+        float cValues[3] = { 0.0, 0.0, 0.0 };
+        int16_t xI, yI, zI;
+
+        // Take 100 readings to get stable centre point
+
+        for( int i = 0; i < 100; i++ ) {
+            float axis[3] = { 0.0, 0.0, 0.0 };
+            acc.getAccAllAxis( axis );
+            cValues[0] += axis[0];
+            cValues[1] += axis[1];
+            cValues[2] += axis[2];
+        }
+
+        cValues[0] /= 100.0;
+        cValues[1] /= 100.0;
+        cValues[2] /= 100.0;
+        pc.printf( "Steady State X: %f Y: %f Z: %f\n", cValues[0], cValues[1], cValues[2] );
+
+        while (true) {
+
+            x = (acc.getAccX() - cValues[0]) * 100.0;
+            y = (acc.getAccY() - cValues[1]) * 100.0;
+            z = (acc.getAccZ() - cValues[2]) * 100.0;
+     //       pc.printf( "X: %f Y: %f Z: %f\n", x, y, z);
+
+            xI = (int16_t)(x);
+            yI = (int16_t)(y);
+            zI = (int16_t)(z);
+            pc.printf( "X: %d Y: %d Z: %d\n", xI, yI, zI);
+    //        pc.printf( "X: %f Y: %f Z: %f\n", x*100.0, y*100.0, z*100.0);
+    //        rled = 1.0 - abs(acc.getAccX());
+    //        gled = 1.0 - abs(acc.getAccY());
+    //        bled = 1.0 - abs(acc.getAccZ());
+            wait(0.5);
+        }
+    */
 }