This is the first rev of HW3 for IDD

Dependencies:   MMA8451Q USBDevice mbed nRF24L01P

Files at this revision

API Documentation at this revision

Comitter:
antoniorohit
Date:
Mon Sep 29 08:45:58 2014 +0000
Child:
1:b58cf7dd20d7
Commit message:
First rev of HW3 for Interactive Device Design:; A game controller for use with the super cool steam game Blade Symphony

Changed in this revision

MMA8451Q.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF24L01P.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA8451Q.lib	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/emilmont/code/MMA8451Q/#c4d879a39775
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mjr/code/USBDevice/#81f57ea86f8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,353 @@
+//NOTE: NORDIC BOARD ONLY WORKS W/ MBED 84!
+//Chose pin ordering from https://mbed.org/questions/1360/Using-nRF24L01-Module-with-FRDM-Board/ -- unused pins
+
+#include "mbed.h"
+#include "nRF24L01P.h"                              // nordic library
+
+
+#define DEBUG 0
+#define BASE 0
+
+
+#include "USBMouseKeyboard.h"                       // for the sword - mouse/keyboard combo
+#if(BASE == 1)
+    USBMouseKeyboard MK;                                //Default is REL_MOUSE, bout could use ABS_MOUSE too
+#endif
+
+#define SCALING 50                                  // factor to multiply the accelerometer reading by (usually it is in the scale of g's. Decides sensitivity of mouse. Keep it less 100 (mouse is assigned an int8)
+ 
+// Accelerometer includes
+#include "MMA8451Q.h" 
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+// define I2C Pins and address for KL25Z. Taken from default sample code.
+PinName const SDA = PTE25;
+PinName const SCL = PTE24;
+
+// Base station TX/RX
+#define RX_NRF24L01P_ADDRESS       ((unsigned long long) 0xABABABABAB )
+#define TX_NRF24L01P_ADDRESS       ((unsigned long long) 0xCDCDCDCDCD )
+
+// Masks
+#define LOW8                        0x00FF
+#define HIGH3                       0x0007
+#define LOW5                        0x001F               
+#define HIGH6                       0x003F
+
+// The nRF24L01+ supports transfers from 1 to 32 bytes 
+// Assume 1680x1050 max screen resolution -- MSB to LSB 0 padded, 1 bit pressed, 11 bits x, 11 bits y for Fruit Ninja
+// For Blade Symphony, way fewer than 24 control bits for keyboard/house
+// From PC, only need (zero padded) 1 bit flag indicating if hit + 1 bit indicating Fruit Ninja (0) or Blade Symphony (1)
+#define TRANSFER_SIZE   3
+
+Serial pc(USBTX, USBRX);                                    // PC communication
+
+PwmOut motor(D2);                                           // Only specific pins have PWM capability
+
+nRF24L01P nordic(PTD2, PTD3, PTC5, PTD0, PTD5, PTA13);      // mosi, miso, sck, csn, ce, irq
+
+DigitalIn modeSW(D15);                                      // base station or sword mode
+
+// Accelerometer
+MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
+
+void Calibrate(void);
+void Acc_GetXY(void);
+
+int16_t x,y;                                              // variables to hold acceleration data after call to Acc_Get_All
+float x_b, y_b;                                           // acc bias
+
+// Debug
+DigitalOut greenLED(LED_GREEN);
+DigitalOut redLED(LED_RED);
+
+
+AnalogIn ATTACK(A0);
+AnalogIn SELECT(A1);
+AnalogIn XJOY(A2);
+AnalogIn YJOY(A3);
+
+DigitalIn JOYSEL(D3);
+
+
+bool isBaseStation;
+
+int main() {
+    int8_t mouse_x, mouse_y;
+    Calibrate();
+
+    modeSW.mode(PullUp);                                  // Configure pull down to minimize wire
+    
+    isBaseStation = (bool) !modeSW;                          // Detect device via jumper connection
+    wait(5);
+
+    // Power up wireless
+    nordic.powerUp();
+
+    // Display + change the (default) setup of the nRF24L01+ chip
+    
+    // Addresses 5 bytes long
+    
+    if (isBaseStation){
+        nordic.setTxAddress(TX_NRF24L01P_ADDRESS ,5); 
+        nordic.setRxAddress(RX_NRF24L01P_ADDRESS ,5); 
+    }
+    else{
+        nordic.setRxAddress(TX_NRF24L01P_ADDRESS ,5); 
+        nordic.setTxAddress(RX_NRF24L01P_ADDRESS ,5); 
+    }
+    
+    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  nordic.getRfFrequency() );
+    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  nordic.getRfOutputPower() );
+    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", nordic.getAirDataRate() );       // 1Mbps
+    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", nordic.getTxAddress() );
+    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", nordic.getRxAddress() );
+
+    // Data packet length
+    nordic.setTransferSize( TRANSFER_SIZE );
+
+    nordic.setReceiveMode();
+    nordic.enable();
+    
+    // Set motor PWM period
+    motor.period(0.001f);       // 1ms period
+    motor.write(0.0f);          // initially not on
+    
+   // motor.write(0.40f);                         // 95% duty cycle, relative to period
+
+    // Status flags
+    bool isBladeSymphony = false;
+    bool sensor1ON = false; 
+    
+    bool motorON = false; 
+
+    int rxDataCnt = 0;
+    
+    // Debug
+    int testcount = 0;
+    
+    // counting the mode
+    uint8_t mode_count = 0;
+
+    while (1) {
+        // Only reads 1 byte from PC + sends to other mcu (pads w/ 0 bytes) if base station
+        if (isBaseStation){
+
+            // If we've received anything over the host serial link...
+            if ( pc.readable() ) {
+                char txData[TRANSFER_SIZE];
+                // ...add it to the transmit buffer -- only care about first byte
+                txData[0] = pc.getc();
+                txData[1] = 100;
+                txData[2] = '\n';
+                
+                // Send the transmitbuffer via the nRF24L01+
+                nordic.write( NRF24L01P_PIPE_P0, txData, TRANSFER_SIZE );
+
+                // Toggle LED1 (to help debug Host -> nRF24L01+ communication)
+                /*if (txData[0] == 66)
+                    greenLED = !greenLED;*/
+            }
+
+            // If we've received anything in the nRF24L01+... = sword
+            if ( nordic.readable() ) {
+                char rxData[TRANSFER_SIZE];
+                // ...read the data into the receive buffer
+                rxDataCnt = nordic.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
+
+                //NOTE: NEED TO INTERPRET AS KEYS/MOUSE HERE
+                
+                int8_t dx = rxData[0];
+                int8_t dy = rxData[1];
+                
+              
+                bool mode_stat = (rxData[2] >> 7) & 1;
+                bool joy_but = (rxData[2] >> 6) & 1;
+                bool sel_stat = (rxData[2] >> 5) & 1;
+                bool attack_stat = (rxData[2] >> 4) & 1;
+                bool key_w = (rxData[2] >> 3) & 1;
+                bool key_s = (rxData[2] >> 2) & 1;
+                bool key_d = (rxData[2] >> 1) & 1;
+                bool key_a = (rxData[2] >> 0) & 1;
+                
+                #if(BASE == 1)
+                    MK.move(-dx, dy); 
+
+                    if(joy_but)
+                    {
+                        MK.putc(' ');
+                    }                
+                    if(key_w)
+                    {
+                        MK.putc('w');
+                    }
+                    if(key_a)
+                    {
+                        MK.putc('a');
+                    }
+                    if(key_s)
+                    {
+                        MK.putc('s');
+                    }
+                    if(key_d)
+                    {
+                        MK.putc('d');
+                    }
+                    if(sel_stat)
+                    {
+                        MK.click(MOUSE_RIGHT);
+                    }
+                    if(attack_stat)
+                    {
+                        MK.click(MOUSE_LEFT);
+                    }
+                    if(mode_stat)
+                    {
+                        MK.putc('1'+mode_count);
+                        mode_count = (mode_count+1)%3;
+                    }
+                    
+                    
+                #endif
+
+
+                pc.printf("x: %d y: %d \r\n",dx,dy);
+
+                // Display the receive buffer contents via the host serial link
+                /*for ( int i = 0; i < TRANSFER_SIZE; i++ ) {
+
+                    pc.putc( rxData[i] );
+                }*/
+
+                // Toggle LED2 (to help debug nRF24L01+ -> Host communication)
+                if (rxData[0] == 65 && rxData[1] == 66 && rxData[2] == 67){
+                    redLED = !redLED;
+                }
+
+            }
+        }
+
+
+        // sword
+        else{
+            int ATTACKVAL = ATTACK.read_u16();
+            int SELECTVAL = SELECT.read_u16();
+            int XJOYVAL = XJOY.read_u16();
+            int YJOYVAL = YJOY.read_u16();
+            int JOYSELVAL = (int) JOYSEL;
+            
+            bool mode_stat = (SELECTVAL > 45000) ? true: 0;
+            bool joy_but = JOYSEL == 0? true: 0;
+            bool sel_stat = (SELECTVAL > 10000 && SELECTVAL < 45000) ? true: 0;
+            bool attack_stat = ATTACKVAL > 10000? true: 0;
+            bool key_d = XJOYVAL > 35000 ? true: 0;
+            bool key_a = XJOYVAL < 30000 ? true : 0;
+            bool key_w = YJOYVAL > 35000 ? true: 0;
+            bool key_s = YJOYVAL < 30000 ? true: 0;
+            
+            uint8_t key_stat = mode_stat<<7|joy_but<<6|sel_stat<<5|attack_stat<<4|key_w<<3|key_s<<2|key_d<<1|key_a<<0;
+            
+            
+            pc.printf("F1: %d \t F2: %d \t X: %d \t Y: %d \t SEL: %d \r\n", ATTACKVAL, SELECTVAL, XJOYVAL, YJOYVAL, JOYSELVAL);
+      
+            greenLED = JOYSEL;
+
+            // Let serial read catch up on base station/PC side
+            wait_us(150);
+
+            char swordData[TRANSFER_SIZE]; 
+            
+            int16_t deltax = 768;
+            int16_t deltay = 345;
+            
+            if (testcount <= 2000){
+                deltax = testcount;
+                deltay = 2000-testcount;
+                testcount++;
+            }
+            else
+                testcount = 0;
+            
+            Acc_GetXY();
+        
+            mouse_x = x;
+            mouse_y = y;
+        
+            char lowX = char(mouse_x & LOW8);
+            char lowY = char(mouse_y & LOW8);
+            
+            // left A, right D, back S, up W
+            
+            // MSB -- LSB, 
+            swordData[0] = lowX;
+            swordData[1] = lowY; 
+            swordData[2] = char(key_stat); 
+            swordData[3] = char((sensor1ON << 7)|key_stat); 
+            
+            // Send the transmitbuffer via the nRF24L01+
+            nordic.write( NRF24L01P_PIPE_P0, swordData, TRANSFER_SIZE );
+
+            // NOTE: Action settings depending on type of game. Accelerometer data. Force sensitive resistor thresholding, etc. 
+
+            // If we've received anything from base station 
+                
+            if ( nordic.readable() ) {
+                char rxData[TRANSFER_SIZE];
+                // ...read the data into the receive buffer
+                rxDataCnt = nordic.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
+
+                #if DEBUG == 1
+                    // Toggle LED1 (to help debug Host -> nRF24L01+ communication)
+                    pc.printf("x: %f \t y: %f \r\n", mouse_x,mouse_y);
+                    greenLED = !greenLED;
+
+                    // Display the receive buffer contents via the host serial link
+                    for ( int i = 0; i < TRANSFER_SIZE; i++ ) {
+    
+                        pc.putc( rxData[i] );
+                    }
+
+                    // Toggle LED2 (to help debug nRF24L01+ -> Host communication)
+                    if (rxData[0] == 65 && rxData[1] == 100 && rxData[2] == 100){
+                        redLED = !redLED;
+                        }
+                #endif
+
+
+                // From PC, only need (zero padded) 1 bit flag indicating if hit + 1 bit indicating Fruit Ninja (0) or Blade Symphony (1)
+                // In first byte
+                isBladeSymphony = (rxData[0] >> 0) & 1;
+                motorON = (rxData[0] >> 1) & 1;                 // Motor ON when sword contact made
+                
+                greenLED = !isBladeSymphony;                    // LEDs active low
+                redLED = !motorON;
+                
+            }
+        }
+    }
+}
+
+void Calibrate(void) 
+{
+     unsigned int count1;
+     count1 = 0;
+     float sstatex = 0;
+     float sstatey = 0;
+     
+     do{ 
+     sstatex += acc.getAccX(); // Accumulate Samples
+     sstatey += acc.getAccY();
+     count1++;
+     }while(count1!=0x0400); // 1024 times
+     x_b = sstatex/1024.0; // division between 1024
+     y_b = sstatey/1024.0;
+}
+
+void Acc_GetXY(void)
+{
+    x = (int16_t)((acc.getAccX()- x_b)*SCALING);
+    y = (int16_t)((acc.getAccY()- y_b)*SCALING);
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/0b3ab51c8877
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF24L01P.lib	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Owen/code/nRF24L01P/#8ae48233b4e4