I am developing a CAN bus information extractor. I am using the Seeeduino CAN Bus v2.0 Shield with their library. The idea is that you plug it into a self-developed battery, and it pulls out all the data. I already have this working. I am sending certain CAN messages with a unique ID, and the BMS (Battery Management System) responds with the information. The problem starts when the BMS enters some kind of sleep mode. After that, my program is not able to SEND messages. byte sndStat = CAN.sendMsgBuf(id, 1, 8, stmp); returns false.
If I also connect my PeakCAN analyzer to the system, it immediately sends information on the bus. Then the BMS also responds. So the BMS does wake up to the messages. After the BMS is woken up, I can just plug in my analyzer, and it works on its own. So I think the problem is that the library/CAN.sendMsgBuf function checks/polls the bus. And if the bus is asleep, it does not recognize it, and therefore it doesn't send a message. Can I somehow overwrite this? For example, I can just send messages with the PeakCAN analyzer even if it is not connected to any bus.
This is the piece of code where I send my messages:
if (currentTime - lastMsgTime >= sendInterval) {
// Hier plaats je de code om het bericht te verzenden
unsigned long id = messageIDs[currentMsgIndex];
byte stmp[8] = {0}; // Voorbeeld gegevens
Serial.println(millis());
byte sndStat = CAN.sendMsgBuf(id, 1, 8, stmp); // Voorbeeld van een bericht
Serial.println(millis());
if (sndStat == CAN_OK) {
Serial.print("Message sent successfully with ID: 0x");
Serial.println(id, HEX);
} else {
Serial.print("Error sending message with ID: 0x");
Serial.println(id, HEX);
}
lastMsgTime = currentTime; // Bijwerken van de tijd van het laatste verzonden bericht
// Verhogen van de huidige berichtindex
currentMsgIndex++;
if (currentMsgIndex >= numMessages) {
currentMsgIndex = 0; // Terug naar het eerste bericht
}
}
The PeakCan does not have a 120 ohm termination resistor. The seeeduino shield does have it. So if I connect my seeeduino shield I measure 63 ohm. (The BMS has a weird resistor value of 137 ohm). I could remove the resistor on my seeeduino. But right now it is actually what it should be. The thing is that I am unable to send a message on the bus with the seeeduino. But with their CAN connection and with the peakcan I am able to send a message. I don't really understand why that is the case?
I also have a usb can tool of the BMS. I started with hooking up my Pcan usb to it to monitor the messages. It just sends the message I am also trying to send to the BMS. But the seeeduino gets an error/false when trying it.
If I print sndStat it gives the value 7. In an other forum I saw it equals to CAN_SENDMSGTIMEOUT. But I don't really know what to change. Because everything works fine when the BMS is awake/active.
You may need to send a special "wake up pattern" (WUP).
It's complicated. Have a read of this document.
I don't know if this will be possible with your shield.
Can you help me understand when a canbus network is "active". Because when I add a node. (for example the) peakcan usb the seeeduino does send the data. Before I thought that a node does not really establish communication. It just sends/drops data on the bus and then an other node can do something with it, or not and just leaves it. But with that thought nothing really changes between adding the node/peakcan usb. Or just connecting my shield directly to the BMS. the termination resistors stay the same.
Using an oscilloscope, if you see data on the CAN High and Low lines then the bus is 'active'.
If one node sends a message and no other devices respond with an ACK then the sending node will keep sending the same message forever. You may be seeing this behavior if the sleeping node does not wake up and send an ACK.
See if this helps:
When the BMS controller is in sleep mode, it can be awakened via the CAN bus to transition into normal operating mode. In such cases, the BMS requires constant power, and the CAN transceiver chip in the BMS controller must have bus wake-up functionality. Several chip suppliers, such as NXP, TI, Infineon, have developed chips with bus wake-up capabilities. Check the link in post by @mikb55#2
Maybe I am missing something fundamental. But the BMS wakes up if there is activity on the bus. Any activity is good, but because my seeeduino canbus shield and the BMS are the only ones on the bus the seeeduino cannot send a message on the bus. If it just drops a message there then the BMS wakes up. Basically a message are just high/low signals. Why can't the shield just output the message as a "dumb" device.
you probably need to use 'one-shot mode' to wake up the BMS, feature which, quickly skimming thru the seedduino library, does not seem to have been implemented.