NMEA2000
NMEA2000 copied to clipboard
"send failed" but still sending?
I'm trying to bring up the library on a KeeYees ESP32 board (ESP32-WROOM-32 module, has "NodeMCU-32S" silk-screened on the underside, but otherwise poorly documented).
I'm working with the MessageSender sketch to demonstrate basic functionality, using an MCP2562 as transceiver. If I compile the sketch with default outputs (TX on GPIO 16, RX on GPIO 4), the code starts fine and reports a few messages being sent without error, but then quickly starts to report "send failed" for every message being sent. Monitoring the CANH/CANL on the MCP2562, however, shows that data is still being sent (or, at least, the outputs are changing).
If, on the other hand, I attempt to reset the pins to something else (say 34/35), the code runs without reporting "send failed", but I don't get data being generated on the pins, so far as I can tell.
Can anyone shed some light on this behaviour? Has anyone attempted to use this module for this purpose?
You must have can-h and can-l connected to proper bus. So at least one 120 ohm termination resistor must exist. In proper bus you have totally 2 termination 1 in both end.
fwiw, 16 and 4 dont work on this chip, I've used successfully:
#define ESP32_CAN_TX_PIN GPIO_NUM_17
#define ESP32_CAN_RX_PIN GPIO_NUM_16
should mention it's a crappy chip altogether, difficult to get working, unstable, analogue input is a joke, uploading stuff to it you have to hit one of the two buttons on it else wont connect, etc. Had three, two installed on my engines, ripped them off after a season full of problems and now back to Teensy3.5-6
You must have can-h and can-l connected to proper bus. So at least one 120 ohm termination resistor must exist. In proper bus you have totally 2 termination 1 in both end.
Thanks for the speedy response, and the library (currently making my life much easier).
I have the MCP2562 loaded with a 120R across the CANH/L pins, but nothing otherwise on the bus except some scope probes; I'll add another MCP2562 to simulate the opposite end, and re-check. It's not clear to me, however, why not having the output bus (on the MCP2562) loaded/terminated should cause the ESP32 to not generate data, or why selecting different output pins should cause a change in behaviour with the same physical wiring. That seems a little black magic to me!
I'll update after re-checking.
should mention it's a crappy chip altogether, difficult to get working, unstable, analogue input is a joke, uploading stuff to it you have to hit one of the two buttons on it else wont connect, etc. Had three, two installed on my engines, ripped them off after a season full of problems and now back to Teensy3.5-6
@virtuvas, thanks for the speedy response. I'll give the alternative pins a try, although I did try with a random pair elsewhere (34/35 in my case), and although the sketch didn't report sending errors, it didn't seem to be generating output data on the pins. It was, however, 0200 local time, so I'll check again when awake.
When you say "it's a crappy chip altogether" do you mean the ESP32 in general, or this particular dev board implementation specifically?
I would also like to know, since I am implementing things over ESP32. Compared to Teensy analog is bad. Anyway for +- 0.06 V accuracy over 0-32 V linear scaling correction is enough. For better accuracy one needs about 200 sampling points. It seem to be repeatable - I have not yet done automated tests, but will do. Our test systems has been reliably running on bus. On the other hand we do not try to do very complex things. Simply normal bus handling+some sensor values sent to bus.
I just fixed NMEA2000_ESP32 library, which crashed in some cases and caused ESP32 to go to state where it crashed every time it rebooted after crash. This naturally caused device to be lost from bus until power off/on.
In out device upload works simply and directly from PlatformIO or batch - no touching to any buttons during upgrade. We even do not have buttons on board. I also have WebServer option, where I can have OTA upgrade. Also OTA works reliably - sometimes upgrade fails, but pages opens back and I can retry. So I have not managed to mash device to unresponsible state.
The best thing on ESP32 is OTA possibility and it is cheaper compared to Teensy in production mind.
well as Timo says, analog is BAD and even worse it's not linear and it gets even worse if you go for 12bit read. Dropping to 10 bit makes values better, but cameon!
I had lots of crashes with two of them on the bus and had to reset the whole NMEA bus in order to get them working again (and that wasnt always the case) Haven't tried the new lib that Timo has, can do but I now only have one running and haven't noticed any crashes lately.
To me generally, the implementation of Timo's lib in teensies is rock solid compared to the flaky esp32s. Sorry cannot be of more help. The reason I bought them was that they were cheaper, theoretically faster and had OTA which is handy if you want to change something on the two engine boxes and it means going down the hatch with the laptop at hand trying to find a place to rest it on, connect, upload, check the monitor, etc.
V.
Analog is rather linear, if you use range from 160->3600. At that range one reaches accuracy +-0.06 over 60 V. If you need to measure just 0-15 V, accuracy is 4 times better with right scaling. Note that you must generate offset to your measurement so that your lowest measurement gives you that 160 on ADC reading. But still this is 10 times worse in accurasy compared to Teensy.
The crashes could have been caused by the NMEA2000_ESP32. In original Thomas Barth library there were expected that frame length will never be corrupted. If it was, it could write behind buffer index and cause stack smash. I limited that and it fixed my crashes. We have put lot effort for modules based on ESP32, so I wont give up yet.
But as virtuvas commented, Teensy library is rock solid.
OK, so some updates (a little late, but better that than ...)
-
No data on certain pins == I am dumb. I managed to chose the limited number of pins on the ESP32 that don't actually output.
-
No data on standard pins 16/4 == I am dumb. It turns out I was seeing the standard announcement frame that the CAN controller was sending, which looked odd through a protocol analyser set at the wrong bit rate. Send and receive via these pins work as expected, I think.
-
"Send Failed" is an ESP32 problem == I am dumb (or unobservant). If I run exactly the same code on a brand-name Arduino Due, the same behaviour happens, even though data is still flowing, and the messages appear to be received by the ESP32 on the other end of the (now correctly terminated) CANbus. So whatever the problem is, it isn't constrained to the ESP32.
So the bottom line is that if I use MessageSender on the Due, with output through an MCP2562, and run my custom code on the ESP32 with interface via another MCP2562, I am seeing data being captured and recorded on the ESP32, and it appears to be what's intended to be sent. However, the code on the Due still reports errors. It's odd.
Logic: You get "send failed", if buffer gets full. If you have large send buffer e.g. 100 frames and you send single frame message in every second and device can not send messages at all, buffer gets full in 100 sec and so you will see message delayed. This often confuses people and they thought it works at beginning and then stops.
The most common reason for system can not send message is that there is no termination on the line. CAN system listens bus to wait it free for starting sending message. If there is no termination, line is floating and device may see it is not free for sending.
Other reason for devices having internal CAN (DUE, ESP32) may be invalid CAN pin configuration, which leads to first case.
Then there is send buffer size. If that is too small, it may get full in bursts and you will see failure report, but some data will go to the bus. Please check you have big enough buffer definition. In default MessageSender I have offset on, when I send messages and buffer has been defined rather big: NMEA2000.SetN2kCANSendFrameBufSize(250); In older versions buffer was smaller and there was no offset causing failure.