Fork with cleaned up main and brakes class. Implementation or regen, friction and emergency stop now in brakes.cpp and called in main

Dependencies:   mbed millis

Committer:
cdevarakonda
Date:
Mon Jun 20 17:12:18 2022 +0000
Revision:
33:9198b292a8eb
Parent:
0:4788e1df7b55
Energyy Storage code updated, pins changed

Who changed what in which revision?

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