wellenvogel / esp32-nmea2000

nmea2000 gateway with ESP32
GNU General Public License v2.0
63 stars 29 forks source link

use TWAI driver in other project? #67

Open phatpaul opened 7 months ago

phatpaul commented 7 months ago

Hi Andreas, I use the NMEA2000 library for my custom project. It looks like your ESP32 CAN / TWAI driver is much improved over the other options I know of:

https://github.com/jiauka/NMEA2000_esp32xx - works with modern IDF, but no error handling https://github.com/ttlappalainen/NMEA2000_esp32 - outdated (and no error handling)

I'm wondering if your driver can be used with the NMEA2000 library? If so, would you consider splitting it into it's own module so I can include it? Or can I just port your additions to my fork: https://github.com/phatpaul/NMEA2000_esp32xx

wellenvogel commented 7 months ago

Yes, works with the NMEA200 library (just my use case). As was already thinking about splitting it into a separate lib - but for now: to much effort ;-( But it should be fairly easy to use it: Copy the directory https://github.com/wellenvogel/esp32-nmea2000/tree/master/lib/nmea2ktwai to your lib dir. Init the NMEA2000 lib like in: https://github.com/wellenvogel/esp32-nmea2000/blob/146bc44c6202c5b903835165c691030610ed3915/src/main.cpp#L128 You can just omit the log wrapper and use Nmea2kTwai instead of Nmea2kTwaiLog (no logger parameter at the end...). And you need to call NMEA2000.loop() in your loop to have the bus recovery handling working.

phatpaul commented 7 months ago

Great! I think I'm almost there, but I'm running on ESP-IDF, not Arduino. So I can't use GwTimer.h which requires Arduino.h. So I guess I just have to port the timers. Do you know of a cross-platform timers implementation already?

phatpaul commented 7 months ago

Well, this is what NMEA2000 library does:

#if defined(ARDUINO_ARCH_ESP32) || defined(ESP_PLATFORM)
#include <esp_timer.h>
#include <esp_attr.h>
  inline uint64_t N2kMillis64() {
    return esp_timer_get_time()/1000ULL;
  }
  inline uint32_t N2kMillis() { return N2kMillis64(); }
#elif defined(ARDUINO)
  #include <Arduino.h>
  uint64_t N2kMillis64();
  inline uint32_t N2kMillis() { return millis(); }
#else
  uint64_t N2kMillis64();
  uint32_t N2kMillis();
#endif
phatpaul commented 7 months ago

For the timers, I used the tN2kSyncScheduler since it is already available from the NMEA2000 library and was already made portable to IDF.
It compiles now, still need to do testing. Thanks for your code and help!

If you are interested in my changes see my fork here: https://github.com/phatpaul/NMEA2000_esp32xx/blob/errorrecovery/NMEA2000_esp32xx.cpp

wellenvogel commented 7 months ago

So I can't use GwTimer.h

Ohh - yes, sorry forgot about that. Was my very simple scheduler. But I guess tN2kSyncScheduler is fine any way. I started with the Arduino framework as some parts are just easier to use - but step by step I start using IDF directly any way. Great to see that you are building a library out of it (was also missing one when I started using TWAI) - so maybe at some point in time I could switch to your's ;-)