Arduino IDE 2.3.10, ESP32RET

I am trying to build and upload esp32_savvycan to an ESP32 dev board. I am working on a laptop with Microsoft Windows 11, version 10.0.26200.8973

I have installed Arduino IDE 2.3.10, all the files including system files are completely up to date.

The can module I am using is from MrDIY. The ESP32 shows in the bottom right of the IDE as ESP32-WROOM-DA Module on COM3.

I have not modified any of the source files, when I try to compile the sketch the output is:

FQBN: esp32:esp32:esp32da
Using board 'esp32da' from platform in folder: C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.3.11
Using core 'esp32' from platform in folder: C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.3.11

cmd /c if exist "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\tools\\partitions\\default.csv" COPY /y "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\tools\\partitions\\default.csv" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\partitions.csv"
        1 file(s) copied.
cmd /c if exist "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\variants\\esp32da\\partitions.csv" COPY /y "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\variants\\esp32da\\partitions.csv" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\partitions.csv"
cmd /c if exist "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\partitions.csv" COPY /y "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\partitions.csv" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\partitions.csv"
cmd /c IF EXIST "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\bootloader.bin" ( COPY /y "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\bootloader.bin" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\ESP32RET.ino.bootloader.bin" ) ELSE ( IF EXIST "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\variants\\esp32da\\bootloader.bin" ( COPY "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.3.11\\variants\\esp32da\\bootloader.bin" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\ESP32RET.ino.bootloader.bin" ) ELSE ( "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esptool_py\\5.3.1\\esptool.exe" --chip esp32 elf2image --flash-mode dio --flash-freq 80m --flash-size 4MB -o "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\ESP32RET.ino.bootloader.bin" "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esp32-libs\\3.3.11\\bin\\bootloader_qio_80m.elf" ) )
esptool v5.3.1
Creating ESP32 image...
Merged 2 ELF sections.
Successfully created ESP32 image.
cmd /c if exist "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\build_opt.h" COPY /y "C:\\Users\\simon\\OneDrive\\Documents\\Arduino\\canabus-main\\esp32_savvycan\\src\\ESP32RET\\build_opt.h" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\build_opt.h"
cmd /c if not exist "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\build_opt.h" type nul > "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\build_opt.h"
cmd /c type nul > "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9/file_opts"
cmd /c COPY /y "C:\\Users\\simon\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esp32-libs\\3.3.11\\sdkconfig" "C:\\Users\\simon\\AppData\\Local\\arduino\\sketches\\E9D17FE56C8DECD4C673A922EBC4F1A9\\sdkconfig"
        1 file(s) copied.
Detecting libraries used...
C:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2601/bin/xtensa-esp32-elf-g++ -c @C:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp32-libs\3.3.11/flags/cpp_flags -w -Os -Werror=return-type -w -x c++ -E -CC -DF_CPU=240000000L -DARDUINO=10607 -DARDUINO_ESP32_WROOM_DA -DARDUINO_ARCH_ESP32 -DARDUINO_BOARD="ESP32_WROOM_DA" -DARDUINO_VARIANT="esp32da" -DARDUINO_PARTITION_default -DARDUINO_HOST_OS="windows" -DARDUINO_FQBN="esp32:esp32:esp32da:UploadSpeed=921600,CPUFreq=240,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=none,LoopCore=1,EventsCore=1,EraseFlash=none" -DESP32=ESP32 -DCORE_DEBUG_LEVEL=0 -DARDUINO_RUNNING_CORE=1 -DARDUINO_EVENT_RUNNING_CORE=1 -DARDUINO_USB_CDC_ON_BOOT=0 @C:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp32-libs\3.3.11/flags/defines -IC:\Users\simon\OneDrive\Documents\Arduino\canabus-main\esp32_savvycan\src\ESP32RET -iprefix C:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp32-libs\3.3.11/include/ @C:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp32-libs\3.3.11/flags/includes -IC:\Users\simon\AppData\Local\Arduino15\packages\esp32\tools\esp32-libs\3.3.11/qio_qspi/include -IC:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.3.11\cores\esp32 -IC:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.3.11\variants\esp32da @C:\Users\simon\AppData\Local\arduino\sketches\E9D17FE56C8DECD4C673A922EBC4F1A9/build_opt.h @C:\Users\simon\AppData\Local\arduino\sketches\E9D17FE56C8DECD4C673A922EBC4F1A9/file_opts C:\Users\simon\AppData\Local\arduino\sketches\E9D17FE56C8DECD4C673A922EBC4F1A9\sketch\ESP32RET.ino.cpp.merged -o nul -MMD -MF C:\Users\simon\AppData\Local\arduino\sketches\E9D17FE56C8DECD4C673A922EBC4F1A9\sketch\ESP32RET.ino.cpp.merged.libsdetect.d
Alternatives for config.h: []
ResolveLibrary(config.h)
  -> candidates: []
