Open jimarcher opened 4 years ago
Yes, I made a fix for that and it fixed it at least for power up reset. What do you mean with soft reset? If it does not reset pin settings and CAN controller, it may be the problem.
Hi Timo, by soft reset, I mean if I issue a software restart command, such as after an OTA update, or after a remote update to the user configuration. The power is not interrupted and the enable pin is not pulled low.
I started a discussion on the Espressif forums (at esp32.com) and this seems to be a known issue. They report the Espressif driver handles it. The discussion is here:
https://www.esp32.com/viewtopic.php?f=2&t=16808&p=63664#p63664
I don't use the Espressif dev environment so I'm going to see what I can do about using their driver, or fixing this driver.
Is that critical? If you receive invalid PGNs, you can just ignore them.
My fix on November was for sending invalid PGNs after reset, which was more critical due to certification tests. Do you also see invalid PGN on other devices, when your device does reset?
Sorry I was not clear. I start receiving invalid PGNs, and there are no valid ones. It seems all the data coming in is corrupted.
I have not actually looked at the PGNs I'm sending after this problem starts. I have Can King, and the PGNs on the N2K bus are valid, it's just that the data I'm getting is corrupted. I'll check to see if the data I'm sending is also corrupted. Over on esp32.com there is a gentleman who advises that while the Thomas Barth driver got CAN going three years ago, it has substantial issues and it's critical to move to the ESP-IDF driver. That looks to be non-trivial, but I'm looking to see what it would entail. I'm not using ESP-IDF so there is some extra work.
Actually, maybe I misunderstood your question. Timo, by "other devices" did you mean different ESP32 boards or other N2K devices on the bus?
I meant other N2k devices.
But your problem is strange. I have two ESP32 devices on my boat and never seen that problem even after OTA update. But I have also rewritten several things and do not use published libraries. E.g. after my OTA update I generate watchdog to restart: void Restart() { esp_task_wdt_init(1,true); while(true); // WD does full reset for CPU }
I'm using a different OTA mechanism, and Mongoose, and I don't believe I have a post-OTA hook I can capture. If that restart resets the peripheral interfaces then it probably works. But the driver should do that when it starts. I'll investigate and see if I can do a phepherial reset, thanks.
Hi Timo, I have been working on this since it has caused me a lot of grief. Without a doubt, a soft reset, even when triggered by the built in watchdog timer, can leave the CAN controller in an undefined state. Fortunately, the ESP-IDF provides a mechanism to reset it as if it had come up from power on. I added this to my code and it solved this problem. The ESP32 CAN controller has other issues as well, but at least I can work around them.
The fix is to call:
periph_module_reset(PERIPH_CAN_MODULE);
I have added this early in my code, before initializing your library.
If you like, I can add it to code and open a PR.
Please do PR. It is easier to see there.
PR opened.
Bom dia, final de semana estive trabalhando com o meu projeto de enviar dados para o nmea2000, com o exemplo que tem do temperatura monitor verificando o sinal do Actisense NMEA reader não estava recebendo o sinal ISO somente os sinais temperatura. estava usando um arduino mega e um MCP2515/tja1050. tentei usar um ModeMCU V3 e não consegui transferir o programa , ele esta dando o erro abaixo, voce tem idéia do que estou fazendo errado? Arduino: 1.8.13 (Windows 7), Placa:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"
In file included from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:161:0,
from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\Examples\WindMonitor\WindMonitor.ino:4:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h:139:84: error: 'MCP_8MHz' was not declared in this scope
tNMEA2000_mcp(unsigned char _N2k_CAN_CS_pin, unsigned char _N2k_CAN_clockset = MCP_8MHz,
^
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h: In member function 'void tNMEA2000_mcp::SetSPI(SPIClass*)':
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h:141:43: error: 'class MCP_CAN' has no member named 'setSPI'
void SetSPI(SPIClass *_pSPI) { N2kCAN.setSPI(_pSPI); }
^
In file included from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\Examples\WindMonitor\WindMonitor.ino:4:0:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h: At global scope:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:173:27: error: 'MCP_16MHz' was not declared in this scope
^
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:176:56: note: in expansion of macro 'MCP_CAN_CLOCK_SET'
tNMEA2000 &NMEA2000=*(new tNMEA2000_mcp(N2k_SPI_CS_PIN,MCP_CAN_CLOCK_SET,N2k_CAN_INT_PIN,MCP_CAN_RX_BUFFER_SIZE));
^
exit status 1
Erro compilando para a placa NodeMCU 1.0 (ESP-12E Module)
Este relatório teria mais informações com "Mostrar a saida detalhada durante a compilação" opção pode ser ativada em "Arquivo -> Preferências"
Please write in English!
Good morning, weekend I was working with my project to send data to nmea2000, with the example that has the temperature monitor checking the signal of the Actisense NMEA reader was not receiving the ISO signal only the temperature signals. was using a mega arduino and an MCP2515 / tja1050. I tried using a ModeMCU V3 and I was unable to download the program, it is giving the error below, do you have any idea what I am doing wrong? Arduino: 1.8.13 (Windows 7), Placa:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"
In file included from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:161:0,
from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\Examples\WindMonitor\WindMonitor.ino:4:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h:139:84: error: 'MCP_8MHz' was not declared in this scope
tNMEA2000_mcp(unsigned char _N2k_CAN_CS_pin, unsigned char _N2k_CAN_clockset = MCP_8MHz,
^
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h: In member function 'void tNMEA2000_mcp::SetSPI(SPIClass*)':
C:\Users\celso\Documents\Arduino\libraries\NMEA2000_mcp-master/NMEA2000_mcp.h:141:43: error: 'class MCP_CAN' has no member named 'setSPI'
void SetSPI(SPIClass *_pSPI) { N2kCAN.setSPI(_pSPI); }
^
In file included from C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\Examples\WindMonitor\WindMonitor.ino:4:0:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h: At global scope:
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:173:27: error: 'MCP_16MHz' was not declared in this scope
^
C:\Users\celso\Documents\Arduino\libraries\NMEA2000-master\src/NMEA2000_CAN.h:176:56: note: in expansion of macro 'MCP_CAN_CLOCK_SET'
tNMEA2000 &NMEA2000=*(new tNMEA2000_mcp(N2k_SPI_CS_PIN,MCP_CAN_CLOCK_SET,N2k_CAN_INT_PIN,MCP_CAN_RX_BUFFER_SIZE));
^
exit status 1
Erro compilando para a placa NodeMCU 1.0 (ESP-12E Module)
Most likely you have loaded mcp_can library from wrong source. You have to download it from my git https://github.com/ttlappalainen/CAN_BUS_Shield. Remove other CAN_BUS_Shield libraries from your C:\Users\celso\Documents\Arduino\libraries folder and download right.
Other hints:
If you want to use different clock setting you do that on your .ino before including NMEA2000_CAN.h like this:
NodeMCU is Esp32 and it should use internal CAN with NMEA2000_esp32, if you have not forced to use mcp_can. Is that your purpose?
This issue is not right subject.
The libraries downloaded your git, I will try to reinstall to see if it works. from nodeMCU I was using your esp32 library I'm using the internal CAn via TX / RX. This is all doing as a test, my idea is to read a CAN network (J1939) from my motor and converter for NMEA2K, I believe that for that I will have to use an arduino because of the two internal CAN.
According your error messages mcp_can_dfs.h will be propably loaded from somewhere else. Check that you have only one CAN_BUS_Shield (or CAN_BUS_Shield-master) folder on your computer and there mcp_can_dfs.h on line 254 you have
Note that only Teensy 3.5, 3.6 and 4.x with multiple internal CAN are supported.
Good morning Timo, this weekend I tried a little more to work with Nmea on the Arduino Mega and I still couldn't get him to read the ISO information, I don't know what I'm doing wrong, I already deleted all the libraries I had in the IDE and installed only yours (CAN BUS, NMEA2000 and NMEA2000 mcp) on my two computers and still without success. Is it a hardware problem?
So do you have two computers each attached to Arduino Mega with Temperature monitor example and bot modified to be as NMEA2000.SetMode(tNMEA2000::N2km_ListenAndNode,22); so that you can use Actisense Reader on both computer? Do you have 8 MHz or 16 Mhz clock on CAN board?
When Temperture monitor starts up, it will send ISO address claim once to the bus and waits is anybody interested. If there would be e.g. MFD on bus, it should request device information, which library will automatically respond. Also if you have two Temperature monitors with same Source (=22), they should do address claiming and other should change to next free source (23). If your device does not respond to any requests, it is possible that your rx line is broken between tranceiver and CAN controller.
I changed it to NMEA2000.SetMode (tNMEA2000 :: N2km_ListenAndNode, 22) and found that Actisense only reads the ISO if before I opened the IDE's serial monitor, now I connected the MCP2515 and I didn't have the CAN H / CAN L signal checking with the oscilloscope . My card is 8mhz and the connection is:
As I mentioned earlier, you must have clock set selection on your code, since default is 16. I also prefer to define bigger read buffer and use interrupt for reading. So wire module INT to e.g. pin 21 and put to the beginning:
remove #include
Good afternoon Timo, first of all thank you very much for the help / class you gave me, I managed to send the data from the Arduino Mega to the Garmin via N2k. My doubt now is if I could install a second MCP2515 on my arduino mega including a second CS port, so I would be able to read the CAN network data from the engine. In the libraries I searched I found Coryfowler's that has a DUAL CAN example:
// Demo: Dual CAN-BUS Shields, Data Pass-through // Written by: Cory J. Fowler // January 31st 2014 // This examples the ability of this library to support more than one MCP2515 based CAN interface.
unsigned long rxId; byte len; byte rxBuf[8];
byte txBuf0[] = {AA,55,AA,55,AA,55,AA,55}; byte txBuf1[] = {55,AA,55,AA,55,AA,55,AA};
MCP_CAN CAN0(10); // CAN0 interface usins CS on digital pin 10 MCP_CAN CAN1(9); // CAN1 interface using CS on digital pin 9
void setup() { Serial.begin(115200);
// init CAN0 bus, baudrate: 250k@16MHz if(CAN0.begin(MCP_EXT, CAN_250KBPS, MCP_16MHZ) == CAN_OK){ Serial.print("CAN0: Init OK!\r\n"); CAN0.setMode(MCP_NORMAL); } else Serial.print("CAN0: Init Fail!!!\r\n");
// init CAN1 bus, baudrate: 250k@16MHz if(CAN1.begin(MCP_EXT, CAN_250KBPS, MCP_16MHZ) == CAN_OK){ Serial.print("CAN1: Init OK!\r\n"); CAN1.setMode(MCP_NORMAL); } else Serial.print("CAN1: Init Fail!!!\r\n");
SPI.setClockDivider(SPI_CLOCK_DIV2); // Set SPI to run at 8MHz (16MHz / 2 = 8 MHz)
CAN0.sendMsgBuf(0x1000000, 1, 8, tx0Buf); CAN1.sendMsgBuf(0x1000001, 1, 8, tx1Buf); }
void loop(){
if(!digitalRead(2)){ // If pin 2 is low, read CAN0 receive buffer
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
CAN1.sendMsgBuf(rxId, 1, len, rxBuf); // Immediately send message out CAN1 interface
}
if(!digitalRead(3)){ // If pin 3 is low, read CAN1 receive buffer
CAN1.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
CAN0.sendMsgBuf(rxId, 1, len, rxBuf); // Immediately send message out CAN0 interface
}
}
/***** END FILE
Unfortunately with current code it is not possible. You can have ESP32 and use internal CAN and external mcp_can as second. Or why not use Teensy 3.6 or Teensy 4? They have two internal CAN controller.
I'm using a board with an ESP32-WROOM-32U, 16MB module. My FW is an N2K projet using this code and also the companion NMEA2000 library (although a version from last November). Upon initial power up, my FW runs beautifully for days. However, often after a soft reset the library will receive invalid PGNs.
I see there is a fix related to this here and I verified I am using this code, with that fix. I checked Mr. Barth's driver on GitHub and it has not been updated in 3 years.
I realize this code has been in circulation quite a while but could there be a similar problem? I have searched, but of course its very hard to Google a term with the word "can" in it.