This is the first rev of HW3 for IDD
Dependencies: MMA8451Q USBDevice mbed nRF24L01P
main.cpp
- Committer:
- antoniorohit
- Date:
- 2014-09-29
- Revision:
- 1:b58cf7dd20d7
- Parent:
- 0:d89cdf3d29f8
- Child:
- 2:c3b748d86642
File content as of revision 1:b58cf7dd20d7:
//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 1 #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; bool roll = (rxData[3] >> 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; } if(roll) { //MK.putc('r'); } #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 roll = ((XJOYVAL > 65000) || (XJOYVAL < 500) || (YJOYVAL > 65000) || (YJOYVAL < 500)) ? true: 0; 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(roll); // 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); }