C:\Users\simon\OneDrive\Documents\Arduino\canabus-main\esp32_savvycan\src\ESP32RET\ESP32RET.ino:28:10: fatal error: config.h: No such file or directory
   28 | #include "config.h"
      |          ^~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: config.h: No such file or directory

config.h exists in the src sub-folder of the project, so I'm really not sure why this is giving this error.

Hi @SPlatten

Just to be sure, do you mean it is at the following path?:

C:\Users\simon\OneDrive\Documents\Arduino\canabus-main\esp32_savvycan\src\ESP32RET\src\config.h

If yes, then you must change line 28 in ESP32RET.ino from this:

#include "config.h"

To this:

#include "src/config.h"

@ptillisch
Do you think it is a correct way to build if OP tried to compile code just inside a library folder?

Please provide us with a link to the library and post the main sketch code.

Now if i go from the point of view that you have downloaded the library from github (canabus-main indicates that) you have not dropped the extracted files in the right place if OneDrive\\Documents\\Arduino\ is you sketch folder, the library should be in a subfolder of you sketch folder called libraries

The actual fix for the header was ..\config.h, however the latest build errors:

In file included from C:\Users\simon\OneDrive\Documents\Arduino\canabus-main\esp32_savvycan\src\ESP32RET\ESP32RET.ino:28:
C:/Users/simon/OneDrive/Documents/Arduino/canabus-main/esp32_savvycan/src/config.h:35:10: fatal error: esp32_can.h: No such file or directory
35 | #include "esp32_can.h"
| ^~~~~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: exit status 1

Here is ESP32RET.ino:

