Skip to content

Commit b735d78

Browse files
authoredJan 30, 2025··
Update ESP32_RET_SD.ino
Removed SoftAP when in log to SD mode and CAN log filenames now start at 1.
1 parent 3bbbb46 commit b735d78

File tree

1 file changed

+114
-81
lines changed

1 file changed

+114
-81
lines changed
 

‎ESP32_RET_SD.ino

+114-81
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
// ESP32_RET_SD
1+
// ESP32_RET_SD (internally known as ESP32_RET_SD_v1)
22
// ESP32 Reverse Engineering Tool with SD CAN bus datalogger for SavvyCAN
33
// Based on Collin Kidder (https://github.com/collin80) fantastic A0RET (https://github.com/collin80/A0RET)
4-
// Updated by frank @ motorvate Jan 1/2024 to add standalone recording of all CAN data to the SD card in SavvyCAN format
4+
// Updated by frank @ motorvate Feb 1/2025
5+
6+
// MotorvateDIY CAN LOGGER v1.0 PCB average current draw: Wifi: ~80mA @ 12v or 1W, with SD card: ~90ma @ 12v, or 1.1W
57

68
// Main Goal: Easy to use, Plug and Play CAN bus datalogging
79
// If an SD card *IS* detected at boot up, all CAN bus data is recorded to the SD card, in SavvyCAN CSV format for offline processing
8-
// If an SD card *IS NOT* detected, a WIFI access point is created for SavvyCAN to connect to and receive or send CAN frames
10+
// If an SD card *IS NOT* detected at boot up, a WIFI access point is created for SavvyCAN to connect to and receive or send CAN frames
911

10-
// compatable with Arduino core 2.0.x and 3.0.x
12+
// compatable with Arduino core 2.0.x and 3.1.x
1113
// Now compiles using default 1.2MB APP partition
1214

1315
// With a focus on "easy of use", an offline mode (CAN to SD) has been added to the SavvyCAN mode (CAN to Wifi)
@@ -17,18 +19,17 @@
1719
// Removed: Bluetooth
1820
// Removed: Digital and Analog I/O
1921

20-
// Added: saves all CAN data to SD card in SavvyCAN CSV format just by plugging into the OBD port for offline processing/reverse engineering
22+
// Added: Saving all CAN data to SD card in SavvyCAN CSV format just by plugging into the OBD port for offline processing/reverse engineering
2123
// Added: when saving to SD card, the ESP32 builtin LED is toggled every 250 (CAN_RX_LED_TOGGLE) CAN frames (set in config.h)
2224
// Added: getting timestamp as soon as possible, see gvret_comm.cpp line 558 and esp32_can_builtin.cpp line 398
2325

2426
// Instructions for use:
2527
// in config.h:
26-
// set SD card pins on lines 43-46. Uses VSPI default pins of: SCK 18, MISO 19, MOSI 23, CS 5
27-
// set CAN Tx/Rx pins on lines 50-51. Defaults to CAN_TX 17, CAN_RX 16
28-
// set CAN0 speed on line 54. Default speed is 500,000 bits/sec
29-
// set SSID and password on lines 57-58. Default SSID: ESP32_RET_SD, password motorvate
28+
// set SD card pins on lines 43-46
29+
// set CAN Tx/Rx pins on lines 50-51
30+
// set SSID and password on lines 54-55
3031
// Compile and upload to ESP32!
31-
// full video instructions at youtube.com/motorvateDIY
32+
// full video instructions at YouTube.com/motorvateDIY
3233

