ttlappalainen / NMEA2000

NMEA2000 library for Arduino
515 stars 211 forks source link

NMEA2000_CAN.h Patch for newer ESP32xx devices #348

Open red8o opened 10 months ago

red8o commented 10 months ago

I had a problem with newer ESP32xx MCUs, as they apparently are not compatible with the included ESP32 code for the internal ESP32xx CAN interface. (Now named "TWAI" by Esperssif.) Luckily this has already been circumvented by jiauka, see https://github.com/jiauka/NMEA2000_esp32xx . The esp32xx library seems to work flawlessly on my ESP32-C3. In order to use the standard NMEA2000_CAN.h, I have modified the file like this, from line 267 onwards:

#elif USE_N2K_CAN == USE_N2K_ESP32_CAN

  #if defined( CONFIG_IDF_TARGET_ESP32C3 ) || defined( CONFIG_IDF_TARGET_ESP32S2 ) || defined( CONFIG_IDF_TARGET_ESP32S3 )
    #include <NMEA2000_esp32xx.h>     // https://github.com/jiauka/NMEA2000_esp32xx
    tNMEA2000 &NMEA2000=*(new tNMEA2000_esp32xx());
  #else
    #include <NMEA2000_esp32.h>       // https://github.com/ttlappalainen/NMEA2000_esp32
    tNMEA2000 &NMEA2000=*(new tNMEA2000_esp32());
  #endif

#else //

I am not sure if CONFIG_IDFTARGET... is the best way to do it, but it seems do it for me. Maybe this can be improved.

ttlappalainen commented 10 months ago

NMEA2000_esp32xx should work with all ESP32 versions. NMEA2000_esp32 is tested and certified by companies using it. NMEA2000_esp32xx has not yet been used by any company and I have not had time to test it. There has been several other cases like "seems to work flawlessly", but finds out in heavy tests that they does not.

riotenn commented 6 months ago

I set up with NMEA2000_esp32xx on an Arduino Nano ESP32. This is the Nora S3 version of the ESP32. It compiles OK. I have followed the instructions to test on the serial bus only (leaving CAN for the next step) in the TemperatureMonitor example. Specifically, I Uncommented: Serial.begin(115200); NMEA2000.SetForwardStream(&Serial); Commented out: // NMEA2000.EnableForward(false);

It seems to run without hanging. However, I do not get any messages on the Actisense Reader - just a repeated " Get Operating Mode Timeout 500ms". message.

For serial readout, I get unreadable output in the serial monitor. I then uncommented: NMEA2000.SetForwardType(tNMEA2000::fwdt_Text);

This showed, in the Serial Monitor window (with Actisense disconnected): 14:26:12.917 -> 13211 : Pri:5 PGN:130310 Source:22 Dest:255 Len:8 Data:1,C1,70,FF,FF,FF,FF,FF for about 15 seconds (running at 9,600 baud) and then switched to alternating lines of: 14:26:12.917 -> 13211 : Pri:5 PGN:130310 Source:22 Dest:255 Len:8 Data:1,C1,70,FF,FF,FF,FF,FF 14:26:13.412 -> PGN 130312 send failed 14:26:13.412 -> 13691 : Pri:5 PGN:130312 Source:22 Dest:255 Len:8 Data:1,1,4,7D,73,FF,FF,FF 14:26:13.412 -> PGN 130311 send failed 14:26:13.412 -> 13701 : Pri:5 PGN:130311 Source:22 Dest:255 Len:8 Data:1,C4,7D,73,FF,7F,FF,FF 14:26:13.412 -> PGN 130310 send failed

I am intensely studying the code but any hints would be appreciated.

Thanks

riotenn commented 6 months ago

