This is the first rev of HW3 for IDD
Dependencies: MMA8451Q USBDevice mbed nRF24L01P
main.cpp
- Committer:
- antoniorohit
- Date:
- 2014-09-29
- Revision:
- 2:c3b748d86642
- Parent:
- 1:b58cf7dd20d7
- Child:
- 3:99ed0483f868
File content as of revision 2:c3b748d86642:
//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(dy, dx);
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);
}