Part 1 + 3
Dependencies: Joystick_skeleton_Pengineers mbed
Fork of ESE519_Lab6_part1_skeleton by
main.cpp
- Committer:
- csharer
- Date:
- 2016-10-20
- Revision:
- 0:0ebe6f55caee
- Child:
- 1:98c414bbfe8a
File content as of revision 0:0ebe6f55caee:
//ESE519 Lab6 Controller Part 1 (FULL IMPLIMENTATION) //Author: Carter Sharer //Date: 10/18/2016 //Sources: ESE350 Whack-A-Mole: https://developer.mbed.org/users/mlab4/code/ESE350-Whack-a-Mole/ //This is a simple working templete for sending and receving between two MRF24J40 Modules //Contains a communication protocol for sending a receiving #include "mbed.h" #include "MRF24J40.h" #include <string> #include "Joystick.h" #define SEND //Uncomment if you want to transmit data //#define RECEIVE //Uncomment if you want to receive data #define NONE 250 //============================ //== Pin Assignments == //============================ //Knobs #define POT1 p17 //Knob1 #define POT2 p18 //Knob2 #define POT3 p16 //Knob3 #define POT4 p15 //Knob4 //JoyStick #define POTV p19 //Vertial #define POTH p20 //Horizontal //MRF24J #define SDI p11 #define SDO p12 #define SCK p13 #define CS p7 #define RESET p8 //Button #define BUTTON1 p21 #define COMMUNICATION_FORMAT "Jstick_h: %0.0f Jstick_v: %0.0f Knob1 %0.2f Knob2 %0.2f Knob3 %0.2f Knob4 %0.2f Button: %d" //============================ //== Objects == //============================ //Knobs AnalogIn pot1(POT1); AnalogIn pot2(POT2); AnalogIn pot3(POT3); AnalogIn pot4(POT4); float knob1, knob2, knob3, knob4; //Joystick Joystick jstick(POTV, POTH); float jstick_h, jstick_v; //MRF24J40 PinName mosi(SDI); PinName miso(SDO); PinName sck(SCK); PinName cs(CS); PinName reset(RESET); // RF tranceiver MRF24J40 mrf(mosi, miso, sck, cs, reset); //Button DigitalIn Button(BUTTON1); bool button; // LEDs DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); // Timer Timer timer; // Serial port for showing RX data. Serial pc(USBTX, USBRX); // Send / receive buffers. // IMPORTANT: The MRF24J40 is intended as zigbee tranceiver; it tends // to reject data that doesn't have the right header. So the first // 8 bytes in txBuffer look like a valid header. The remaining 120 // bytes can be used for anything you like. char txBuffer[128]; char rxBuffer[128]; int rxLen; //***************** Do not change these methods (please) *****************// /** * Receive data from the MRF24J40. * * @param data A pointer to a char array to hold the data * @param maxLength The max amount of data to read. */ int rf_receive(char *data, uint8_t maxLength) { uint8_t len = mrf.Receive((uint8_t *)data, maxLength); uint8_t header[8]= {1, 8, 0, 0xA1, 0xB2, 0xC3, 0xD4, 0x00}; if(len > 10) { //Remove the header and footer of the message for(uint8_t i = 0; i < len-2; i++) { if(i<8) { //Make sure our header is valid first if(data[i] != header[i]) return 0; } else { data[i-8] = data[i]; } } //pc.printf("Received: %s length:%d\r\n", data, ((int)len)-10); } return ((int)len)-10; } /** * Send data to another MRF24J40. * * @param data The string to send * @param maxLength The length of the data to send. * If you are sending a null-terminated string you can pass strlen(data)+1 */ void rf_send(char *data, uint8_t len) { //We need to prepend the message with a valid ZigBee header uint8_t header[8]= {1, 8, 0, 0xA1, 0xB2, 0xC3, 0xD4, 0x00}; uint8_t *send_buf = (uint8_t *) malloc( sizeof(uint8_t) * (len+8) ); for(uint8_t i = 0; i < len+8; i++) { //prepend the 8-byte header send_buf[i] = (i<8) ? header[i] : data[i-8]; } //pc.printf("Sent: %s\r\n", send_buf+8); mrf.Send(send_buf, len+8); free(send_buf); } //***************** You can start coding here *****************// //Returns true if c is a letter, false otherwise bool isLetter(char c) { if(('a'<=c & c<='z') | ('A'<=c & c<='Z')) return true; return false; } //Returns true if c is a number, false otherwise bool isNumber(char c) { if('0'<=c & c<='9') return true; return false; } //Pulls data out of rxBuffer and updates global variables accordingly void communication_protocal(int len) { bool found_name = false; bool found_num = false; bool complete_name = false; bool complete_num = false; uint8_t name_start = NONE; uint8_t name_end = NONE; uint8_t num_start = NONE; uint8_t num_end = NONE; //Loop through all charaters in rxBuffer for(uint8_t i = 0; i <= rxLen; i++) { char c = rxBuffer[i]; //pc.printf("Indexed char '%c'\r\n", c); //Is is the start of a name? (Check if its a letter) if(isLetter(c) & name_start==NONE) { //if a num //If We havent found a name yet, this is start of a name if(found_name == false) { //pc.printf("found name start at: '%c'\r\n", c); name_start = i; found_name = true; } } //Is is a 'end of name' charater? Check for ' ', ':', '-' else if(((c == ' ') | (c == ':') | (c == '-')) & found_name & !complete_name) {// found end name character if(found_name) { complete_name = true; name_end = i; //pc.printf("found end of name at: '%c'\r\n", txBuffer[name_end]); } } //Is it a 'start of a number' charater? Check if its a number, or '-', or a '.' else if( (isNumber(c) | (c=='-') | (c=='.')) & complete_name & num_start==NONE) { if(found_num == false) { //pc.printf("found num start at: '%c'\r\n",c); num_start = i; found_num = true; } } //Is it a 'end of number' character? Check if its a ' ', ':', '-', or a letter else if( (((c==' ')|(c==':')|(c=='-')) | isLetter(c)) & found_num & complete_name) { if(found_num) { complete_num = true; num_end = i; //pc.printf("found end of num at: '%c' \r\n", txBuffer[num_end]); } } //If we have a complete name AND number value (ie. start and end of each != NONE) if(found_name & found_num & complete_name & complete_num) { //pc.printf("Found MATCH\r\n"); //Reset flags found_name = false; found_num = false; complete_name = false; complete_num = false; //Set name uint8_t nameLen = uint8_t((name_end-name_start) + 1); char * name[nameLen]; *name = &rxBuffer[name_start]; rxBuffer[name_end] = '\0'; //Set num uint8_t numLen = uint8_t((num_end-num_start) + 1); char * num[numLen]; *num = &rxBuffer[num_start]; rxBuffer[num_end] = '\0'; //Set variables if(strcmp(*name, "Jstick_h\0")==0) jstick_h = atof(*num); else if(strcmp(*name, "Jstick_v\0")==0) jstick_v = atof(*num); else if(strcmp(*name, "Knob1\0")==0) knob1 = atof(*num); else if(strcmp(*name, "Knob2\0")==0) knob2 = atof(*num); else if(strcmp(*name, "Knob3\0")==0) knob3 = atof(*num); else if(strcmp(*name, "Knob4\0")==0) knob4 = atof(*num); else if(strcmp(*name, "Button\0")==0) button = atof(*num); //Reset flags name_start = NONE; name_end = NONE; num_start = NONE; num_end = NONE; } } } int main (void) { //Set the Channel. 0 is default, 15 is max uint8_t channel = 2; mrf.SetChannel(channel); //Set Baud rate (9600-115200 is ideal) pc.baud(115200); pc.printf("\r\n Start! \r\n"); //Start Timer timer.start(); //Scale Joystick Values jstick.setScale(-50, 25); while(1) { //(1) Read Joystick Values, round to int8_t presision jstick_h = (int8_t)jstick.horizontal(); jstick_v = (int8_t)jstick.vertical(); //pc.printf("H: %d V:%d \r\n", jstick_h, jstick_v); //(2) Read Pot Values, Scale, and round to precision knob1 = (uint8_t)(pot1.read() * 100); //rounded to uint8_t knob2 = (pot2.read() * 100); knob3 = (pot3.read()); knob4 = (int)(pot4.read() * 100); //rounded to float //(3)Read Button Val, Add to buffer button = !Button.read(); //button is active low #ifdef RECEIVE //RECEIVE DATA: Try to receive some data rxLen = rf_receive(rxBuffer, 128); if(rxLen > 0) { //Toggle the Led led1 = led1^1; //(4) Process data with our protocal communication_protocal(rxLen); //Print values once we recieve and process data pc.printf(COMMUNICATION_FORMAT, jstick_h, jstick_v, knob1, knob2, knob3, knob4, button); pc.printf("\r\n"); }//main if #endif #ifdef SEND //SEND DATA: Send some data every 1/2 second if(timer.read_ms() >= 500) { //Reset the timer to 0 timer.reset(); // Toggle LED 2. led2 = led2^1; //(5) Add all values to buffer to be sent sprintf(txBuffer, COMMUNICATION_FORMAT, jstick_h, jstick_v, knob1, knob2, knob3, knob4, button); //(6) Send the buffer rf_send(txBuffer, strlen(txBuffer) + 1); pc.printf("%s\r\n", txBuffer); } #endif } //end loop }//end main