Sorry, the repeating 3 lines in the serial monitor prior to the "send failed" messages are: 14:33:23.309 -> 2201 : Pri:5 PGN:130311 Source:22 Dest:255 Len:8 Data:1,C4,7D,73,FF,7F,FF,FF 14:33:23.309 -> 2211 : Pri:5 PGN:130310 Source:22 Dest:255 Len:8 Data:1,C1,70,FF,FF,FF,FF,FF 14:33:23.818 -> 2701 : Pri:5 PGN:130311 Source:22 Dest:255 Len:8 Data:1,C4,7D,73,FF,7F,FF,FF 14:33:23.818 -> 2711 : Pri:5 PGN:130310 Source:22 Dest:255 Len:8 Data:1,C1,70,FF,FF,FF,FF,FF 14:33:24.313 -> 3201 : Pri:5 PGN:130311 Source:22 Dest:255 Len:8 Data:1,C4,7D,73,FF,7F,FF,FF 14:33:24.313 -> 3211 : Pri:5 PGN:130310 Source:22 Dest:255 Len:8 Data:1,C1,70,FF,FF,FF,FF,FF 14:33:24.794 -> 3691 : Pri:5 PGN:130312 Source:22 Dest:255 Len:8 Data:1,1,4,7D,73,FF,FF,FF

ttlappalainen commented 6 months ago

Have you read the document https://ttlappalainen.github.io/NMEA2000/page_h_w_set_up.html chapter "Most common hardware errors"? If you get "send failed" message, CAN controller does not communicate with bus. Or have you setup can pins properly? See issue https://github.com/ttlappalainen/NMEA2000/issues/374

red8o commented 6 months ago

Looks like you have noise on the CAN bus that prevents the controller from actually sending the packets. The controller seems to accept the packets and says "ok", but in fact the packets stay in the transmit buffer, because the controller cannot physically send them to the bus. (The controller always reads back what it (tries to) write to the bus, it's part of the protocol.) So after a few seconds the buffer fills up and that is when you get that error message. Sending packets faster may take you to that point a little sooner. You can check using a logic analyser on the can bus. Most cheap analyzers however will not work with CAN H to CAN L but require you to measure CAN L to Ground. Also check wiring (CAN H / CAN L and terminators on both ends). I used a tranceiver board from aliexpress, the one that labels the last pin "VIO" on one side of the PCB and "NC" on the other. Make sure to supply this pin with 5 V, as 3.3 V seem to not be enough to drive the bus. (You can use 3.3 V on the VCC pin for the Interface to the MCU). On my workbench, connecting all devices to the same ground seemed to help, too. The problem may also go away if you have three or four devices on the bus - but of course that is not really a proper solution.

riotenn commented 6 months ago

Thanks for the very quick responses.
I have studied the CAN issues document and will give it another read. However, it was my understanding that, at this point in the TermperatureMonitor example (serial lines uncommented) that the CAN transceiver was not yet involved in the send/receive chain. I am in the very initial section: "Try on PC only Now we are ready to try sample without N2k bus connection. So you need only Arduino board and PC. No CANBUS shield or extra chips yet!"

I am using the ESP32xx alternate library with the modifications of red80 above. Yes, it does seem a buffer is filling but not being emptied. Can this occur at the point I am in the code testing? Is it possible this is an issue with Actisense Reader not pulling data from the (simulated) COM port?

Again, thanks very much for the assistance.

ttlappalainen commented 6 months ago

If you test CAN controller without connecting it to bus, you have that issue. You must have bus with termination resistors and at least one working device. If you do not have proper bus connection, buffer will not empty, since controller fails to send any data to the bus. Easiest is to make one device with e.g., TemperatureMonitor and other with DataDisplay2 or DeviceAnalyzer. Or use ActisenseListenerSender and my NMEASimulator.

You can test device without CAN bus by setting library to debug mode, but there is not much use with it. Either I have tested debug mode for several years.

riotenn commented 6 months ago

Thanks very much. I thought I could start with Actisense Listener on the PC and then move to CAN H/W. Apparently not. I thought I might be experiencing issues due to the ESP32S3 and use of the ESPxx code.

I'll set up the N2K network and give that a try.
Thanks again for your assistance.

riotenn commented 6 months ago

Working! I abandoned trying to use the Actisense Reader for debugging. I added a 3.3V CAN driver to the Arduino Nano ESP32 and added the ESP32xx "fix" for the S3 version of the ESP32 (along with red80's code additions). Simple Temperature example is displaying on a Garmin on my bench setup. Good progress. Thanks for all the assistance!