3334
/*
3435
A0RET.ino
@@ -100,9 +101,9 @@ Preferences nvPrefs;
100101

101102
WiFiManager wifiManager;
102103

103-
GVRET_Comm_Handler serialGVRET; // gvret protocol over the serial to USB connection
104-
GVRET_Comm_Handler wifiGVRET; // GVRET over the wifi telnet port
105-
CANManager canManager; // keeps track of bus load and abstracts away some details of how things are done
104+
GVRET_Comm_Handler serialGVRET; // gvret protocol over the serial to USB connection
105+
GVRET_Comm_Handler wifiGVRET; // GVRET over the wifi telnet port
106+
CANManager canManager; // keeps track of bus load and abstracts away some details of how things are done
106107

107108
SerialConsole console;
108109

@@ -115,14 +116,15 @@ QueueHandle_t SD_Queue;
115116
// initializes all the system EEPROM values. Chances are this should be broken out a bit but
116117
// there is only one checksum check for all of them so it's simple to do it all here.
117118
// NOTE: IF PREFS ERROR, USE ? AND SET ONE ITEM. This writes the SSID< WPA2KEY and ELM327-BT to flash
118-
void loadSettings() {
119-
settings.CAN0Speed = CAN_SPEED_500K;
119+
void loadSettings()
120+
{
121+
settings.CAN0Speed = 500000;
120122
settings.CAN0_Enabled = true;
121123
settings.CAN0ListenOnly = false;
122124
settings.useBinarySerialComm = false;
123-
settings.logLevel = 1; // info
124-
settings.wifiMode = 2; // Wifi defaults to creating an AP
125-
settings.systemType = 0; // ESP32 with single CAN bus
125+
settings.logLevel = 1; // info
126+
settings.wifiMode = 2; // Wifi defaults to creating an AP
127+
settings.systemType = 0; // ESP32 with single CAN bus
126128
settings.CAN1Speed = 500000;
127129
// below needs strcpy to copy the short string into the larger string 32/64
128130
strcpy(settings.SSID, SSID_NAME);
@@ -139,49 +141,60 @@ void loadSettings() {
139141
SysSettings.sdToggle = false;
140142
SysSettings.txToggle = false;
141143
SysSettings.rxToggle = true;
142-
SysSettings.numBuses = 1; // Currently we support CAN0
144+
SysSettings.numBuses = 1; // Currently we support CAN0
143145
SysSettings.isWifiActive = false;
144146
SysSettings.isWifiConnected = false;
145147
}
146148

147149
uint32_t chipId = 0;
148150

149-
String getDefaultMacAddress() {
151+
String getDefaultMacAddress()
152+
{
150153

151154
String mac = "";
152155

153-
unsigned char mac_base[6] = { 0 };
156+
unsigned char mac_base[6] = {0};
154157

155-
if (esp_efuse_mac_get_default(mac_base) == ESP_OK) {
156-
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
158+
if (esp_efuse_mac_get_default(mac_base) == ESP_OK)
159+
{
160+
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
157161
sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]);
158162
mac = buffer;
159163
}
160164

161165
return mac;
162166
}
163167

164-
String getInterfaceMacAddress(esp_mac_type_t interface) {
168+
String getInterfaceMacAddress(esp_mac_type_t interface)
169+
{
165170

166171
String mac = "";
167172

168-
unsigned char mac_base[6] = { 0 };
173+
unsigned char mac_base[6] = {0};
169174

170-
if (esp_read_mac(mac_base, interface) == ESP_OK) {
171-
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
175+
if (esp_read_mac(mac_base, interface) == ESP_OK)
176+
{
177+
char buffer[18]; // 6*2 characters for hex + 5 characters for colons + 1 character for null terminator
172178
sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]);
173179
mac = buffer;
174180
}
175181

176182
return mac;
177183
}
178184

179-
void setup() {
185+
void setup()
186+
{
187+
// allow supply voltage to stabalize
188+
// delay(250);
180189

181190
Serial.begin(115200);
182191

192+
// allow serial to setup and to prevent SD card header being sent to SD card on noisey power up
193+
// delay(250);
194+
183195
// display ESP32 details
184-
for (int i = 0; i < 17; i = i + 8) {
196+
for (int i = 0; i < 17; i = i + 8)
197+
{
185198
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
186199
}
187200

@@ -209,43 +222,55 @@ void setup() {
209222
spi.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
210223

211224
// set SPI clock speed to 30 MHz
212-
if (!SD.begin(SD_CS, spi, 30000000)) {
225+
if (!SD.begin(SD_CS, spi, 30000000))
226+
{
213227
Serial.print("\nSD card mount failed, ");
214228
}
215229

216230
uint8_t cardType = SD.cardType();
217231

218-
if (cardType == CARD_NONE) {
232+
if (cardType == CARD_NONE)
233+
{
219234
Serial.println("no SD card found");
220235
SD_card_present = false;
221-
} else {
236+
}
237+
else
238+
{
222239
SD_card_present = true;
223240

224241
// SD card Queue creation only if SD card detected
225242
SD_Queue = xQueueCreate(20, sizeof(SD_buffer));
226-
if (SD_Queue == NULL) {
243+
if (SD_Queue == NULL)
244+
{
227245
Serial.println("Error Creating the SD Queue");
228246
}
229247

230248
// create task to read xQueue and write to SD card
231249
xTaskCreatePinnedToCore(
232-
TaskSDWrite, // task function to call
233-
"SD Write", // name of task for optional eports
234-
2048, // Stack depth/size in bytes
235-
NULL, // pvParameters
236-
2, // Priority 1, same as setup() and loop(), now priority of 2
237-
&xSDWrite, // task handle
238-
// NULL, // no task handle
239-
1); // core to use for this task
250+
TaskSDWrite, // task function to call
251+
"SD Write", // name of task for optional eports
252+
2048, // Stack depth/size in bytes
253+
NULL, // pvParameters
254+
2, // Priority 1, same as setup() and loop(), now priority of 2
255+
&xSDWrite, // task handle
256+
// NULL, // no task handle
257+
1); // core to use for this task
240258

241259
Serial.print("SD card type: ");
242-
if (cardType == CARD_MMC) {
260+
if (cardType == CARD_MMC)
261+
{
243262
Serial.println("MMC");
244-
} else if (cardType == CARD_SD) {
263+
}
264+
else if (cardType == CARD_SD)
265+
{
245266
Serial.println("SDSC");
246-
} else if (cardType == CARD_SDHC) {
267+
}
268+
else if (cardType == CARD_SDHC)
269+
{
247270
Serial.println("SDHC");
248-
} else {
271+
}
272+
else
273+
{
249274
Serial.println("UNKNOWN");
250275
}
251276

@@ -254,9 +279,10 @@ void setup() {
254279
Serial.printf("SD Card Size: %llu MB\n", SD.cardSize() / (1024 * 1024));
255280
Serial.printf("Available space: %llu MB\n", (SD.totalBytes() - SD.usedBytes()) / (1024 * 1024));
256281

257-
// create a unique LogFile filename
258-
int fn = 0;
259-
do {
282+
// create a unique LogFile filename, start at 1
283+
int fn = 1;
284+
do
285+
{
260286
sprintf(LogFileName, "/CAN_LOG_%d.csv", fn++);
261287
} while (SD.exists(LogFileName));
262288
LogFile = SD.open(LogFileName, FILE_APPEND);
@@ -267,36 +293,32 @@ void setup() {
267293

268294
Serial.printf("CAN log filename: %s\n", LogFileName);
269295

270-
} // end SD_card_present
296+
} // end SD_card_present
271297

272298
// sets CAN speed, LED pins, WIFI, SSID, etc
273299
loadSettings();
274300

275301
// starts CAN
276302
canManager.setup();
277303

278-
279-
if (SD_card_present) {
280-
Serial.println("*** Recording CAN bus to SD card ***");
281-
} else {
282-
Serial.println("*** Ready for SavvyCAN Network (GVRET) connection ***");
283-
}
284-
304+
// setup wifi
285305
SysSettings.isWifiConnected = false;
286306

287-
// allow CAN bus to start up before starting wifi
288-
delay(250);
289-
290-
// setup wifi
291-
wifiManager.setup();
307+
if (!SD_card_present)
308+
{
309+
// allow CAN bus to start up before starting wifi
310+
delay(250);
311+
wifiManager.setup();
312+
}
292313
}
293314

294315
/*
295316
Send a fake frame out USB and maybe to file to show where the mark was triggered at. The fake frame has bits 31 through 3
296317
set which can never happen in reality since frames are either 11 or 29 bit IDs. So, this is a sign that it is a mark frame
297318
and not a real frame. The bottom three bits specify which mark triggered.
298319
*/
299-
void sendMarkTriggered(int which) {
320+
void sendMarkTriggered(int which)
321+
{
300322
CAN_FRAME frame;
301323
frame.id = 0xFFFFFFF8ull + which;
302324
frame.extended = true;
@@ -317,7 +339,8 @@ Any bytes between checksum and 0xF1 are thrown away
317339
Yes, this should probably have been done more neatly but this way is likely to be the
318340
fastest and safest with limited function calls
319341
*/
320-
void loop() {
342+
void loop()
343+
{
321344
// uint32_t temp32;
322345
bool isConnected = false;
323346
int serialCnt;
@@ -326,17 +349,24 @@ void loop() {
326349
/*if (Serial)*/ isConnected = true;
327350

328351
canManager.loop();
329-
wifiManager.loop();
352+
353+
// only start softAP is SD card is not present
354+
if (!SD_card_present)
355+
{
356+
wifiManager.loop();
357+
}
330358

331359
size_t wifiLength = wifiGVRET.numAvailableBytes();
332360
size_t serialLength = serialGVRET.numAvailableBytes();
333361

334362
size_t maxLength = (wifiLength > serialLength) ? wifiLength : serialLength;
335363

336364
// If the max time has passed or the buffer is almost filled then send buffered data out
337-
if ((micros() - lastFlushMicros > SER_BUFF_FLUSH_INTERVAL) || (maxLength > (WIFI_BUFF_SIZE - 40))) {
365+
if ((micros() - lastFlushMicros > SER_BUFF_FLUSH_INTERVAL) || (maxLength > (WIFI_BUFF_SIZE - 40)))
366+
{
338367
lastFlushMicros = micros();
339-
if (serialLength > 0) {
368+
if (serialLength > 0)
369+
{
340370

341371
if (SD_card_present)
342372
// saves CAN frames to uSD card in SavvyCAN CSV format
@@ -346,45 +376,48 @@ void loop() {
346376
// copy serialGVRET.getBufferedBytes() > transmitBuffer to SD_buffer
347377
memcpy(&SD_buffer, serialGVRET.getBufferedBytes(), serialLength);
348378

349-
if (xQueueSend(SD_Queue, (void *)&SD_buffer, 10 * portTICK_PERIOD_MS) != pdPASS) {
379+
if (xQueueSend(SD_Queue, (void *)&SD_buffer, 10 * portTICK_PERIOD_MS) != pdPASS)
380+
{
350381
Serial.println("xQueueSend to SD_Queue 10ms timeout error");
351382
}
352383

353-
// flush SD card every 20ms
354384
LogFile.flush();
355385

356386
serialGVRET.clearBufferedBytes();
357-
// only toggle Rx LED when writing to SD card, regardless of CAN activity
358-
359-
// toggles every 20ms x 100 = 2 seconds
360-
// toggleRXLED();
361-
// below works, but blinks too fast
362-
// toggleSD_LED();
363-
} else {
387+
}
388+
else
389+
{
364390
serialGVRET.clearBufferedBytes();
365391
}
366392
}
367393

368-
if (wifiLength > 0) {
394+
if (wifiLength > 0)
395+
{
369396
wifiManager.sendBufferedData();
370397
}
371398
}
372399

373400
serialCnt = 0;
374-
while ((Serial.available() > 0) && serialCnt < 128) {
401+
while ((Serial.available() > 0) && serialCnt < 128)
402+
{
375403
serialCnt++;
376404
in_byte = Serial.read();
377405
serialGVRET.processIncomingByte(in_byte);
378406
}
379407
}
380408

381409
// write data to SD card
382-
void TaskSDWrite(void *pvParameters) {
383-
for (;;) {
410+
void TaskSDWrite(void *pvParameters)
411+
{
412+
for (;;)
413+
{
384414
// blocks/waits 1000 ms to receive data from SD_Queue
385-
if (xQueueReceive(SD_Queue, &SD_buffer, 1000 * portTICK_PERIOD_MS) != pdPASS) {
415+
if (xQueueReceive(SD_Queue, &SD_buffer, 1000 * portTICK_PERIOD_MS) != pdPASS)
416+
{
386417
Serial.println("SD queue receive error: 1000ms second timeout.");
387-
} else {
418+
}
419+
else
420+
{
388421
LogFile.print(SD_buffer);
389422
}
390423
}

0 commit comments

Comments
 (0)
Please sign in to comment.