Formula Student Electronics & Software
The code for the embedded software
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1#include <Adafruit_MCP3008.h>
2#include <FlexCAN_T4.h>
3#include <Wire.h>
4#include <elapsedMillis.h>
5#include <iostream>
6
7FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
8
9Adafruit_MCP3008 ADCs[8];
10
11#define Reference 2.5
12#define ERROR_TIME 900
13
14#define N_ADCs 8
15#define N_ADC_CHANNELS 8
16
17// #define BMS_CAN_PERIOD 250
18// #define BROADCAST_PERIOD 250
19#define BROADCAST_ID 0x301
20
21elapsedMicros tempErrorTimer;
22
24
25CAN_message_t BMSInfoMsg;
26CAN_message_t BMSErrorFlag;
27CAN_message_t tempBroadcast;
28CAN_message_t msg_1;
29
30// elapsedMillis timeSinceLastBroadcast = 0;
31// elapsedMillis timeSinceLastBMSMessage = 0;
32
35int count = 0;
36
37float read = 0;
38double voltage = 0;
39double voltage1 = 0;
40double voltage2 = 0;
41double voltage3 = 0;
42double voltage4 = 0;
43double temperature = 0.0;
44float maxTemp = 0.0;
45float minTemp = 60.0;
46float tempSum = 0.0;
47float avgTemp = 0.0;
48
49volatile bool BMSErr = 0;
50volatile bool tempErr = 0;
51
52int ADCRaw[8][8] = {
53 {0, 0, 0, 0, 0, 0, 0, 0},
54 {0, 0, 0, 0, 0, 0, 0, 0},
55 {0, 0, 0, 0, 0, 0, 0, 0},
56 {0, 0, 0, 0, 0, 0, 0, 0},
57 {0, 0, 0, 0, 0, 0, 0, 0},
58 {0, 0, 0, 0, 0, 0, 0, 0},
59 {0, 0, 0, 0, 0, 0, 0, 0},
60 {0, 0, 0, 0, 0, 0, 0, 0}};
61
62float Temps[8][8] = {
63 {0, 0, 0, 0, 0, 0, 0, 0},
64 {0, 0, 0, 0, 0, 0, 0, 0},
65 {0, 0, 0, 0, 0, 0, 0, 0},
66 {0, 0, 0, 0, 0, 0, 0, 0},
67 {0, 0, 0, 0, 0, 0, 0, 0},
68 {0, 0, 0, 0, 0, 0, 0, 0},
69 {0, 0, 0, 0, 0, 0, 0, 0},
70 {0, 0, 0, 0, 0, 0, 0, 0}};
71
72double ADCconversion(int raw) {
73 voltage = (raw * Reference) / 1024.0;
77
78 temperature = 2875.88397 - 5512.867802 * voltage + 4082.002758 * voltage2 - 1358.200746 * voltage3 + 168.841073 * voltage4;
79 return temperature;
80}
81
82// write a function to read all the ADC values
84 for (int adc = 0; adc < N_ADCs; adc++) {
85 for (int channel = 0; channel < N_ADC_CHANNELS; channel++) {
86 if (adc == 7 && channel > 3)
87 continue;
88 int tempID = adc * 8 + channel;
89 switch (tempID) {
90 case 20:
91 case 29:
92 case 27:
93 ADCRaw[adc][channel] = ADCRaw[1][1];
94 break;
95 default:
96 ADCRaw[adc][channel] = ADCs[adc].readADC(channel);
97 break;
98 }
99 Temps[adc][channel] = ADCconversion(ADCRaw[adc][channel]);
100
101 minTemp = min(minTemp, Temps[adc][channel]);
102 maxTemp = max(maxTemp, Temps[adc][channel]);
103 tempSum += Temps[adc][channel];
104 }
105 }
106 avgTemp = tempSum / (N_ADCs * N_ADC_CHANNELS - 4); // Only 60 ADC Channels are usable
107}
108
110 tempBroadcast.id = BROADCAST_ID + broadcastIndex; // para decidir
112 for (int i = 0; i < N_ADCs; i++)
113 tempBroadcast.buf[i] = (uint8_t)ADCRaw[broadcastIndex][i];
114
115 can1.write(tempBroadcast);
117}
118
119void CAN_msg() {
120 msg_1.id = 0x301; // para decidir
121 msg_1.len = 8;
122
123 msg_1.buf[0] = 0;
124 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[0][0]);
125 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[0][1]);
126 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[0][2]);
127 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[0][3]);
128 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[0][4]);
129 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[0][5]);
130 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[0][6]);
131 can1.write(msg_1);
132
133 msg_1.buf[0] = 1;
134 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[0][7]);
135 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[1][0]);
136 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[1][1]);
137 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[1][2]);
138 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[1][3]);
139 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[1][4]);
140 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[1][5]);
141 can1.write(msg_1);
142
143 msg_1.buf[0] = 2;
144 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[1][6]);
145 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[1][7]);
146 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[2][0]);
147 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[2][1]);
148 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[2][2]);
149 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[2][3]);
150 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[2][4]);
151 can1.write(msg_1);
152
153 msg_1.buf[0] = 3;
154 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[2][5]);
155 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[2][6]);
156 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[2][7]);
157 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[3][0]);
158 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[3][1]);
159 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[3][2]);
160 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[3][3]);
161 can1.write(msg_1);
162
163 msg_1.buf[0] = 4;
164 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[3][4]);
165 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[3][5]);
166 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[3][6]);
167 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[3][7]);
168 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[4][0]);
169 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[4][1]);
170 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[4][2]);
171 can1.write(msg_1);
172
173 msg_1.buf[0] = 5;
174 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[4][3]);
175 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[4][4]);
176 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[4][5]);
177 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[4][6]);
178 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[4][7]);
179 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[5][0]);
180 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[5][1]);
181 can1.write(msg_1);
182
183 msg_1.buf[0] = 6;
184 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[5][2]);
185 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[5][3]);
186 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[5][4]);
187 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[5][5]);
188 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[5][6]);
189 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[5][7]);
190 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[6][0]);
191 can1.write(msg_1);
192
193 msg_1.buf[0] = 7;
194 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[6][1]);
195 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[6][2]);
196 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[6][3]);
197 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[6][4]);
198 msg_1.buf[5] = (uint8_t)ADCconversion(ADCRaw[6][5]);
199 msg_1.buf[6] = (uint8_t)ADCconversion(ADCRaw[6][6]);
200 msg_1.buf[7] = (uint8_t)ADCconversion(ADCRaw[6][7]);
201 can1.write(msg_1);
202
203 msg_1.buf[0] = 8;
204 msg_1.buf[1] = (uint8_t)ADCconversion(ADCRaw[7][0]);
205 msg_1.buf[2] = (uint8_t)ADCconversion(ADCRaw[7][1]);
206 msg_1.buf[3] = (uint8_t)ADCconversion(ADCRaw[7][2]);
207 msg_1.buf[4] = (uint8_t)ADCconversion(ADCRaw[7][3]);
208 can1.write(msg_1);
209}
210
212 if (minTemp < 0 or maxTemp > 58){
213 if(flagErrorTimerOn == 0){
214 tempErrorTimer = 0;
216 }
217 if (tempErrorTimer >= 700){
218 tempErr = 1;
219 }
220 }
221 else
222 tempErr = 0;
223
224 BMSInfoMsg.id = 0x1839F380;
225 BMSInfoMsg.flags.extended = 1;
226 BMSInfoMsg.len = 8;
227 BMSInfoMsg.buf[0] = 0x00;
228 BMSInfoMsg.buf[1] = minTemp; // 60 is maximum allowed temperature before
229 BMSInfoMsg.buf[2] = maxTemp; // triggering an error on the BMS
230 BMSInfoMsg.buf[3] = avgTemp;
231 BMSInfoMsg.buf[4] = 0x01;
232 BMSInfoMsg.buf[5] = 0x01;
233 BMSInfoMsg.buf[6] = 0x00;
234 BMSInfoMsg.buf[7] = BMSInfoMsg.buf[1] + BMSInfoMsg.buf[2] + BMSInfoMsg.buf[3] + BMSInfoMsg.buf[4] + BMSInfoMsg.buf[5] + BMSInfoMsg.buf[6] + 0x39 + 0x08;
235 can1.write(BMSInfoMsg);
236
237 BMSErrorFlag.id = 0x306;
238 BMSErrorFlag.flags.extended = 1;
239 BMSErrorFlag.len = 1;
240 BMSErrorFlag.buf[0] = tempErr;
241 can1.write(BMSErrorFlag);
242}
243
244void canbusSniffer(const CAN_message_t& msg) {
245 if (msg.id == 0x300)
247
248 if (msg.id == 0x270) {
249 BMSErr = msg.buf[0]; // atualiza flag erro BMS
250 }
251}
252
253void setup() {
254 // try to connect to the serial monitor
255 Serial.begin(9600);
256
257 if (Serial)
258 Serial.println("Serial monitor connected");
259
260 can1.begin();
261 can1.setBaudRate(125000);
262
263 can1.enableFIFO();
264 can1.enableFIFOInterrupt();
265 can1.setFIFOFilter(REJECT_ALL);
266 (void)can1.setFIFOFilter(0, 0x111, STD);
267 can1.setFIFOFilter(0, 0x300, STD);
268 //can1.setFIFOFilter(1, 0x270, STD);
269 can1.setFIFOFilter(2, 0x306, STD);
270 can1.onReceive(canbusSniffer);
271
272 (void)ADCs[0].begin(13, 11, 12, 18);
273 (void)ADCs[1].begin(13, 11, 12, 19);
274 (void)ADCs[2].begin(13, 11, 12, 20);
275 (void)ADCs[3].begin(13, 11, 12, 21);
276 (void)ADCs[4].begin(13, 11, 12, 4);
277 (void)ADCs[5].begin(13, 11, 12, 5);
278 (void)ADCs[6].begin(13, 11, 12, 6);
279 (void)ADCs[7].begin(13, 11, 12, 7);
280}
281
282void printTemp() {
283 for (int i = 0; i < 8; i++) {
284 for (int j = 0; j < 8; j++) {
285 Serial.printf("ADC %d raw data: %d temp: %f\n", (i * 8) + j, ADCRaw[i][j], ADCconversion(ADCRaw[i][j]));
286 }
287 }
288 Serial.printf("BMS Error: %d\n", BMSErr);
289 Serial.printf("Temp Error: %d\n", tempErr);
290}
291
292void loop() {
293 // reset measurement
294 tempSum = 0;
295 maxTemp = 0;
296 minTemp = 999;;
297
299 // broadcastRawData();
300 CAN_msg();
302 if (Serial)
303 printTemp();
304
305 delay(50);
306}
void setup()
Definition main.cpp:10
void loop()
AMI main loop: Button gets picked and lights up the corresponding LED LAST BUTTON CHECKED WINS.
Definition main.cpp:23
int voltage
Definition main.cpp:60
void canbusSniffer(const CAN_message_t &msg)
Definition main.cpp:139
FlexCAN_T4< CAN1, RX_SIZE_256, TX_SIZE_16 > can1
Definition main.cpp:87
volatile bool BMSErr
Definition main.cpp:49
bool flagErrorTimerOn
Definition main.cpp:23
double ADCconversion(int raw)
Definition main.cpp:72
float Temps[8][8]
Definition main.cpp:62
double voltage3
Definition main.cpp:41
CAN_message_t BMSErrorFlag
Definition main.cpp:26
float maxTemp
Definition main.cpp:44
float read
Definition main.cpp:37
int ADCRaw[8][8]
Definition main.cpp:52
CAN_message_t BMSInfoMsg
Definition main.cpp:25
float minTemp
Definition main.cpp:45
CAN_message_t msg_1
Definition main.cpp:28
float avgTemp
Definition main.cpp:47
void CAN_msg()
Definition main.cpp:119
int broadcastIndex
Definition main.cpp:33
void readRawADCData()
Definition main.cpp:83
float tempSum
Definition main.cpp:46
double voltage1
Definition main.cpp:39
int broadcastEnabled
Definition main.cpp:34
CAN_message_t tempBroadcast
Definition main.cpp:27
#define N_ADC_CHANNELS
Definition main.cpp:15
#define Reference
Definition main.cpp:11
double temperature
Definition main.cpp:43
void broadcastRawData()
Definition main.cpp:109
#define N_ADCs
Definition main.cpp:14
#define BROADCAST_ID
Definition main.cpp:19
Adafruit_MCP3008 ADCs[8]
Definition main.cpp:9
volatile bool tempErr
Definition main.cpp:50
int count
Definition main.cpp:35
void printTemp()
Definition main.cpp:282
void sendTempsToBMS()
Definition main.cpp:211
elapsedMicros tempErrorTimer
Definition main.cpp:21
double voltage4
Definition main.cpp:42
double voltage2
Definition main.cpp:40
CAN_message_t msg