Railway Challenge
/
challenge-2022Fork
Commented out energgy sotrage code to rever to old state
remoteControl.cpp@39:c36b75a3402e, 16 months ago (annotated)
- Committer:
- as96
- Date:
- Fri Jun 23 17:44:09 2023 +0000
- Revision:
- 39:c36b75a3402e
- Parent:
- 38:1c93a9501929
Energy Change
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rwcjoliver | 0:4788e1df7b55 | 1 | #include <mbed.h> |
rwcjoliver | 0:4788e1df7b55 | 2 | #include "remoteControl.h" |
rwcjoliver | 0:4788e1df7b55 | 3 | #include "definitions.h" |
rwcjoliver | 0:4788e1df7b55 | 4 | |
as96 | 38:1c93a9501929 | 5 | Remote::Remote(SPI& remoteControl, DigitalOut& remoteControlCS, SPI& lcdScreen, DigitalOut& lcdScreenCS) : _remoteControl(remoteControl), _remoteControlCS(remoteControlCS), _lcdScreen(lcdScreen), _lcdScreenCS(lcdScreenCS) { |
rwcjoliver | 0:4788e1df7b55 | 6 | _remoteControl.format(8,0); // FORMAT SPI AS 8-BIT DATA, SPI CLOCK MODE 0 |
as96 | 38:1c93a9501929 | 7 | _lcdScreen.format(8,0); |
rwcjoliver | 0:4788e1df7b55 | 8 | const long arduinoClock = 16000000; |
rwcjoliver | 0:4788e1df7b55 | 9 | long spiFrequency = arduinoClock / 4; |
rwcjoliver | 0:4788e1df7b55 | 10 | _remoteControl.frequency(spiFrequency); // SET SPI CLOCK FREQUENCY |
as96 | 38:1c93a9501929 | 11 | _lcdScreen.frequency(spiFrequency); |
rwcjoliver | 0:4788e1df7b55 | 12 | |
rwcjoliver | 0:4788e1df7b55 | 13 | _remoteControlCS = 1; // DISABLE SLAVE |
as96 | 38:1c93a9501929 | 14 | _lcdScreenCS = 1; // Disable Slave for LCD |
rwcjoliver | 0:4788e1df7b55 | 15 | spiDelay = 600; //DELAY BETWEEN SPI TRANSACTIONS (SO ARDUINO CAN KEEP UP WITH REQUESTS) |
rwcjoliver | 0:4788e1df7b55 | 16 | |
rwcjoliver | 0:4788e1df7b55 | 17 | commsGood = false; // Successful Comms Between Nucleo and Remote Control |
rwcjoliver | 0:4788e1df7b55 | 18 | commsFailures = 0; // Number of consecutive remote comms failures |
rwcjoliver | 0:4788e1df7b55 | 19 | errorIndex = 0; |
rwcjoliver | 0:4788e1df7b55 | 20 | |
rwcjoliver | 0:4788e1df7b55 | 21 | // remoteSwitchStateTicker.attach(this, &Remote::getSwitchStates, 0.2); |
rwcjoliver | 0:4788e1df7b55 | 22 | 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 |
rwcjoliver | 0:4788e1df7b55 | 23 | } |
rwcjoliver | 0:4788e1df7b55 | 24 | |
as96 | 36:5c61710813b3 | 25 | int Remote::sendData(int precursor, int data) |
as96 | 36:5c61710813b3 | 26 | { |
rwcjoliver | 0:4788e1df7b55 | 27 | int response = 0; |
rwcjoliver | 0:4788e1df7b55 | 28 | |
rwcjoliver | 0:4788e1df7b55 | 29 | _remoteControlCS = 0; // ENABLE REMOTE SPI |
rwcjoliver | 0:4788e1df7b55 | 30 | // pc.printf("Enabled \r\n"); |
rwcjoliver | 0:4788e1df7b55 | 31 | _remoteControl.write(precursor); // Prepare arduino to receive data |
rwcjoliver | 0:4788e1df7b55 | 32 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 33 | _remoteControl.write(data); // SEND DATA |
rwcjoliver | 0:4788e1df7b55 | 34 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 35 | response = _remoteControl.write(255); |
rwcjoliver | 0:4788e1df7b55 | 36 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 37 | |
rwcjoliver | 0:4788e1df7b55 | 38 | _remoteControlCS = 1; // DISABLE REMOTE SPI |
as96 | 38:1c93a9501929 | 39 | |
as96 | 38:1c93a9501929 | 40 | if(precursor == 10) |
as96 | 38:1c93a9501929 | 41 | { |
as96 | 38:1c93a9501929 | 42 | _lcdScreenCS = 0; |
as96 | 38:1c93a9501929 | 43 | _lcdScreen.write(data); |
as96 | 38:1c93a9501929 | 44 | |
as96 | 38:1c93a9501929 | 45 | wait_us(spiDelay); |
as96 | 38:1c93a9501929 | 46 | _lcdScreenCS = 1; |
as96 | 38:1c93a9501929 | 47 | } |
rwcjoliver | 0:4788e1df7b55 | 48 | // pc.printf("Disabling\r\n"); |
rwcjoliver | 0:4788e1df7b55 | 49 | |
rwcjoliver | 0:4788e1df7b55 | 50 | return response; |
rwcjoliver | 0:4788e1df7b55 | 51 | } |
rwcjoliver | 0:4788e1df7b55 | 52 | |
as96 | 36:5c61710813b3 | 53 | void Remote::commsCheck() |
as96 | 36:5c61710813b3 | 54 | { |
rwcjoliver | 0:4788e1df7b55 | 55 | // Send a random number to the controller and expect its square in return for valid operation. |
rwcjoliver | 0:4788e1df7b55 | 56 | |
rwcjoliver | 0:4788e1df7b55 | 57 | // Random number between 2 and 15. Reply should be the squared, and within the 1 byte size limit of 255 for SPI comms. |
rwcjoliver | 0:4788e1df7b55 | 58 | // Does not conflict with switch states as they use ASCII A, B C etc which are Decimal 65+ |
rwcjoliver | 0:4788e1df7b55 | 59 | int randomNumber = rand() % (15 - 2 + 1) + 2; // rand()%(max-min + 1) + min inclusive of max and min |
rwcjoliver | 0:4788e1df7b55 | 60 | int expectedResponse = randomNumber * randomNumber; |
rwcjoliver | 0:4788e1df7b55 | 61 | int actualResponse = 0; |
rwcjoliver | 0:4788e1df7b55 | 62 | |
rwcjoliver | 0:4788e1df7b55 | 63 | actualResponse = sendData(1, randomNumber); |
as96 | 36:5c61710813b3 | 64 | |
rwcjoliver | 0:4788e1df7b55 | 65 | |
as96 | 36:5c61710813b3 | 66 | if (actualResponse == expectedResponse) |
as96 | 36:5c61710813b3 | 67 | { |
as96 | 36:5c61710813b3 | 68 | |
rwcjoliver | 0:4788e1df7b55 | 69 | commsGood = true; |
rwcjoliver | 0:4788e1df7b55 | 70 | commsFailures = 0; // Reset consecutive failure count |
rwcjoliver | 0:4788e1df7b55 | 71 | } |
rwcjoliver | 0:4788e1df7b55 | 72 | else |
rwcjoliver | 0:4788e1df7b55 | 73 | { |
as96 | 36:5c61710813b3 | 74 | |
rwcjoliver | 0:4788e1df7b55 | 75 | |
as96 | 36:5c61710813b3 | 76 | if (commsFailures++ > 3) |
as96 | 36:5c61710813b3 | 77 | { // Increment consecutive failure count |
rwcjoliver | 0:4788e1df7b55 | 78 | commsGood = false; // Flag comms failure after 3 failures (> 0.3 seconds) |
as96 | 36:5c61710813b3 | 79 | |
rwcjoliver | 0:4788e1df7b55 | 80 | } |
rwcjoliver | 0:4788e1df7b55 | 81 | } |
as96 | 36:5c61710813b3 | 82 | |
rwcjoliver | 0:4788e1df7b55 | 83 | } |
rwcjoliver | 0:4788e1df7b55 | 84 | |
rwcjoliver | 0:4788e1df7b55 | 85 | // CONVERT BYTE TO BITS |
rwcjoliver | 0:4788e1df7b55 | 86 | /* |
rwcjoliver | 0:4788e1df7b55 | 87 | The received bytes from the remote control uses bitmapping. |
rwcjoliver | 0:4788e1df7b55 | 88 | Each 0/1 bit represents the on/ off state of a switch. |
rwcjoliver | 0:4788e1df7b55 | 89 | This function takes each bit and assigned it to a switch variable. |
rwcjoliver | 0:4788e1df7b55 | 90 | */ |
rwcjoliver | 0:4788e1df7b55 | 91 | void Remote::ByteToBits(unsigned char character, bool *boolArray) |
rwcjoliver | 0:4788e1df7b55 | 92 | { |
as96 | 36:5c61710813b3 | 93 | for (int i=0; i < 8; ++i) |
as96 | 36:5c61710813b3 | 94 | { |
rwcjoliver | 0:4788e1df7b55 | 95 | boolArray[i] = (character & (1<<i)) != 0; |
rwcjoliver | 0:4788e1df7b55 | 96 | } |
rwcjoliver | 0:4788e1df7b55 | 97 | } |
rwcjoliver | 0:4788e1df7b55 | 98 | |
as96 | 36:5c61710813b3 | 99 | void Remote::getSwitchStates() |
as96 | 36:5c61710813b3 | 100 | { |
rwcjoliver | 0:4788e1df7b55 | 101 | // GET THE SWITCH STATES FROM THE REMOTE CONTROL |
rwcjoliver | 0:4788e1df7b55 | 102 | |
rwcjoliver | 0:4788e1df7b55 | 103 | |
rwcjoliver | 0:4788e1df7b55 | 104 | bool bitGroupA[8] = {1, 1, 1, 1, 1, 1, 1, 1}; |
rwcjoliver | 0:4788e1df7b55 | 105 | bool bitGroupB[8] = {1, 1, 1, 1, 1, 1, 1, 1}; |
rwcjoliver | 0:4788e1df7b55 | 106 | |
rwcjoliver | 0:4788e1df7b55 | 107 | char slaveReceivedA, slaveReceivedB; // BYTE RECEIVED FROM REMOTE CONTROL |
rwcjoliver | 0:4788e1df7b55 | 108 | |
rwcjoliver | 0:4788e1df7b55 | 109 | slaveReceivedA = sendData(3, 3); |
rwcjoliver | 0:4788e1df7b55 | 110 | slaveReceivedB = sendData(4, 4); |
rwcjoliver | 0:4788e1df7b55 | 111 | throttle = sendData(5, 5); |
rwcjoliver | 0:4788e1df7b55 | 112 | braking = sendData(6, 6); |
rwcjoliver | 0:4788e1df7b55 | 113 | |
rwcjoliver | 0:4788e1df7b55 | 114 | ByteToBits(slaveReceivedA, bitGroupA); // CONVERT GROUP A BYTE TO BITS |
rwcjoliver | 0:4788e1df7b55 | 115 | ByteToBits(slaveReceivedB, bitGroupB); // CONVERT GROUP B BYTE TO BITS |
rwcjoliver | 0:4788e1df7b55 | 116 | |
rwcjoliver | 0:4788e1df7b55 | 117 | // ASSIGN VARIABLES FROM BIT GROUPS |
rwcjoliver | 0:4788e1df7b55 | 118 | |
rwcjoliver | 0:4788e1df7b55 | 119 | start = bitGroupA[0]; |
rwcjoliver | 0:4788e1df7b55 | 120 | forward = bitGroupA[1]; |
rwcjoliver | 0:4788e1df7b55 | 121 | park = bitGroupA[2]; |
rwcjoliver | 0:4788e1df7b55 | 122 | reverse = bitGroupA[3]; |
rwcjoliver | 0:4788e1df7b55 | 123 | compressor = bitGroupA[4]; |
rwcjoliver | 0:4788e1df7b55 | 124 | autoStop = bitGroupA[5]; |
rwcjoliver | 0:4788e1df7b55 | 125 | regenBrake = bitGroupA[6]; |
rwcjoliver | 0:4788e1df7b55 | 126 | regenThrottle = bitGroupA[7]; |
rwcjoliver | 0:4788e1df7b55 | 127 | |
rwcjoliver | 0:4788e1df7b55 | 128 | whistle = bitGroupB[0]; |
rwcjoliver | 0:4788e1df7b55 | 129 | innovation = bitGroupB[1]; |
rwcjoliver | 0:4788e1df7b55 | 130 | |
rwcjoliver | 0:4788e1df7b55 | 131 | |
rwcjoliver | 0:4788e1df7b55 | 132 | } |
rwcjoliver | 0:4788e1df7b55 | 133 | |
as96 | 36:5c61710813b3 | 134 | void Remote::setTime(int hr, int min, int sec, int day, int mon, int yr) |
as96 | 36:5c61710813b3 | 135 | { |
rwcjoliver | 0:4788e1df7b55 | 136 | _remoteControlCS = 0; |
rwcjoliver | 0:4788e1df7b55 | 137 | |
rwcjoliver | 0:4788e1df7b55 | 138 | _remoteControl.write(7); |
rwcjoliver | 0:4788e1df7b55 | 139 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 140 | _remoteControl.write(hr); |
rwcjoliver | 0:4788e1df7b55 | 141 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 142 | _remoteControl.write(min); |
rwcjoliver | 0:4788e1df7b55 | 143 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 144 | _remoteControl.write(sec); |
rwcjoliver | 0:4788e1df7b55 | 145 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 146 | _remoteControl.write(day); |
rwcjoliver | 0:4788e1df7b55 | 147 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 148 | _remoteControl.write(mon); |
rwcjoliver | 0:4788e1df7b55 | 149 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 150 | _remoteControl.write(yr); |
rwcjoliver | 0:4788e1df7b55 | 151 | wait_us(spiDelay); |
rwcjoliver | 0:4788e1df7b55 | 152 | _remoteControl.write(255); |
rwcjoliver | 0:4788e1df7b55 | 153 | |
rwcjoliver | 0:4788e1df7b55 | 154 | _remoteControlCS = 1; // DISABLE REMOTE SPI |
rwcjoliver | 0:4788e1df7b55 | 155 | } |
rwcjoliver | 0:4788e1df7b55 | 156 | |
as96 | 36:5c61710813b3 | 157 | void Remote::sendError(int error) |
as96 | 36:5c61710813b3 | 158 | { |
rwcjoliver | 0:4788e1df7b55 | 159 | |
rwcjoliver | 0:4788e1df7b55 | 160 | bool errorInBuffer = false; |
rwcjoliver | 0:4788e1df7b55 | 161 | |
as96 | 36:5c61710813b3 | 162 | for (int index = 0; index < errorIndex; index++) |
as96 | 36:5c61710813b3 | 163 | { |
as96 | 36:5c61710813b3 | 164 | if (errorBuffer[index] == error) |
as96 | 36:5c61710813b3 | 165 | { |
as96 | 36:5c61710813b3 | 166 | errorInBuffer = true; |
rwcjoliver | 0:4788e1df7b55 | 167 | break; |
rwcjoliver | 0:4788e1df7b55 | 168 | } |
rwcjoliver | 0:4788e1df7b55 | 169 | } |
rwcjoliver | 0:4788e1df7b55 | 170 | |
as96 | 36:5c61710813b3 | 171 | if (errorInBuffer == false) |
as96 | 36:5c61710813b3 | 172 | { |
rwcjoliver | 0:4788e1df7b55 | 173 | errorBuffer[errorIndex++] = error; |
rwcjoliver | 0:4788e1df7b55 | 174 | } |
as96 | 36:5c61710813b3 | 175 | else |
as96 | 36:5c61710813b3 | 176 | { |
rwcjoliver | 0:4788e1df7b55 | 177 | errorInBuffer = false; // reset |
rwcjoliver | 0:4788e1df7b55 | 178 | } |
rwcjoliver | 0:4788e1df7b55 | 179 | |
rwcjoliver | 0:4788e1df7b55 | 180 | sendData(8, errorBuffer[0]); |
rwcjoliver | 0:4788e1df7b55 | 181 | |
rwcjoliver | 0:4788e1df7b55 | 182 | for (int index = 0; index < errorIndex; index++) { |
rwcjoliver | 0:4788e1df7b55 | 183 | errorBuffer[index] = errorBuffer[index + 1]; |
rwcjoliver | 0:4788e1df7b55 | 184 | } |
rwcjoliver | 0:4788e1df7b55 | 185 | errorIndex--; |
rwcjoliver | 0:4788e1df7b55 | 186 | |
rwcjoliver | 0:4788e1df7b55 | 187 | wait_ms(100); |
rwcjoliver | 0:4788e1df7b55 | 188 | } |