/*
 ESP32RET.ino

 Created: June 1, 2020
 Author: Collin Kidder

Copyright (c) 2014-2020 Collin Kidder, Michael Neuweiler

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "..\config.h"
#include <esp32_can.h>
#include <SPI.h>
#include <Preferences.h>
#include <FastLED.h>
#include "ELM327_Emulator.h"
#include "SerialConsole.h"
#include "wifi_manager.h"
#include "gvret_comm.h"
#include "can_manager.h"
#include "lawicel.h"

byte i = 0;

uint32_t lastFlushMicros = 0;

bool markToggle[6];
uint32_t lastMarkTrigger = 0;

EEPROMSettings settings;
SystemSettings SysSettings;
Preferences nvPrefs;
char deviceName[20];
char otaHost[40];
char otaFilename[100];

uint8_t espChipRevision;

ELM327Emu elmEmulator;

WiFiManager wifiManager;

GVRET_Comm_Handler serialGVRET; //gvret protocol over the serial to USB connection
GVRET_Comm_Handler wifiGVRET; //GVRET over the wifi telnet port
CANManager canManager; //keeps track of bus load and abstracts away some details of how things are done
LAWICELHandler lawicel;

SerialConsole console;

CRGB leds[A5_NUM_LEDS]; //A5 has the largest # of LEDs so use that one even for A0 or EVTV

CAN_COMMON *canBuses[NUM_BUSES];

//initializes all the system EEPROM values. Chances are this should be broken out a bit but
//there is only one checksum check for all of them so it's simple to do it all here.
void loadSettings()
{
    Logger::console("Loading settings....");

    //Logger::console("%i\n", espChipRevision);

    for (int i = 0; i < NUM_BUSES; i++) canBuses[i] = nullptr;

    nvPrefs.begin(PREF_NAME, false);

    settings.useBinarySerialComm = nvPrefs.getBool("binarycomm", false);
    settings.logLevel = nvPrefs.getUChar("loglevel", 1); //info
    settings.wifiMode = nvPrefs.getUChar("wifiMode", 2); //Wifi defaults to creating an AP
    settings.enableBT = nvPrefs.getBool("enable-bt", false);
    settings.enableLawicel = nvPrefs.getBool("enableLawicel", true);
    settings.systemType = 0; //nvPrefs.getUChar("systype", (espChipRevision > 2) ? 0 : 1); //0 = A0, 1 = EVTV ESP32

    if (settings.systemType == 0)
    {
        canBuses[0] = &CAN0;
        SysSettings.LED_CANTX = 26;
        SysSettings.LED_CANRX = 27;
        SysSettings.LED_LOGGING = 35;
        SysSettings.LED_CONNECTION_STATUS = 0;
        SysSettings.fancyLED = false;
        SysSettings.logToggle = false;
        SysSettings.txToggle = true;
        SysSettings.rxToggle = true;
        SysSettings.lawicelAutoPoll = false;
        SysSettings.lawicelMode = false;
        SysSettings.lawicellExtendedMode = false;
        SysSettings.lawicelTimestamping = false;
        SysSettings.numBuses = 1;
        SysSettings.isWifiActive = false;
        SysSettings.isWifiConnected = false;
        strcpy(deviceName, MACC_NAME);
        strcpy(otaHost, "");
        strcpy(otaFilename, "");
        pinMode(SysSettings.LED_CANTX, OUTPUT);
        pinMode(SysSettings.LED_CANRX, OUTPUT);
        digitalWrite(SysSettings.LED_CANTX, LOW);
        digitalWrite(SysSettings.LED_CANRX, LOW);
        delay(100);
        FastLED.addLeds<LED_TYPE, A0_LED_PIN, COLOR_ORDER>(leds, A0_NUM_LEDS).setCorrection( TypicalLEDStrip );
        FastLED.setBrightness(  BRIGHTNESS );
        leds[0] = CRGB::Red;
        FastLED.show();
        //pinMode(21, OUTPUT);
        //digitalWrite(21, LOW);
        CAN0.setCANPins(GPIO_NUM_4, GPIO_NUM_5);     // use this for shield v1.3 and later
        //  CAN0.setCANPins(GPIO_NUM_5, GPIO_NUM_4); // use this for shield v1.2 and earlier
    }

    if (nvPrefs.getString("SSID", settings.SSID, 32) == 0)
    {
        strcpy(settings.SSID, deviceName);
        strcat(settings.SSID, "-Wireless");
   }

    if (nvPrefs.getString("wpa2Key", settings.WPA2Key, 64) == 0)
    {
        strcpy(settings.WPA2Key, "mrdiy.ca");
    }
    if (nvPrefs.getString("btname", settings.btName, 32) == 0)
    {
        strcpy(settings.btName, "ELM327-");
        strcat(settings.btName, deviceName);
    }

    char buff[80];
    for (int i = 0; i < SysSettings.numBuses; i++)
    {
        sprintf(buff, "can%ispeed", i);
        settings.canSettings[i].nomSpeed = nvPrefs.getUInt(buff, 500000);
        sprintf(buff, "can%i_en", i);
        settings.canSettings[i].enabled = nvPrefs.getBool(buff, (i < 2)?true:false);
        sprintf(buff, "can%i-listenonly", i);
        settings.canSettings[i].listenOnly = nvPrefs.getBool(buff, false);
        sprintf(buff, "can%i-fdspeed", i);
        settings.canSettings[i].fdSpeed = nvPrefs.getUInt(buff, 5000000);
        sprintf(buff, "can%i-fdmode", i);
        settings.canSettings[i].fdMode = nvPrefs.getBool(buff, false);
    }

    nvPrefs.end();

    Logger::setLoglevel((Logger::LogLevel)settings.logLevel);

    for (int rx = 0; rx < NUM_BUSES; rx++) SysSettings.lawicelBusReception[rx] = true; //default to showing messages on RX 
}

void setup()
{
    //delay(5000); //just for testing. Don't use in production

    espChipRevision = ESP.getChipRevision();

    Serial.begin(115200); //for production
    //Serial.begin(115200); //for testing

    SysSettings.isWifiConnected = false;

    loadSettings();

    //If you enable PSRAM then BluetoothSerial will kill everything via a heap error. These calls
    //try to debug that. But, no dice yet. :(
    //heap_caps_print_heap_info(MALLOC_CAP_8BIT);

    if (settings.enableBT) 
    {
        Serial.println("Starting bluetooth");
        elmEmulator.setup();
        if (SysSettings.fancyLED && (settings.wifiMode == 0) )
        {
            leds[0] = CRGB::Green;
            FastLED.show();
        }
    }
    /*else*/ wifiManager.setup();

    //heap_caps_print_heap_info(MALLOC_CAP_8BIT);

    //heap_caps_print_heap_info(MALLOC_CAP_8BIT);
    Serial.println("");
    Serial.println("===================================");
    Serial.println("        MrDIY.ca CAN Shield        ");
    Serial.println("===================================");
    Serial.println("");
    //Serial.print("Build number: ");
    //Serial.println(CFG_BUILD_NUM);

    canManager.setup();

    SysSettings.lawicelMode = false;
    SysSettings.lawicelAutoPoll = false;
    SysSettings.lawicelTimestamping = false;
    SysSettings.lawicelPollCounter = 0;
    
    //elmEmulator.setup();

    //Serial.print("Free heap: ");
    //Serial.println(esp_get_free_heap_size());

   // Serial.print("Done with init\n");
}
 
