-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCANBUS.cpp
executable file
·267 lines (231 loc) · 12.8 KB
/
CANBUS.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
CANBUS Library, created by Seb Smith
*/
#include "WProgram.h"
#include "CANBUS.h"
#include <FlexCAN.h>
CAN_message_t CANBUS::encode(CAN_message_t msg, double inputData, int startBit, int bitLength, String byteOrder, String dataType, double Scale, double bias){
//////////////////////////////////////////////////////////////////////////////
//Step 1 Reverse Scale and bias
//////////////////////////////////////////////////////////////////////////////
inputData = (1/Scale) * (inputData - bias);
//Serial.print("After scale and bias: ");
//Serial.println(inputData);
//////////////////////////////////////////////////////////////////////////////
//Step 2 Account for signed values
//////////////////////////////////////////////////////////////////////////////
int maxTheoraticalValue = (pow(2,bitLength)-1); //Minus one to account for zero
//Serial.print("max theoretical value:");
//Serial.println(maxTheoraticalValue);
if(dataType == "SIGNED" || dataType == "signed"){
if(inputData < 0){inputData = inputData + (maxTheoraticalValue+1);} //Convert to signed value
//Serial.print("After being signed: ");
//Serial.println(inputData);
}
//////////////////////////////////////////////////////////////////////////////
//Step 3 Convert to string
//////////////////////////////////////////////////////////////////////////////
String DataBinaryString = toBinary((int)inputData, bitLength);
//Serial.print("DataBinaryString: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 4 - Byte order correction
//////////////////////////////////////////////////////////////////////////////
if(byteOrder == "LSB" || byteOrder == "lsb" || byteOrder == "intel" || byteOrder == "INTEL"){
DataBinaryString = reverseString(DataBinaryString);
}
//Serial.print("After byte order correction: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 5 - Calculate section of string to insert into
//////////////////////////////////////////////////////////////////////////////
int startbitcalc;
int endbitcalc;
if(byteOrder == "MSB" || byteOrder == "msb" || byteOrder == "motorola" || byteOrder == "MOTOROLA"){
//needs redoing
if(startBit < 8 && startBit > -1) {startbitcalc = (7 - startBit);}
if(startBit < 16 && startBit > 7) {startbitcalc = (15 - startBit) + 8;}
if(startBit < 24 && startBit > 15){startbitcalc = (23 - startBit) + 16;}
if(startBit < 32 && startBit > 23){startbitcalc = (31 - startBit) + 24;}
if(startBit < 40 && startBit > 31){startbitcalc = (39 - startBit) + 32;}
if(startBit < 48 && startBit > 39){startbitcalc = (47 - startBit) + 40;}
if(startBit < 56 && startBit > 47){startbitcalc = (55 - startBit) + 48;}
if(startBit < 64 && startBit > 55){startbitcalc = (63 - startBit) + 56;}
endbitcalc = ((startbitcalc)+bitLength);
} else {
startbitcalc = startBit;
endbitcalc = (startBit+bitLength);
}
//Serial.print("startbitcalc: ");
//Serial.println(startbitcalc);
//Serial.print("endbitcalc: ");
//Serial.println(endbitcalc);
//////////////////////////////////////////////////////////////////////////////
//Step 6 - Gets current data and make very long string
//////////////////////////////////////////////////////////////////////////////
String inputDataBinaryString;
for(int x=0; x<msg.len; x++){
String tempdata = toBinary(msg.buf[x], 8);
if(byteOrder == "LSB" || byteOrder == "lsb" || byteOrder == "intel" || byteOrder == "INTEL"){
tempdata = reverseString(tempdata);
}
inputDataBinaryString = inputDataBinaryString + tempdata; //Merge into mega long string
}
//Serial.print("Raw Binary Data input: ");
//Serial.println(inputDataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 7 - Split input data string into chunks for left and right and merge in encoded data
//////////////////////////////////////////////////////////////////////////////
String leftportion = "";
String rightportion = "";
if(startbitcalc > 0){ //Check if not at very start of string
leftportion = inputDataBinaryString.substring(0, startbitcalc);
}
if(endbitcalc < inputDataBinaryString.length()){ //Check if not all the way at the end
rightportion = inputDataBinaryString.substring(endbitcalc, inputDataBinaryString.length());
}
//Serial.print("leftportion: ");
//Serial.println(leftportion);
//Serial.print("rightportion: ");
//Serial.println(rightportion);
DataBinaryString = leftportion + DataBinaryString + rightportion; //Merge together
//Serial.print("After merge together: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 8 - convert bytes to decimal and return message
//////////////////////////////////////////////////////////////////////////////
char byte0[9];
char byte1[9];
char byte2[9];
char byte3[9];
char byte4[9];
char byte5[9];
char byte6[9];
char byte7[9];
if(byteOrder == "LSB" || byteOrder == "lsb" || byteOrder == "intel" || byteOrder == "INTEL"){
//need to swap each byte again for lsb
String byte0s = reverseString(DataBinaryString.substring(0,8));
String byte1s = reverseString(DataBinaryString.substring(8,16));
String byte2s = reverseString(DataBinaryString.substring(16,24));
String byte3s = reverseString(DataBinaryString.substring(24,32));
String byte4s = reverseString(DataBinaryString.substring(32,40));
String byte5s = reverseString(DataBinaryString.substring(40,48));
String byte6s = reverseString(DataBinaryString.substring(48,56));
String byte7s = reverseString(DataBinaryString.substring(56,64));
byte0s.toCharArray(byte0,9);
byte1s.toCharArray(byte1,9);
byte2s.toCharArray(byte2,9);
byte3s.toCharArray(byte3,9);
byte4s.toCharArray(byte4,9);
byte5s.toCharArray(byte5,9);
byte6s.toCharArray(byte6,9);
byte7s.toCharArray(byte7,9);
}else{
DataBinaryString.substring(0,8).toCharArray(byte0,9);
DataBinaryString.substring(9,16).toCharArray(byte1,9);
DataBinaryString.substring(16,24).toCharArray(byte2,9);
DataBinaryString.substring(24,32).toCharArray(byte3,9);
DataBinaryString.substring(32,40).toCharArray(byte4,9);
DataBinaryString.substring(40,48).toCharArray(byte5,9);
DataBinaryString.substring(48,56).toCharArray(byte6,9);
DataBinaryString.substring(56,64).toCharArray(byte7,9);
}
msg.buf[0] = strtol(byte0, NULL, 2);
msg.buf[1] = strtol(byte1, NULL, 2);
msg.buf[2] = strtol(byte2, NULL, 2);
msg.buf[3] = strtol(byte3, NULL, 2);
msg.buf[4] = strtol(byte4, NULL, 2);
msg.buf[5] = strtol(byte5, NULL, 2);
msg.buf[6] = strtol(byte6, NULL, 2);
msg.buf[7] = strtol(byte7, NULL, 2);
return msg;
}
double CANBUS::decode(CAN_message_t msg, int startBit, int bitLength, String byteOrder, String dataType, double Scale, double bias){
//used to be: rxBufD
//now: msg.buf
//used to be: lengthD
//now: msg.len
//////////////////////////////////////////////////////////////////////////////
//Step 1 - Gets all received data and converts to super long string
//////////////////////////////////////////////////////////////////////////////
String DataBinaryString;
for(int x=0; x<msg.len; x++){
String tempdata = toBinary(msg.buf[x], 8);
if(byteOrder == "LSB" || byteOrder == "lsb" || byteOrder == "intel" || byteOrder == "INTEL"){
tempdata = reverseString(tempdata); //For LSB byte order flip each byte around first
}
DataBinaryString = DataBinaryString + tempdata; //Merge into mega long string
}
//Serial.print("Raw Binary Data input: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 2 - Calculate section of string to select
//////////////////////////////////////////////////////////////////////////////
if(byteOrder == "MSB" || byteOrder == "msb" || byteOrder == "motorola" || byteOrder == "MOTOROLA"){
int startbitcalc = 0;
if(startBit < 8 && startBit > -1) {startbitcalc = (7 - startBit);}
if(startBit < 16 && startBit > 7) {startbitcalc = (15 - startBit) + 8;}
if(startBit < 24 && startBit > 15){startbitcalc = (23 - startBit) + 16;}
if(startBit < 32 && startBit > 23){startbitcalc = (31 - startBit) + 24;}
if(startBit < 40 && startBit > 31){startbitcalc = (39 - startBit) + 32;}
if(startBit < 48 && startBit > 39){startbitcalc = (47 - startBit) + 40;}
if(startBit < 56 && startBit > 47){startbitcalc = (55 - startBit) + 48;}
if(startBit < 64 && startBit > 55){startbitcalc = (63 - startBit) + 56;}
//Serial.print("startbitcalc: ");
//Serial.println(startbitcalc);
//Serial.print("endbit: ");
//Serial.println((startbitcalc)+bitLength);
DataBinaryString = DataBinaryString.substring(startbitcalc, ((startbitcalc)+bitLength));
} else {DataBinaryString = DataBinaryString.substring(startBit, (startBit+bitLength));}
//Serial.print("Extracted data portion: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 3 - Byte order correction
//////////////////////////////////////////////////////////////////////////////
if(byteOrder == "LSB" || byteOrder == "lsb" || byteOrder == "intel" || byteOrder == "INTEL"){
DataBinaryString = reverseString(DataBinaryString);
}
//Serial.print("After byte order correction: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 4 - Convert to integer
//////////////////////////////////////////////////////////////////////////////
int maxTheoraticalValue = (pow(2,(DataBinaryString.length()))-1); //Minus one to account for zero
//Serial.print("max theoretical value:");
//Serial.println(maxTheoraticalValue);
char tempholder[64]; //char array with max size of data
DataBinaryString.toCharArray(tempholder,64); //string to char array
int dataInteger = strtol(tempholder, NULL, 2); //Convert from binary (base 2) to decimal
//Serial.print("Raw integer: ");
//Serial.println(dataInteger);
//////////////////////////////////////////////////////////////////////////////
//Step 4 - Account for signed values
//////////////////////////////////////////////////////////////////////////////
if(dataType == "SIGNED" || dataType == "signed"){
if(dataInteger > (maxTheoraticalValue/2)){dataInteger = dataInteger - (maxTheoraticalValue+1);} //Convert to signed value
}
//Serial.print("After being signed: ");
//Serial.println(DataBinaryString);
//////////////////////////////////////////////////////////////////////////////
//Step 5 - Scale and bias
//////////////////////////////////////////////////////////////////////////////
//Referenced from: https://www.csselectronics.com/screen/page/can-dbc-file-database-intro/language/en
double returnData = bias + (Scale*dataInteger);
return(returnData);
}
String CANBUS::reverseString(String inputString){
//Simply reverses string (used for MSB > LSB conversion)
String returnString;
for(int x=inputString.length(); x>0; x--){returnString = returnString + inputString.substring(x, (x-1));}
return(returnString);
}
String CANBUS::toBinary(int input1, int length1){
//Function that returns a string of the input binary,and pads out with zeros to match the length requested
String tempString = String(input1, BIN);
if(tempString.length() == length1){return tempString;} else {
int paddingToAdd = length1-tempString.length();
String zeros = "";
for (int i = 1; i <= paddingToAdd; i++) {zeros = zeros + "0";}
tempString = zeros + tempString;
}
}