This is the first rev of HW3 for IDD
Dependencies: MMA8451Q USBDevice mbed nRF24L01P
Revision 0:d89cdf3d29f8, committed 2014-09-29
- 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
--- /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