/*
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
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
and not a real frame. The bottom three bits specify which mark triggered.
*/
void sendMarkTriggered(int which)
{
    CAN_FRAME frame;
    frame.id = 0xFFFFFFF8ull + which;
    frame.extended = true;
    frame.length = 0;
    frame.rtr = 0;
    canManager.displayFrame(frame, 0);
}

/*
Loop executes as often as possible all the while interrupts fire in the background.
The serial comm protocol is as follows:
All commands start with 0xF1 this helps to synchronize if there were comm issues
Then the next byte specifies which command this is.
Then the command data bytes which are specific to the command
Lastly, there is a checksum byte just to be sure there are no missed or duped bytes
Any bytes between checksum and 0xF1 are thrown away

Yes, this should probably have been done more neatly but this way is likely to be the
fastest and safest with limited function calls
*/
void loop()
{
    //uint32_t temp32;    
    bool isConnected = false;
    int serialCnt;
    uint8_t in_byte;

    /*if (Serial)*/ isConnected = true;

    if (SysSettings.lawicelPollCounter > 0) SysSettings.lawicelPollCounter--;
    //}

    canManager.loop();
    /*if (!settings.enableBT)*/ wifiManager.loop();

    size_t wifiLength = wifiGVRET.numAvailableBytes();
    size_t serialLength = serialGVRET.numAvailableBytes();
    size_t maxLength = (wifiLength>serialLength) ? wifiLength : serialLength;

    //If the max time has passed or the buffer is almost filled then send buffered data out
    if ((micros() - lastFlushMicros > SER_BUFF_FLUSH_INTERVAL) || (maxLength > (WIFI_BUFF_SIZE - 40)) ) 
    {
        lastFlushMicros = micros();
        if (serialLength > 0) 
        {
            Serial.write(serialGVRET.getBufferedBytes(), serialLength);
            serialGVRET.clearBufferedBytes();
        }
        if (wifiLength > 0)
        {
            wifiManager.sendBufferedData();
        }
    }

    serialCnt = 0;
    while ( (Serial.available() > 0) && serialCnt < 128 ) 
    {
        serialCnt++;
        in_byte = Serial.read();
        serialGVRET.processIncomingByte(in_byte);
    }

    elmEmulator.loop();
}

as long as the library folder is not actually in either the sketchbook\libraries or core libraries folder, the compiler will not be looking in the correct place for the files referenced.

Which is not really a fix if the next file can not be found either.

What do I need to do to resolve this?

Where is esp32_can.h located on your PC ?

In the IDE under File->Preferences there is the location of you sketchbook folder.

Inside this folder there should be the libraries folder (i mean is actually called that)

Move your folder canabus-main to that location. I see you are using onedrive, please make sure the IDE has permission to access this remote location and/or make all files available offline

Close and open the IDE.

In the File->Examples find the examples for library you want to use ESP32RET.ino It should show up under examples, otherwise you can locate it manually and open it.

As far as i know that should fix the issue you are having.

@SPlatten please provide a link to the web page where you found this "canabus" project.

That will give the forum helpers context that will allow us to more effectively assist you.