Railway Challenge / Mbed 2 deprecated challenge

Dependencies:   mbed millis

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers remoteControl.cpp Source File

remoteControl.cpp

00001 #include <mbed.h>
00002 #include "remoteControl.h"
00003 #include "definitions.h"
00004 
00005 Remote::Remote(SPI& remoteControl, DigitalOut& remoteControlCS) : _remoteControl(remoteControl), _remoteControlCS(remoteControlCS) {
00006     _remoteControl.format(8,0);    // FORMAT SPI AS 8-BIT DATA, SPI CLOCK MODE 0
00007     const long arduinoClock = 16000000;
00008     long spiFrequency = arduinoClock / 4;
00009     _remoteControl.frequency(spiFrequency); // SET SPI CLOCK FREQUENCY
00010     
00011     _remoteControlCS = 1;   // DISABLE SLAVE
00012     spiDelay = 600;    //DELAY BETWEEN SPI TRANSACTIONS (SO ARDUINO CAN KEEP UP WITH REQUESTS)
00013     
00014     commsGood = false;                 // Successful Comms Between Nucleo and Remote Control
00015     commsFailures = 0;                      // Number of consecutive remote comms failures
00016     errorIndex = 0;
00017     
00018 //    remoteSwitchStateTicker.attach(this, &Remote::getSwitchStates, 0.2);
00019     commsCheckTicker.attach(this, &Remote::commsCheck, 0.2);  // Run the commsCheck function every 0.1s with the commsCheckTicker. - &commsCheck = The address of the function to be attached and 0.1 = the interval
00020 }
00021 
00022 int Remote::sendData(int precursor, int data) {
00023     int response  = 0;
00024     
00025     _remoteControlCS = 0;          // ENABLE REMOTE SPI
00026 //    pc.printf("Enabled \r\n");
00027     _remoteControl.write(precursor);   // Prepare arduino to receive data
00028     wait_us(spiDelay);
00029     _remoteControl.write(data);          // SEND DATA
00030     wait_us(spiDelay);
00031     response = _remoteControl.write(255);
00032     wait_us(spiDelay);
00033     
00034     _remoteControlCS = 1;         // DISABLE REMOTE SPI
00035 //    pc.printf("Disabling\r\n");
00036 
00037     return response;
00038 }
00039 
00040 void Remote::commsCheck() {
00041     // Send a random number to the controller and expect its square in return for valid operation.
00042     
00043     // Random number between 2 and 15. Reply should be the squared, and within the 1 byte size limit of 255 for SPI comms.
00044     // Does not conflict with switch states as they use ASCII A, B C etc which are Decimal 65+
00045     int randomNumber = rand() % (15 - 2 + 1) + 2;  // rand()%(max-min + 1) + min inclusive of max and min
00046     int expectedResponse = randomNumber * randomNumber;
00047     int actualResponse = 0;
00048     
00049     actualResponse = sendData(1, randomNumber);
00050     
00051 //    pc.printf("Random Number: %d\r\n", randomNumber);
00052 //    pc.printf("Expected: %d\r\n", expectedResponse);
00053 //    pc.printf("Actual: %d\r\n", actualResponse);
00054     
00055     if (actualResponse == expectedResponse) {
00056         commsGood = true;
00057         commsFailures = 0;          // Reset consecutive failure count
00058     }
00059     else
00060     {
00061 //        pc.printf("Failed at: \r\n");
00062 //        pc.printf("Random Number: %d\r\n", randomNumber);
00063 //        pc.printf("Expected: %d\r\n", expectedResponse);
00064 //        pc.printf("Actual: %d\r\n", actualResponse);
00065         
00066         if (commsFailures++ > 3) {            // Increment consecutive failure count
00067             commsGood = false;              // Flag comms failure after 3 failures (> 0.3 seconds)
00068 //            pc.printf("Remote Comms Failure!\r\n");
00069         }
00070     }
00071 //    pc.printf("commsGood: %d\r\n", commsGood);
00072 }
00073 
00074 // CONVERT BYTE TO BITS
00075 /* 
00076 The received bytes from the remote control uses bitmapping.
00077 Each 0/1 bit represents the on/ off state of a switch.
00078 This function takes each bit and assigned it to a switch variable.
00079 */
00080 void Remote::ByteToBits(unsigned char character, bool *boolArray)
00081 {
00082     for (int i=0; i < 8; ++i) {
00083         boolArray[i] = (character & (1<<i)) != 0;
00084     }   
00085 }
00086 
00087 void Remote::getSwitchStates() {
00088     // GET THE SWITCH STATES FROM THE REMOTE CONTROL
00089 
00090     
00091     bool bitGroupA[8] = {1, 1, 1, 1, 1, 1, 1, 1};
00092     bool bitGroupB[8] = {1, 1, 1, 1, 1, 1, 1, 1};
00093         
00094     char slaveReceivedA, slaveReceivedB;  // BYTE RECEIVED FROM REMOTE CONTROL
00095     
00096     slaveReceivedA = sendData(3, 3);
00097     slaveReceivedB = sendData(4, 4);
00098     throttle = sendData(5, 5);
00099     braking = sendData(6, 6);
00100             
00101     ByteToBits(slaveReceivedA, bitGroupA);    // CONVERT GROUP A BYTE TO BITS
00102     ByteToBits(slaveReceivedB, bitGroupB);    // CONVERT GROUP B BYTE TO BITS
00103     
00104     // ASSIGN VARIABLES FROM BIT GROUPS
00105 
00106     start         = bitGroupA[0];
00107     forward       = bitGroupA[1];
00108     park          = bitGroupA[2];
00109     reverse       = bitGroupA[3];
00110     compressor    = bitGroupA[4];
00111     autoStop      = bitGroupA[5];
00112     regenBrake    = bitGroupA[6];
00113     regenThrottle = bitGroupA[7];
00114     
00115     whistle       = bitGroupB[0];
00116     innovation    = bitGroupB[1];
00117    
00118 //    pc.printf("Start: %d\n\r", start);
00119 //    pc.printf("Forward: %d\n\r", forward);
00120 //    pc.printf("Park: %d\n\r", park);
00121 //    pc.printf("Reverse: %d\n\r", reverse);
00122 //    pc.printf("Compressor: %d\n\r", compressor);
00123 //    pc.printf("AutoStop: %d\n\r", autoStop);
00124 //    pc.printf("Regen Brake: %d\n\r", regenBrake);
00125 //    pc.printf("Regen Throttle: %d\n\r", regenThrottle);
00126 //    pc.printf("Whistle: %d\n\r", whistle);
00127 //    pc.printf("Innovation: %d\n\r", innovation);
00128 //    pc.printf("Throttle: %d\n\r", throttle);
00129 //    pc.printf("Brake: %d\n\r", braking);
00130         
00131 }
00132         
00133 void Remote::setTime(int hr, int min, int sec, int day, int mon, int yr) {
00134     _remoteControlCS = 0;
00135     
00136     _remoteControl.write(7);
00137     wait_us(spiDelay);
00138     _remoteControl.write(hr);
00139     wait_us(spiDelay);
00140     _remoteControl.write(min);
00141     wait_us(spiDelay);
00142     _remoteControl.write(sec);
00143     wait_us(spiDelay);
00144     _remoteControl.write(day);
00145     wait_us(spiDelay);
00146     _remoteControl.write(mon);
00147     wait_us(spiDelay);
00148     _remoteControl.write(yr);
00149     wait_us(spiDelay);
00150     _remoteControl.write(255);
00151     
00152     _remoteControlCS = 1;   // DISABLE REMOTE SPI
00153 }
00154 
00155 void Remote::sendError(int error) {
00156 
00157     bool errorInBuffer = false;
00158     
00159     for (int index = 0; index < errorIndex; index++) {
00160         if (errorBuffer[index] == error) {
00161             errorInBuffer == true;
00162             break;
00163         }
00164     }
00165     
00166     if (errorInBuffer == false) {
00167         errorBuffer[errorIndex++] = error;
00168     }
00169     else {
00170         errorInBuffer = false;  // reset
00171     }
00172     
00173     sendData(8, errorBuffer[0]);
00174 
00175     for (int index = 0; index < errorIndex; index++) {
00176         errorBuffer[index] = errorBuffer[index + 1];
00177     }
00178     errorIndex--;
00179     
00180     wait_ms(100);
00181 }