Weird CANbus results... deconstructor for struct() required?

I am spending now a week of long days to tame a BMS (battery mgmt system), which is the weirdest thing I have experienced.
I see results when I use all functions in loop(); I use one and don' t use the others, I get no results. I have taken lines of code and put them in a function and will not get the output I had previously. Lots of strange things. While I have posted the program, there are many Serial.print() statements to get to the bottom of this (what I now call) nonsense.
There is some commentary in the program below, listing these issues.

Below is the output of one CAN response containing four 2-byte values, battery Volt, acquisition Volt (don't care, can't explain what this value means), current and state of charge (SoC). The battery is continuous discharged at a fixed 700 W. However, the current seems to wobble form negative to zero to charging and back.
I only noticed this when outputting this CAN response only.
I can't explain why this is so.

[edit] I just installed the Bluetooth app for this BMS, and it does the same wobble; not as prominent, because the update frequency is lower. So, I'd say no focus required on this issue. :slight_smile:
[/edit]

Ready to query BMS ... v0.1.2
Compiled at: Aug 20 2024, 21:48:52
MsgID 90 sent (1) -->  | 02 | 0F | 00 | 00 | 74 | D9 | 03 | 9F | 527|29913|927 | Battery is discharging | 52.7 V | -8.7 A | 92.7 %
MsgID 90 sent (2) -->  | 02 | 0F | 00 | 00 | 74 | FD | 03 | 9F | 527|29949|927 | Battery is discharging | 52.7 V | -5.1 A | 92.7 %
MsgID 90 sent (3) -->  | 02 | 0F | 00 | 00 | 75 | 1F | 03 | 9F | 527|29983|927 | Battery is discharging | 52.7 V | -1.7 A | 92.7 %
MsgID 90 sent (4) -->  | 02 | 0F | 00 | 00 | 75 | 34 | 03 | 9F | 527|30004|927 | Battery is charging | 52.7 V | 0.4 A | 92.7 %
MsgID 90 sent (5) -->  | 02 | 0F | 00 | 00 | 75 | 3B | 03 | 9F | 527|30011|927 | Battery is charging | 52.7 V | 1.1 A | 92.7 %
MsgID 90 sent (6) -->  | 02 | 0F | 00 | 00 | 75 | 2E | 03 | 9F | 527|29998|927 | Battery is discharging | 52.7 V | -0.2 A | 92.7 %
MsgID 90 sent (7) -->  | 02 | 0F | 00 | 00 | 75 | 16 | 03 | 9F | 527|29974|927 | Battery is discharging | 52.7 V | -2.6 A | 92.7 %
MsgID 90 sent (8) -->  | 02 | 0F | 00 | 00 | 75 | 08 | 03 | 9F | 527|29960|927 | Battery is discharging | 52.7 V | -4.0 A | 92.7 %
MsgID 90 sent (9) -->  | 02 | 0F | 00 | 00 | 74 | FF | 03 | 9F | 527|29951|927 | Battery is discharging | 52.7 V | -4.9 A | 92.7 %
MsgID 90 sent (10) -->  | 02 | 0F | 00 | 00 | 74 | FE | 03 | 9F | 527|29950|927 | Battery is discharging | 52.7 V | -5.0 A | 92.7 %
MsgID 90 sent (11) -->  | 02 | 0F | 00 | 00 | 74 | FC | 03 | 9F | 527|29948|927 | Battery is discharging | 52.7 V | -5.2 A | 92.7 %
MsgID 90 sent (12) -->  | 02 | 0F | 00 | 00 | 74 | FB | 03 | 9F | 527|29947|927 | Battery is discharging | 52.7 V | -5.3 A | 92.7 %
MsgID 90 sent (13) -->  | 02 | 0F | 00 | 00 | 74 | FB | 03 | 9F | 527|29947|927 | Battery is discharging | 52.7 V | -5.3 A | 92.7 %
MsgID 90 sent (14) -->  | 02 | 0F | 00 | 00 | 74 | F3 | 03 | 9F | 527|29939|927 | Battery is discharging | 52.7 V | -6.1 A | 92.7 %
MsgID 90 sent (15) -->  | 02 | 0F | 00 | 00 | 74 | E1 | 03 | 9F | 527|29921|927 | Battery is discharging | 52.7 V | -7.9 A | 92.7 %
MsgID 90 sent (16) -->  | 02 | 0F | 00 | 00 | 74 | CC | 03 | 9F | 527|29900|927 | Battery is discharging | 52.7 V | -10.0 A | 92.7 %
MsgID 90 sent (17) -->  | 02 | 0F | 00 | 00 | 74 | BF | 03 | 9F | 527|29887|927 | Battery is discharging | 52.7 V | -11.3 A | 92.7 %
MsgID 90 sent (18) -->  | 02 | 0F | 00 | 00 | 74 | C4 | 03 | 9F | 527|29892|927 | Battery is discharging | 52.7 V | -10.8 A | 92.7 %
MsgID 90 sent (19) -->  | 02 | 0F | 00 | 00 | 74 | C8 | 03 | 9F | 527|29896|927 | Battery is discharging | 52.7 V | -10.4 A | 92.7 %
MsgID 90 sent (20) -->  | 02 | 0F | 00 | 00 | 74 | C3 | 03 | 9F | 527|29891|927 | Battery is discharging | 52.7 V | -10.9 A | 92.7 %
MsgID 90 sent (21) -->  | 02 | 0F | 00 | 00 | 74 | C7 | 03 | 9F | 527|29895|927 | Battery is discharging | 52.7 V | -10.5 A | 92.7 %
MsgID 90 sent (22) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %
MsgID 90 sent (23) -->  | 02 | 0F | 00 | 00 | 74 | CF | 03 | 9F | 527|29903|927 | Battery is discharging | 52.7 V | -9.7 A | 92.7 %
MsgID 90 sent (24) -->  | 02 | 0F | 00 | 00 | 74 | DA | 03 | 9F | 527|29914|927 | Battery is discharging | 52.7 V | -8.6 A | 92.7 %
MsgID 90 sent (25) -->  | 02 | 0F | 00 | 00 | 74 | E3 | 03 | 9F | 527|29923|927 | Battery is discharging | 52.7 V | -7.7 A | 92.7 %
MsgID 90 sent (26) -->  | 02 | 0F | 00 | 00 | 74 | EA | 03 | 9F | 527|29930|927 | Battery is discharging | 52.7 V | -7.0 A | 92.7 %
MsgID 90 sent (27) -->  | 02 | 0F | 00 | 00 | 74 | F9 | 03 | 9F | 527|29945|927 | Battery is discharging | 52.7 V | -5.5 A | 92.7 %
MsgID 90 sent (28) -->  | 02 | 0F | 00 | 00 | 75 | 0F | 03 | 9F | 527|29967|927 | Battery is discharging | 52.7 V | -3.3 A | 92.7 %
MsgID 90 sent (29) -->  | 02 | 0F | 00 | 00 | 75 | 1E | 03 | 9F | 527|29982|927 | Battery is discharging | 52.7 V | -1.8 A | 92.7 %
MsgID 90 sent (30) -->  | 02 | 0F | 00 | 00 | 75 | 2B | 03 | 9F | 527|29995|927 | Battery is discharging | 52.7 V | -0.5 A | 92.7 %
MsgID 90 sent (31) -->  | 02 | 0F | 00 | 00 | 75 | 36 | 03 | 9F | 527|30006|927 | Battery is charging | 52.7 V | 0.6 A | 92.7 %
MsgID 90 sent (32) -->  | 02 | 0F | 00 | 00 | 75 | 3D | 03 | 9F | 527|30013|927 | Battery is charging | 52.7 V | 1.3 A | 92.7 %
MsgID 90 sent (33) -->  | 02 | 0F | 00 | 00 | 75 | 24 | 03 | 9F | 527|29988|927 | Battery is discharging | 52.7 V | -1.2 A | 92.7 %
MsgID 90 sent (34) -->  | 02 | 0F | 00 | 00 | 74 | F8 | 03 | 9F | 527|29944|927 | Battery is discharging | 52.7 V | -5.6 A | 92.7 %
MsgID 90 sent (35) -->  | 02 | 0F | 00 | 00 | 74 | D5 | 03 | 9F | 527|29909|927 | Battery is discharging | 52.7 V | -9.1 A | 92.7 %
MsgID 90 sent (36) -->  | 02 | 0F | 00 | 00 | 74 | BF | 03 | 9F | 527|29887|927 | Battery is discharging | 52.7 V | -11.3 A | 92.7 %
MsgID 90 sent (37) -->  | 02 | 0F | 00 | 00 | 74 | C2 | 03 | 9F | 527|29890|927 | Battery is discharging | 52.7 V | -11.0 A | 92.7 %
MsgID 90 sent (38) -->  | 02 | 0F | 00 | 00 | 74 | CD | 03 | 9F | 527|29901|927 | Battery is discharging | 52.7 V | -9.9 A | 92.7 %
MsgID 90 sent (39) -->  | 02 | 0F | 00 | 00 | 74 | CD | 03 | 9F | 527|29901|927 | Battery is discharging | 52.7 V | -9.9 A | 92.7 %
MsgID 90 sent (40) -->  | 02 | 0F | 00 | 00 | 74 | CC | 03 | 9F | 527|29900|927 | Battery is discharging | 52.7 V | -10.0 A | 92.7 %
MsgID 90 sent (41) -->  | 02 | 0F | 00 | 00 | 74 | CE | 03 | 9F | 527|29902|927 | Battery is discharging | 52.7 V | -9.8 A | 92.7 %
MsgID 90 sent (42) -->  | 02 | 0F | 00 | 00 | 74 | D3 | 03 | 9F | 527|29907|927 | Battery is discharging | 52.7 V | -9.3 A | 92.7 %
MsgID 90 sent (43) -->  | 02 | 0F | 00 | 00 | 74 | D3 | 03 | 9F | 527|29907|927 | Battery is discharging | 52.7 V | -9.3 A | 92.7 %
MsgID 90 sent (44) -->  | 02 | 0F | 00 | 00 | 74 | DC | 03 | 9F | 527|29916|927 | Battery is discharging | 52.7 V | -8.4 A | 92.7 %
MsgID 90 sent (45) -->  | 02 | 0F | 00 | 00 | 74 | E3 | 03 | 9F | 527|29923|927 | Battery is discharging | 52.7 V | -7.7 A | 92.7 %
MsgID 90 sent (46) -->  | 02 | 0F | 00 | 00 | 74 | EB | 03 | 9F | 527|29931|927 | Battery is discharging | 52.7 V | -6.9 A | 92.7 %
MsgID 90 sent (47) -->  | 02 | 0F | 00 | 00 | 74 | F6 | 03 | 9F | 527|29942|927 | Battery is discharging | 52.7 V | -5.8 A | 92.7 %
MsgID 90 sent (48) -->  | 02 | 0F | 00 | 00 | 75 | 03 | 03 | 9F | 527|29955|927 | Battery is discharging | 52.7 V | -4.5 A | 92.7 %
MsgID 90 sent (49) -->  | 02 | 0F | 00 | 00 | 75 | 0E | 03 | 9F | 527|29966|927 | Battery is discharging | 52.7 V | -3.4 A | 92.7 %
MsgID 90 sent (50) -->  | 02 | 0F | 00 | 00 | 75 | 1A | 03 | 9F | 527|29978|927 | Battery is discharging | 52.7 V | -2.2 A | 92.7 %
MsgID 90 sent (51) -->  | 02 | 0F | 00 | 00 | 75 | 21 | 03 | 9F | 527|29985|927 | Battery is discharging | 52.7 V | -1.5 A | 92.7 %
MsgID 90 sent (52) -->  | 02 | 0F | 00 | 00 | 75 | 26 | 03 | 9F | 527|29990|927 | Battery is discharging | 52.7 V | -1.0 A | 92.7 %
MsgID 90 sent (53) -->  | 02 | 0F | 00 | 00 | 75 | 2C | 03 | 9F | 527|29996|927 | Battery is discharging | 52.7 V | -0.4 A | 92.7 %
MsgID 90 sent (54) -->  | 02 | 0F | 00 | 00 | 75 | 31 | 03 | 9F | 527|30001|927 | Battery is charging | 52.7 V | 0.1 A | 92.7 %
MsgID 90 sent (55) -->  | 02 | 0F | 00 | 00 | 75 | 33 | 03 | 9F | 527|30003|927 | Battery is charging | 52.7 V | 0.3 A | 92.7 %
MsgID 90 sent (56) -->  | 02 | 0F | 00 | 00 | 75 | 38 | 03 | 9F | 527|30008|927 | Battery is charging | 52.7 V | 0.8 A | 92.7 %
MsgID 90 sent (57) -->  | 02 | 0F | 00 | 00 | 75 | 38 | 03 | 9F | 527|30008|927 | Battery is charging | 52.7 V | 0.8 A | 92.7 %
MsgID 90 sent (58) -->  | 02 | 0F | 00 | 00 | 75 | 38 | 03 | 9F | 527|30008|927 | Battery is charging | 52.7 V | 0.8 A | 92.7 %
MsgID 90 sent (59) -->  | 02 | 0F | 00 | 00 | 75 | 34 | 03 | 9F | 527|30004|927 | Battery is charging | 52.7 V | 0.4 A | 92.7 %
MsgID 90 sent (60) -->  | 02 | 0F | 00 | 00 | 75 | 36 | 03 | 9F | 527|30006|927 | Battery is charging | 52.7 V | 0.6 A | 92.7 %
MsgID 90 sent (61) -->  | 02 | 0F | 00 | 00 | 75 | 2C | 03 | 9F | 527|29996|927 | Battery is discharging | 52.7 V | -0.4 A | 92.7 %
MsgID 90 sent (62) -->  | 02 | 0F | 00 | 00 | 75 | 1A | 03 | 9F | 527|29978|927 | Battery is discharging | 52.7 V | -2.2 A | 92.7 %
MsgID 90 sent (63) -->  | 02 | 0F | 00 | 00 | 75 | 0A | 03 | 9F | 527|29962|927 | Battery is discharging | 52.7 V | -3.8 A | 92.7 %
MsgID 90 sent (64) -->  | 02 | 0F | 00 | 00 | 74 | F6 | 03 | 9F | 527|29942|927 | Battery is discharging | 52.7 V | -5.8 A | 92.7 %
MsgID 90 sent (65) -->  | 02 | 0F | 00 | 00 | 74 | DD | 03 | 9F | 527|29917|927 | Battery is discharging | 52.7 V | -8.3 A | 92.7 %
MsgID 90 sent (66) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %
MsgID 90 sent (67) -->  | 02 | 0F | 00 | 00 | 74 | BA | 03 | 9F | 527|29882|927 | Battery is discharging | 52.7 V | -11.8 A | 92.7 %
MsgID 90 sent (68) -->  | 02 | 0F | 00 | 00 | 74 | C0 | 03 | 9F | 527|29888|927 | Battery is discharging | 52.7 V | -11.2 A | 92.7 %
MsgID 90 sent (69) -->  | 02 | 0F | 00 | 00 | 74 | BD | 03 | 9F | 527|29885|927 | Battery is discharging | 52.7 V | -11.5 A | 92.7 %
MsgID 90 sent (70) -->  | 02 | 0F | 00 | 00 | 74 | BF | 03 | 9F | 527|29887|927 | Battery is discharging | 52.7 V | -11.3 A | 92.7 %
MsgID 90 sent (71) -->  | 02 | 0F | 00 | 00 | 74 | C0 | 03 | 9F | 527|29888|927 | Battery is discharging | 52.7 V | -11.2 A | 92.7 %
MsgID 90 sent (72) -->  | 02 | 0F | 00 | 00 | 74 | C5 | 03 | 9F | 527|29893|927 | Battery is discharging | 52.7 V | -10.7 A | 92.7 %
MsgID 90 sent (73) -->  | 02 | 0F | 00 | 00 | 74 | C6 | 03 | 9F | 527|29894|927 | Battery is discharging | 52.7 V | -10.6 A | 92.7 %
MsgID 90 sent (74) -->  | 02 | 0F | 00 | 00 | 74 | CD | 03 | 9F | 527|29901|927 | Battery is discharging | 52.7 V | -9.9 A | 92.7 %
MsgID 90 sent (75) -->  | 02 | 0F | 00 | 00 | 74 | CD | 03 | 9F | 527|29901|927 | Battery is discharging | 52.7 V | -9.9 A | 92.7 %
MsgID 90 sent (76) -->  | 02 | 0F | 00 | 00 | 74 | CB | 03 | 9F | 527|29899|927 | Battery is discharging | 52.7 V | -10.1 A | 92.7 %
MsgID 90 sent (77) -->  | 02 | 0F | 00 | 00 | 74 | CD | 03 | 9F | 527|29901|927 | Battery is discharging | 52.7 V | -9.9 A | 92.7 %
MsgID 90 sent (78) -->  | 02 | 0F | 00 | 00 | 74 | D7 | 03 | 9F | 527|29911|927 | Battery is discharging | 52.7 V | -8.9 A | 92.7 %
MsgID 90 sent (79) -->  | 02 | 0F | 00 | 00 | 74 | DA | 03 | 9F | 527|29914|927 | Battery is discharging | 52.7 V | -8.6 A | 92.7 %
MsgID 90 sent (80) -->  | 02 | 0F | 00 | 00 | 74 | DB | 03 | 9F | 527|29915|927 | Battery is discharging | 52.7 V | -8.5 A | 92.7 %
MsgID 90 sent (81) -->  | 02 | 0F | 00 | 00 | 74 | E0 | 03 | 9F | 527|29920|927 | Battery is discharging | 52.7 V | -8.0 A | 92.7 %
MsgID 90 sent (82) -->  | 02 | 0F | 00 | 00 | 74 | E0 | 03 | 9F | 527|29920|927 | Battery is discharging | 52.7 V | -8.0 A | 92.7 %
MsgID 90 sent (83) -->  | 02 | 0F | 00 | 00 | 74 | E5 | 03 | 9F | 527|29925|927 | Battery is discharging | 52.7 V | -7.5 A | 92.7 %
MsgID 90 sent (84) -->  | 02 | 0F | 00 | 00 | 74 | E4 | 03 | 9F | 527|29924|927 | Battery is discharging | 52.7 V | -7.6 A | 92.7 %
MsgID 90 sent (85) -->  | 02 | 0F | 00 | 00 | 74 | E6 | 03 | 9F | 527|29926|927 | Battery is discharging | 52.7 V | -7.4 A | 92.7 %
MsgID 90 sent (86) -->  | 02 | 0F | 00 | 00 | 74 | E8 | 03 | 9F | 527|29928|927 | Battery is discharging | 52.7 V | -7.2 A | 92.7 %
MsgID 90 sent (87) -->  | 02 | 0F | 00 | 00 | 74 | EF | 03 | 9F | 527|29935|927 | Battery is discharging | 52.7 V | -6.5 A | 92.7 %
MsgID 90 sent (88) -->  | 02 | 0F | 00 | 00 | 74 | F6 | 03 | 9F | 527|29942|927 | Battery is discharging | 52.7 V | -5.8 A | 92.7 %
MsgID 90 sent (89) -->  | 02 | 0F | 00 | 00 | 74 | FD | 03 | 9F | 527|29949|927 | Battery is discharging | 52.7 V | -5.1 A | 92.7 %
MsgID 90 sent (90) -->  | 02 | 0F | 00 | 00 | 75 | 02 | 03 | 9F | 527|29954|927 | Battery is discharging | 52.7 V | -4.6 A | 92.7 %
MsgID 90 sent (91) -->  | 02 | 0F | 00 | 00 | 75 | 07 | 03 | 9F | 527|29959|927 | Battery is discharging | 52.7 V | -4.1 A | 92.7 %
MsgID 90 sent (92) -->  | 02 | 0F | 00 | 00 | 75 | 11 | 03 | 9F | 527|29969|927 | Battery is discharging | 52.7 V | -3.1 A | 92.7 %
MsgID 90 sent (93) -->  | 02 | 0F | 00 | 00 | 75 | 1E | 03 | 9F | 527|29982|927 | Battery is discharging | 52.7 V | -1.8 A | 92.7 %
MsgID 90 sent (94) -->  | 02 | 0F | 00 | 00 | 75 | 26 | 03 | 9F | 527|29990|927 | Battery is discharging | 52.7 V | -1.0 A | 92.7 %
MsgID 90 sent (95) -->  | 02 | 0F | 00 | 00 | 75 | 2E | 03 | 9F | 527|29998|927 | Battery is discharging | 52.7 V | -0.2 A | 92.7 %
MsgID 90 sent (96) -->  | 02 | 0F | 00 | 00 | 75 | 35 | 03 | 9F | 527|30005|927 | Battery is charging | 52.7 V | 0.5 A | 92.7 %
MsgID 90 sent (97) -->  | 02 | 0F | 00 | 00 | 75 | 38 | 03 | 9F | 527|30008|927 | Battery is charging | 52.7 V | 0.8 A | 92.7 %
MsgID 90 sent (98) -->  | 02 | 0F | 00 | 00 | 75 | 3C | 03 | 9F | 527|30012|927 | Battery is charging | 52.7 V | 1.2 A | 92.7 %
MsgID 90 sent (99) -->  | 02 | 0F | 00 | 00 | 75 | 3B | 03 | 9F | 527|30011|927 | Battery is charging | 52.7 V | 1.1 A | 92.7 %
MsgID 90 sent (100) -->  | 02 | 0F | 00 | 00 | 75 | 30 | 03 | 9F | 527|30000|927 | Battery is discharging | 52.7 V | 0.0 A | 92.7 %
MsgID 90 sent (101) -->  | 02 | 0F | 00 | 00 | 75 | 2B | 03 | 9F | 527|29995|927 | Battery is discharging | 52.7 V | -0.5 A | 92.7 %
MsgID 90 sent (102) -->  | 02 | 0F | 00 | 00 | 75 | 1C | 03 | 9F | 527|29980|927 | Battery is discharging | 52.7 V | -2.0 A | 92.7 %
MsgID 90 sent (103) -->  | 02 | 0F | 00 | 00 | 75 | 15 | 03 | 9F | 527|29973|927 | Battery is discharging | 52.7 V | -2.7 A | 92.7 %
MsgID 90 sent (104) -->  | 02 | 0F | 00 | 00 | 75 | 0E | 03 | 9F | 527|29966|927 | Battery is discharging | 52.7 V | -3.4 A | 92.7 %
MsgID 90 sent (105) -->  | 02 | 0F | 00 | 00 | 75 | 03 | 03 | 9F | 527|29955|927 | Battery is discharging | 52.7 V | -4.5 A | 92.7 %
MsgID 90 sent (106) -->  | 02 | 0F | 00 | 00 | 74 | FA | 03 | 9F | 527|29946|927 | Battery is discharging | 52.7 V | -5.4 A | 92.7 %
MsgID 90 sent (107) -->  | 02 | 0F | 00 | 00 | 74 | EB | 03 | 9F | 527|29931|927 | Battery is discharging | 52.7 V | -6.9 A | 92.7 %
MsgID 90 sent (108) -->  | 02 | 0F | 00 | 00 | 74 | E0 | 03 | 9F | 527|29920|927 | Battery is discharging | 52.7 V | -8.0 A | 92.7 %
MsgID 90 sent (109) -->  | 02 | 0F | 00 | 00 | 74 | D0 | 03 | 9F | 527|29904|927 | Battery is discharging | 52.7 V | -9.6 A | 92.7 %
MsgID 90 sent (110) -->  | 02 | 0F | 00 | 00 | 74 | C2 | 03 | 9F | 527|29890|927 | Battery is discharging | 52.7 V | -11.0 A | 92.7 %
MsgID 90 sent (111) -->  | 02 | 0F | 00 | 00 | 74 | C1 | 03 | 9F | 527|29889|927 | Battery is discharging | 52.7 V | -11.1 A | 92.7 %
MsgID 90 sent (112) -->  | 02 | 0F | 00 | 00 | 74 | C1 | 03 | 9F | 527|29889|927 | Battery is discharging | 52.7 V | -11.1 A | 92.7 %
MsgID 90 sent (113) -->  | 02 | 0F | 00 | 00 | 74 | C6 | 03 | 9F | 527|29894|927 | Battery is discharging | 52.7 V | -10.6 A | 92.7 %
MsgID 90 sent (114) -->  | 02 | 0F | 00 | 00 | 74 | C8 | 03 | 9F | 527|29896|927 | Battery is discharging | 52.7 V | -10.4 A | 92.7 %
MsgID 90 sent (115) -->  | 02 | 0F | 00 | 00 | 74 | C5 | 03 | 9F | 527|29893|927 | Battery is discharging | 52.7 V | -10.7 A | 92.7 %
MsgID 90 sent (116) -->  | 02 | 0F | 00 | 00 | 74 | C4 | 03 | 9F | 527|29892|927 | Battery is discharging | 52.7 V | -10.8 A | 92.7 %
MsgID 90 sent (117) -->  | 02 | 0F | 00 | 00 | 74 | C4 | 03 | 9F | 527|29892|927 | Battery is discharging | 52.7 V | -10.8 A | 92.7 %
MsgID 90 sent (118) -->  | 02 | 0F | 00 | 00 | 74 | CE | 03 | 9F | 527|29902|927 | Battery is discharging | 52.7 V | -9.8 A | 92.7 %
MsgID 90 sent (119) -->  | 02 | 0F | 00 | 00 | 74 | CB | 03 | 9F | 527|29899|927 | Battery is discharging | 52.7 V | -10.1 A | 92.7 %
MsgID 90 sent (120) -->  | 02 | 0F | 00 | 00 | 74 | CE | 03 | 9F | 527|29902|927 | Battery is discharging | 52.7 V | -9.8 A | 92.7 %
MsgID 90 sent (121) -->  | 02 | 0F | 00 | 00 | 74 | D9 | 03 | 9F | 527|29913|927 | Battery is discharging | 52.7 V | -8.7 A | 92.7 %
MsgID 90 sent (122) -->  | 02 | 0F | 00 | 00 | 74 | F0 | 03 | 9F | 527|29936|927 | Battery is discharging | 52.7 V | -6.4 A | 92.7 %
MsgID 90 sent (123) -->  | 02 | 0F | 00 | 00 | 75 | 0C | 03 | 9F | 527|29964|927 | Battery is discharging | 52.7 V | -3.6 A | 92.7 %
MsgID 90 sent (124) -->  | 02 | 0F | 00 | 00 | 75 | 22 | 03 | 9F | 527|29986|927 | Battery is discharging | 52.7 V | -1.4 A | 92.7 %
MsgID 90 sent (125) -->  | 02 | 0F | 00 | 00 | 75 | 2E | 03 | 9F | 527|29998|927 | Battery is discharging | 52.7 V | -0.2 A | 92.7 %
MsgID 90 sent (126) -->  | 02 | 0F | 00 | 00 | 75 | 3A | 03 | 9F | 527|30010|927 | Battery is charging | 52.7 V | 1.0 A | 92.7 %
MsgID 90 sent (127) -->  | 02 | 0F | 00 | 00 | 75 | 3C | 03 | 9F | 527|30012|927 | Battery is charging | 52.7 V | 1.2 A | 92.7 %
MsgID 90 sent (128) -->  | 02 | 0F | 00 | 00 | 75 | 2A | 03 | 9F | 527|29994|927 | Battery is discharging | 52.7 V | -0.6 A | 92.7 %
MsgID 90 sent (129) -->  | 02 | 0F | 00 | 00 | 75 | 05 | 03 | 9F | 527|29957|927 | Battery is discharging | 52.7 V | -4.3 A | 92.7 %
MsgID 90 sent (130) -->  | 02 | 0F | 00 | 00 | 74 | DE | 03 | 9F | 527|29918|927 | Battery is discharging | 52.7 V | -8.2 A | 92.7 %
MsgID 90 sent (131) -->  | 02 | 0F | 00 | 00 | 74 | C2 | 03 | 9F | 527|29890|927 | Battery is discharging | 52.7 V | -11.0 A | 92.7 %
MsgID 90 sent (132) -->  | 02 | 0F | 00 | 00 | 74 | BD | 03 | 9F | 527|29885|927 | Battery is discharging | 52.7 V | -11.5 A | 92.7 %
MsgID 90 sent (133) -->  | 02 | 0F | 00 | 00 | 74 | CA | 03 | 9F | 527|29898|927 | Battery is discharging | 52.7 V | -10.2 A | 92.7 %
MsgID 90 sent (134) -->  | 02 | 0F | 00 | 00 | 74 | D2 | 03 | 9F | 527|29906|927 | Battery is discharging | 52.7 V | -9.4 A | 92.7 %
MsgID 90 sent (135) -->  | 02 | 0F | 00 | 00 | 74 | E8 | 03 | 9F | 527|29928|927 | Battery is discharging | 52.7 V | -7.2 A | 92.7 %
MsgID 90 sent (136) -->  | 02 | 0F | 00 | 00 | 75 | 0C | 03 | 9F | 527|29964|927 | Battery is discharging | 52.7 V | -3.6 A | 92.7 %
MsgID 90 sent (137) -->  | 02 | 0F | 00 | 00 | 75 | 2A | 03 | 9F | 527|29994|927 | Battery is discharging | 52.7 V | -0.6 A | 92.7 %
MsgID 90 sent (138) -->  | 02 | 0F | 00 | 00 | 75 | 3A | 03 | 9F | 527|30010|927 | Battery is charging | 52.7 V | 1.0 A | 92.7 %
MsgID 90 sent (139) -->  | 02 | 0F | 00 | 00 | 75 | 30 | 03 | 9F | 527|30000|927 | Battery is discharging | 52.7 V | 0.0 A | 92.7 %
MsgID 90 sent (140) -->  | 02 | 0F | 00 | 00 | 74 | FE | 03 | 9F | 527|29950|927 | Battery is discharging | 52.7 V | -5.0 A | 92.7 %
MsgID 90 sent (141) -->  | 02 | 0F | 00 | 00 | 74 | CB | 03 | 9F | 527|29899|927 | Battery is discharging | 52.7 V | -10.1 A | 92.7 %
MsgID 90 sent (142) -->  | 02 | 0F | 00 | 00 | 74 | C4 | 03 | 9F | 527|29892|927 | Battery is discharging | 52.7 V | -10.8 A | 92.7 %
MsgID 90 sent (143) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %
MsgID 90 sent (144) -->  | 02 | 0F | 00 | 00 | 74 | CF | 03 | 9F | 527|29903|927 | Battery is discharging | 52.7 V | -9.7 A | 92.7 %
MsgID 90 sent (145) -->  | 02 | 0F | 00 | 00 | 74 | D1 | 03 | 9F | 527|29905|927 | Battery is discharging | 52.7 V | -9.5 A | 92.7 %
MsgID 90 sent (146) -->  | 02 | 0F | 00 | 00 | 74 | D3 | 03 | 9F | 527|29907|927 | Battery is discharging | 52.7 V | -9.3 A | 92.7 %
MsgID 90 sent (147) -->  | 02 | 0F | 00 | 00 | 74 | DE | 03 | 9F | 527|29918|927 | Battery is discharging | 52.7 V | -8.2 A | 92.7 %
MsgID 90 sent (148) -->  | 02 | 0F | 00 | 00 | 74 | E8 | 03 | 9F | 527|29928|927 | Battery is discharging | 52.7 V | -7.2 A | 92.7 %
MsgID 90 sent (149) -->  | 02 | 0F | 00 | 00 | 74 | F7 | 03 | 9F | 527|29943|927 | Battery is discharging | 52.7 V | -5.7 A | 92.7 %
MsgID 90 sent (150) -->  | 02 | 0F | 00 | 00 | 75 | 06 | 03 | 9F | 527|29958|927 | Battery is discharging | 52.7 V | -4.2 A | 92.7 %
MsgID 90 sent (151) -->  | 02 | 0F | 00 | 00 | 75 | 19 | 03 | 9F | 527|29977|927 | Battery is discharging | 52.7 V | -2.3 A | 92.7 %
MsgID 90 sent (152) -->  | 02 | 0F | 00 | 00 | 75 | 27 | 03 | 9F | 527|29991|927 | Battery is discharging | 52.7 V | -0.9 A | 92.7 %
MsgID 90 sent (153) -->  | 02 | 0F | 00 | 00 | 75 | 31 | 03 | 9F | 527|30001|927 | Battery is charging | 52.7 V | 0.1 A | 92.7 %
MsgID 90 sent (154) -->  | 02 | 0F | 00 | 00 | 75 | 39 | 03 | 9F | 527|30009|927 | Battery is charging | 52.7 V | 0.9 A | 92.7 %
MsgID 90 sent (155) -->  | 02 | 0F | 00 | 00 | 75 | 3B | 03 | 9F | 527|30011|927 | Battery is charging | 52.7 V | 1.1 A | 92.7 %
MsgID 90 sent (156) -->  | 02 | 0F | 00 | 00 | 75 | 23 | 03 | 9F | 527|29987|927 | Battery is discharging | 52.7 V | -1.3 A | 92.7 %
MsgID 90 sent (157) -->  | 02 | 0F | 00 | 00 | 74 | F5 | 03 | 9F | 527|29941|927 | Battery is discharging | 52.7 V | -5.9 A | 92.7 %
MsgID 90 sent (158) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %
MsgID 90 sent (159) -->  | 02 | 0F | 00 | 00 | 74 | BE | 03 | 9F | 527|29886|927 | Battery is discharging | 52.7 V | -11.4 A | 92.7 %
MsgID 90 sent (160) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %
MsgID 90 sent (161) -->  | 02 | 0F | 00 | 00 | 74 | E7 | 03 | 9F | 527|29927|927 | Battery is discharging | 52.7 V | -7.3 A | 92.7 %
MsgID 90 sent (162) -->  | 02 | 0F | 00 | 00 | 75 | 14 | 03 | 9F | 527|29972|927 | Battery is discharging | 52.7 V | -2.8 A | 92.7 %
MsgID 90 sent (163) -->  | 02 | 0F | 00 | 00 | 75 | 2E | 03 | 9F | 527|29998|927 | Battery is discharging | 52.7 V | -0.2 A | 92.7 %
MsgID 90 sent (164) -->  | 02 | 0F | 00 | 00 | 75 | 38 | 03 | 9F | 527|30008|927 | Battery is charging | 52.7 V | 0.8 A | 92.7 %
MsgID 90 sent (165) -->  | 02 | 0F | 00 | 00 | 75 | 21 | 03 | 9F | 527|29985|927 | Battery is discharging | 52.7 V | -1.5 A | 92.7 %
MsgID 90 sent (166) -->  | 02 | 0F | 00 | 00 | 74 | EC | 03 | 9F | 527|29932|927 | Battery is discharging | 52.7 V | -6.8 A | 92.7 %
MsgID 90 sent (167) -->  | 02 | 0F | 00 | 00 | 74 | BE | 03 | 9F | 527|29886|927 | Battery is discharging | 52.7 V | -11.4 A | 92.7 %
MsgID 90 sent (168) -->  | 02 | 0F | 00 | 00 | 74 | BE | 03 | 9F | 527|29886|927 | Battery is discharging | 52.7 V | -11.4 A | 92.7 %
MsgID 90 sent (169) -->  | 02 | 0F | 00 | 00 | 74 | C9 | 03 | 9F | 527|29897|927 | Battery is discharging | 52.7 V | -10.3 A | 92.7 %

Another observation, when outputting three CANbus responses is that seemingly the same MsgId 90 will eventually corrupt and not recover.

[edit] I am referring here to msg ID 90 (sequential number) 394, byte 2 and 3 (when starting at 0); these are 0 and 0. Then look at msg ID 90 at counter 400; now these bytes are 39 and 13. This is what I am trying to figure out as to why it has changed. [/edit]

MsgID 90 sent (394) -->  | 2 | 31 | 0 | 0 | 117 | 91 | 3 | 232 | 543|30043|1000 | Battery is charging | 54.3 V | 4.3 A | 100.0 %
MsgID 91 sent (395) -->  | 3.426 Vmax in cell 8 | 3.357 Vmin in cell 2
MsgID 95 sent (396) -->  | 3363|3355|3361|3414|3364|3361|3419|3423|3414|3401|3377|3403|3412|3422|3419|3422
MsgID 90 sent (397) -->  | 2 | 31 | 0 | 0 | 117 | 24 | 3 | 232 | 543|29976|1000 | Battery is discharging | 54.3 V | -2.4 A | 100.0 %
MsgID 91 sent (398) -->  | 3.421 Vmax in cell 7 | 3.351 Vmin in cell 2
MsgID 95 sent (399) -->  | 3367|3352|3364|3410|3365|3359|3423|3415|3420|3395|3382|3398|3417|3418|3423|3418

MsgID 90 sent (400) -->  | 1 | 13 | 39 | 13 | 24 | 13 | 36 | 0
MsgID 91 sent (401) -->  | 0.525 Vmax in cell 82 | 3.365 Vmin in cell 13
MsgID 95 sent (402) -->  | 3364|3354|3362|3410|3364|3360|3420|3418|3417|3399|3379|3400|3417|3418|3423|3418
MsgID 90 sent (403) -->  | 5 | 13 | 86 | 13 | 92 | 13 | 91 | 0
MsgID 91 sent (404) -->  | 1.549 Vmax in cell 91 | 3.420 Vmin in cell 13
MsgID 95 sent (405) -->  | 3363|3356|3360|3412|3363|3360|3417|3422|3414|3403|3376|3403|3417|3418|3423|3418

By the way: the number in brackets is a msg sent counter.

In the example above, the 'acquisition bytes turn for no reason apparent to me to non-zero, and when this happens, the program does not recover.

Not sure, if anyone is tempted to look at this, but here the code, which is pretty much pattern-ised.
The messageRead() in each function was a necessity because the a single function reading the message and then invoking the relevant 'getter' function would not work; mostly no longer outputting anything.

I am not a programmer, and come from a non-object background; the only thing I could come up with is that maybe the response message frame struct can_frame g_can_response; needs a deconstructor, like a variable.

As I read the mcp2515 library code, readMessage() populates, or overwrites the struct(). At least I can't see where it might be reset/deleted/emptied/nullified?!
Maybe this is the cause for all this weird behaviour.

Please note: get_cell_voltages, works differently. It reads 6 consecutive frames from one CANbus data ID; this is weird by itself (I think). Anyway, it does a send_query and then reads a few times to capture the six frames.

Any hints appreciated. Thanks.

The library cane be found here: GitHub - autowp/arduino-mcp2515: Arduino MCP2515 CAN interface library
The program, as below:

/*
    Daly BMS 250 A CAN Interface with Arduino UNO R3
*/
#define CODE_VERSION "0.1.2"
/*
    This does seem to work :)
    ... and is basis for further development

    20240820 MaxG v0.1.2  - testing
    20240820 MaxG v0.1.1  - more reorganising of variables and code, added commentary
                            executing sent_query_msgs_counter() in send_can_query()
                            does not produce output anymore. WTF?
    20240819 MaxG v0.0.3  - code is working; delay() in loop() will kill it
    20240813 MaxG v0.0.1  - PoC on Arduino UNO R3 (PlatformIO)

    How it works:
    setup(): init serial, init MCP2515
    loop(): e.g., get cell voltages
    get_can_data(():
    - send CAN request
    send_can_data():
    - do while(read CAN message)
    - if read call respective data retrieval function
    get_cell_voltages():
    - loop through data
    - output

    get other parameters
    -> loop()

    What it should look like...
    MsgID 90 sent (666) --> Battery is discharging | 54.3 V | 0 | -14.0 A | 97.5 %
    MsgID 91 sent (667) --> max. V = 3.427 mV in cell 10 | min. V = 3.368 mV in cell 2
    MsgID 92 sent (668) --> temp sensor 1 = 23 °C | temp sensor 1 = 23 °C
    MsgID 93 sent (669) --> Charge-discharge flag: 2, charge MOSFET status: 1, discharge MOSFET status: 1, available capacity: 380 Ah
    MsgID 95 sent (670) --> 3365,3374,3366,3416,3377,3380,3376,3433,3385,3437,3394,3424,3385,3402,3380,3408
*/
/*! --------------- Libraries ----------------------------------------------- */
#include <Arduino.h>
#include <mcp2515.h>
#include <SPI.h>

#define G_BAUD_RATE_HW  115200                  // hardware serial baud rate
#define G_PIN_CAN_SPI_CS    10                  // CS (Chip Select) pin
#define G_PIN_CAN_INT        2                  // Set CANbus interrupt to pin 2

struct can_frame g_can_query;
struct can_frame g_can_response;

// 4 bytes: priority, msg id, BMS address, host address
//          18        9n      01           40
enum CAN_DATA_ID
{
    CAN_DATA_ID_BATTERY_PACK_DATA       = 0x90,
    CAN_DATA_ID_MIN_MAX_CELLS           = 0x91,
    CAN_DATA_ID_MIN_MAX_TEMPERATURE     = 0x92,
    CAN_DATA_ID_MOSFET_CHARGE_STATUS    = 0x93,
    CAN_DATA_ID_STATUS_INFO             = 0x94,
    CAN_DATA_ID_CELL_VOLTAGES           = 0x95,
    CAN_DATA_ID_CELL_TEMPERATURES       = 0x96,
    CAN_DATA_ID_CELL_BALANCE_STATUS     = 0x97,
    CAN_DATA_ID_BATTERY_FAILURE_STATUS  = 0x98
};

uint16_t cell_voltages[17] = {0};
uint8_t g_frame_number = 0;
bool b_reading_cell_voltage_frames = 0;
uint8_t g_can_read_msg_return_code = 5;
uint16_t g_can_msg_read_timeout_counter = 0;

MCP2515 mcp2515(G_PIN_CAN_SPI_CS);

/*! --------------- Prototypes ---------------------------------------------- */
uint16_t build_word(uint8_t array_index_low_byte, uint8_t array_index_high_byte);
float convert_int_to_float_with_divisor(int16_t value, int16_t divisor);
void sent_query_msgs_counter(uint8_t data_id);
void loop_counter();
void send_can_query(uint8_t can_query_id);
void get_battery_pack_data();
void get_min_max_cell_voltages();
void get_min_max_temperatures();
void get_mosfet_charge_status();
void get_cell_voltages();


/*! --------------- Function declarations ----------------------------------- */

/*
 * -----------------------------------------------------------------------------
 * @brief Converting two unsigned bytes to one unsigned 16-bit value
 * The byte order is array_index_low_byte first.
 *
 * @param[in] array_index_low_byte is the index of the low byte in the data
 * section of the global CANbus query repsonse (g_can_response)
 *
 * @param[in] array_index_high_byte is the index of the high byte in the data
 * section of the global CANbus query repsonse (g_can_response)
 *
 * @return 16-bit value
 * -----------------------------------------------------------------------------
 */
uint16_t build_word(uint8_t array_index_low_byte, uint8_t array_index_high_byte)
{
    return (g_can_response.data[array_index_low_byte] << 8)
        | g_can_response.data[array_index_high_byte];

}   // build_word()


/*
 * -----------------------------------------------------------------------------
 * @brief Converting signed 16-bit integer to a float and dividing it by the
 * divisor provided.
 * @param[in] 16-bit signed integer
 * @return float
 * -----------------------------------------------------------------------------
 */
float convert_int_to_float_with_divisor(int16_t value, int16_t divisor)
{
    if (divisor == 0)
    {
        return value;
    }

    float return_value = (double)value / divisor;

    return return_value;

}   // convert_int_to_float_with_divisor()


/*
 * -----------------------------------------------------------------------------
 * @brief Counting CANbus queries sent to the BMS.
 * This function was used during development and for debugging purposes.
 * @param[in] CAN data ID
 * -----------------------------------------------------------------------------
 */
void sent_query_msgs_counter(uint8_t data_id)
{
    // 20240820: this function does not work when called; yet has the same
    // lines of code transferred fomr the calling function send_can_query().
    static uint32_t sent_query_msgs_count = 0;

    sent_query_msgs_count++;

    Serial.print("MsgID ");
    Serial.print(data_id, HEX);
    Serial.print(" sent (");
    Serial.print(sent_query_msgs_count);
    Serial.print(") --> ");

    //return;

}   // sent_query_msgs_counter()


/*
 * -----------------------------------------------------------------------------
 * @brief Counting loop() executions
 * This function was used during development and for debugging purposes.
 * -----------------------------------------------------------------------------
 */
void loop_counter()
{
    static uint32_t loop_count = 0;

    loop_count++;

    Serial.print("loop() count = ");
    Serial.println(loop_count);

    return;
}   // loop_counter()


/*
 * -----------------------------------------------------------------------------
 * @brief Sending CANbus queries to the connected battery management system
 * (BMS).
 *
 * Specifications:
 * Byte 0..Byte 7: Reserved (0x00 being submitted to complete the CAN msg
 *
 * @parmam[in] can_query_id; is the CANbus data ID; e.g., the CANbus address
 * (CAN ID) is in the form of Priority + Data ID + BMS Address + host address,
 * like so: 0x18100140, where the 0x00 is replaced with the Data ID (here
 * can_query_id).
 * -----------------------------------------------------------------------------
 */
void send_can_query(uint8_t can_query_id)
{
    switch (can_query_id)
    {
        case CAN_DATA_ID_BATTERY_PACK_DATA:
            g_can_query.can_id  = 0x18900140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_MIN_MAX_CELLS:
            g_can_query.can_id  = 0x18910140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_MIN_MAX_TEMPERATURE:
            g_can_query.can_id  = 0x18920140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_MOSFET_CHARGE_STATUS:
            g_can_query.can_id  = 0x18930140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_STATUS_INFO:
            g_can_query.can_id  = 0x18940140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_CELL_VOLTAGES:
            g_can_query.can_id  = 0x18950140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_CELL_TEMPERATURES:
            g_can_query.can_id  = 0x18960140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_CELL_BALANCE_STATUS:
            g_can_query.can_id  = 0x18970140 | CAN_EFF_FLAG;
        break;

        case CAN_DATA_ID_BATTERY_FAILURE_STATUS:
            g_can_query.can_id  = 0x18980140 | CAN_EFF_FLAG;
        break;
    }

    // DLC = Data Length Code. The DLC field indicates the number of bytes in
    // the data field, ranging (usually) from 0 to 8.
    const uint8_t NUMBER_OF_DATA_FIELDS = 8;

    g_can_query.can_dlc = NUMBER_OF_DATA_FIELDS;

    //for (uint8_t i = 0; i < NUMBER_OF_DATA_FIELDS; i++)
    //{
    //    g_can_query.data[i] = 0x00;
    //}
    g_can_query.data[8] = {0x00};

    //sent_query_msgs_counter(can_query_id);

    static uint32_t sent_counter = 0;
    sent_counter++;

    Serial.print("MsgID ");
    Serial.print(can_query_id, HEX);
    Serial.print(" sent (");
    Serial.print(sent_counter);
    Serial.print(") --> ");

    mcp2515.sendMessage(&g_can_query);

}   // send_can_query()


/*
 * -----------------------------------------------------------------------------
 * @brief Sending a CANbus query message and retrieving SOC, total voltage,
 * current; data ID = 0x90
 *
 * Specifications:
 * Byte 0..Byte 1: Cumulative total voltage (0.1 V)
 * Byte 2..Byte 3: Gather total voltage (0.1 V) => unclear what it represents
 * Byte 4..Byte 5: Current, 30000 Offset (0.1 A)
 * Byte 6..Byte 7: SOC (0.1 %)
 * -----------------------------------------------------------------------------
 */
void get_battery_pack_data()
{
    send_can_query(CAN_DATA_ID_BATTERY_PACK_DATA);

    while ((5 == g_can_read_msg_return_code) && g_can_msg_read_timeout_counter < 5000)
    {
        g_can_msg_read_timeout_counter++;
        g_can_read_msg_return_code = mcp2515.readMessage(&g_can_response);
    }

    if (0 == g_can_read_msg_return_code)
    {
        g_can_msg_read_timeout_counter = 0;

        for (uint8_t i = 0; i < 8; i++)
        {
            Serial.print(" | ");

            if (g_can_response.data[i] < 0x10)
            {
                Serial.print("0");
            }

            Serial.print(g_can_response.data[i], HEX);
        }

        if (0 != g_can_response.data[2])
        {
            g_can_read_msg_return_code = 5;
            return;
        }

        Serial.print(" | ");
        uint16_t battery_voltage = build_word(0, 1);
        Serial.print(battery_voltage);
        Serial.print("|");
/*
        uint16_t acquisition     = build_word(2, 3);
        Serial.print(acquisition);
        Serial.print("|");
*/
        uint16_t battery_current = build_word(4, 5);
        Serial.print(battery_current);
        Serial.print("|");

        uint16_t battery_soc     = build_word(6, 7);
        Serial.print(battery_soc);
        Serial.print(" | ");

        const uint16_t BATTERY_CURRENT_OFFSET = 30000;  // [mA]

        if (battery_current > BATTERY_CURRENT_OFFSET)
        {
            // positive
            Serial.print("Battery is charging | ");
        }
        else
        {
            // negative
            Serial.print("Battery is discharging | ");
        }

        battery_current = battery_current - BATTERY_CURRENT_OFFSET;

        Serial.print(convert_int_to_float_with_divisor(battery_voltage, 10), 1);
        Serial.print(" V | ");

        //Serial.print(acquisition);
        //Serial.print(" | ");

        Serial.print(convert_int_to_float_with_divisor(battery_current, 10), 1);
        Serial.print(" A | ");

        Serial.print(convert_int_to_float_with_divisor(battery_soc, 10), 1);
        Serial.println(" %");

        g_can_read_msg_return_code = 5;
    }
}


/*
 * -----------------------------------------------------------------------------
 * @brief Sending a CANbus query message and retrieving minimum and maximum cell
 * voltage and number; data ID = 0x91
 *
 * Specifications:
 * Byte 0..Byte1: Maximum cell voltage value (mV)
 * Byte 2:        Cell number with maximum voltage
 * Byte 3..byte4: Minimum cell voltage value (mV)
 * Byte 5:        Cell number with minimum voltage
 * -----------------------------------------------------------------------------
 */
void get_min_max_cell_voltages()
{
    send_can_query(CAN_DATA_ID_MIN_MAX_CELLS);

    while ((5 == g_can_read_msg_return_code) && g_can_msg_read_timeout_counter < 5000)
    {
        g_can_msg_read_timeout_counter++;
        g_can_read_msg_return_code = mcp2515.readMessage(&g_can_response);
    }

    if (0 == g_can_read_msg_return_code)
    {
        g_can_msg_read_timeout_counter = 0;

        uint16_t max_cell_voltage   = build_word(0, 1);
        uint8_t max_voltage_in_cell = g_can_response.data[2];
        uint16_t min_cell_voltage   = build_word(3, 4);
        uint8_t min_voltage_in_cell = g_can_response.data[5];

        Serial.print(" | ");
        Serial.print(convert_int_to_float_with_divisor(max_cell_voltage, 1000), 3);
        Serial.print(" Vmax in cell ");
        Serial.print(max_voltage_in_cell);
        Serial.print(" | ");
        Serial.print(convert_int_to_float_with_divisor(min_cell_voltage, 1000), 3);
        Serial.print(" Vmin in cell ");
        Serial.print(min_voltage_in_cell);
        Serial.println();

        g_can_read_msg_return_code = 5;
    }
}


/*
 * -----------------------------------------------------------------------------
 * @brief Retrieving minimum and maximum cell temperature; data ID = 0x92
 * Only top sensors have been connected.
 *
 * Specifications:
 * Byte0: Maximum temperature value (40 Offset, °C)
 * Byte1: Maximum temperature cell number
 * Byte2: Minimum temperature value (40 Offset, °C)
 * Byte3: Minimum temperature cell number
 * -----------------------------------------------------------------------------
 */
void get_min_max_temperatures()
{
    send_can_query(CAN_DATA_ID_MIN_MAX_TEMPERATURE);

    while ((5 == g_can_read_msg_return_code) && g_can_msg_read_timeout_counter < 5000)
    {
        g_can_msg_read_timeout_counter++;
        g_can_read_msg_return_code = mcp2515.readMessage(&g_can_response);
    }

    if (0 == g_can_read_msg_return_code)
    {
        g_can_msg_read_timeout_counter = 0;

        int16_t temperature_sensor_1     = g_can_response.data[0];
        uint16_t temperature_sensor_1_id = g_can_response.data[1];
        int16_t temperature_sensor_2     = g_can_response.data[2];
        uint16_t temperature_sensor_2_id = g_can_response.data[3];

        const uint8_t TEMPERATURE_SENSOR_VALUE_OFFSET = 40;

        temperature_sensor_1 = temperature_sensor_1 - TEMPERATURE_SENSOR_VALUE_OFFSET;
        temperature_sensor_2 = temperature_sensor_2 - TEMPERATURE_SENSOR_VALUE_OFFSET;

        Serial.print(" | ");
        Serial.print("temp sensor ");
        Serial.print(temperature_sensor_1_id);
        Serial.print(" = ");
        Serial.print(temperature_sensor_1);
        Serial.print(" °C | temp sensor ");
        Serial.print(temperature_sensor_2_id);
        Serial.print(" = ");
        Serial.print(temperature_sensor_2);
        Serial.println(" °C");

        g_can_read_msg_return_code = 5;
    }
}


/*
 * -----------------------------------------------------------------------------
 * @brief Sending a CANbus query message and retrieving charge and discharge
 * MOSFET state; data ID = 0x93
 *
 * Specifications:
 * Byte 0: State (0 stationary 1 charge 2 discharge)
 * Byte 1: Charge MOS state
 * Byte 2: Discharge MOS status
 * Byte 3: BMS life (0~255 cycles)
 * Byte 4..Byte 7: Remaining capacity (mAH)
 * -----------------------------------------------------------------------------
 */
void get_mosfet_charge_status()
{
    send_can_query(CAN_DATA_ID_MOSFET_CHARGE_STATUS);  // 0x18930140

    while ((5 == g_can_read_msg_return_code) && g_can_msg_read_timeout_counter < 5000)
    {
        g_can_msg_read_timeout_counter++;
        g_can_read_msg_return_code = mcp2515.readMessage(&g_can_response);
    }

    if (0 == g_can_read_msg_return_code)
    {
        g_can_msg_read_timeout_counter = 0;

        uint8_t charge_discharge    =  g_can_response.data[0];
        uint8_t charge_MOS_STUS     =  g_can_response.data[1];
        uint8_t dischage_MOS_STUS   =  g_can_response.data[2];
        //uint8_t BMS_life            =  g_can_response.data[3];

        // Cast the uint8_t to int32_t before doing the shift
        uint32_t residual_capacity  =
              (uint32_t)g_can_response.data[4] << 24
            | (uint32_t)g_can_response.data[5] << 16
            | (uint32_t)g_can_response.data[6] <<  8
            | (uint32_t)g_can_response.data[7];

        // divide mA by 1,000 bu shifting right 10 bits
        uint32_t amp_hours = residual_capacity >> 10;

        Serial.print(" | ");
        Serial.print("Charge-discharge flag: ");
        Serial.print(charge_discharge);
        Serial.print(", charge MOSFET status: ");
        Serial.print(charge_MOS_STUS);
        Serial.print(", discharge MOSFET status: ");
        Serial.print(dischage_MOS_STUS);

        // not sure what this os good for
        //Serial.print(", BMS life: ");
        //Serial.print(BMS_life);

        Serial.print(", available capacity: ");
        Serial.print(amp_hours);
        Serial.println(" Ah");

        g_can_read_msg_return_code = 5;
    }
}


/*
 * -----------------------------------------------------------------------------
 * @brief Sending a CANbus query message and retrieving cell voltages;
 * data ID = 0x95
 *
 * Specifications:
 * Cell voltage 1~48
 * The voltage of each sensor is 2 byte, according to the actual number of
 * cells. The maximum sent is 96 byte, and is sent in maximum 16 frames.
 * Byte 0: frame number, starting from 0; 0xFF is invalid
 * Byte 1..Byte 6: Cell voltage
 * -----------------------------------------------------------------------------
 */
void get_cell_voltages()
{
    const uint16_t DELAY_POST_VOLTAGES = 2000;

    while ((5 == g_can_read_msg_return_code) && g_can_msg_read_timeout_counter < 5000)
    {
        g_can_msg_read_timeout_counter++;
        g_can_read_msg_return_code = mcp2515.readMessage(&g_can_response);;

        if (g_can_msg_read_timeout_counter >= 5000)
        {
            g_frame_number = 0;
        }
    }

    if (0 == g_can_read_msg_return_code)
    {
        g_can_msg_read_timeout_counter = 0;
        b_reading_cell_voltage_frames = true;
        g_frame_number++;

        uint8_t frame_id = g_can_response.data[0];

        switch (frame_id)
        {
            case 1:
                cell_voltages[1]  = build_word(1, 2);
                cell_voltages[2]  = build_word(3, 4);
                cell_voltages[3]  = build_word(5, 6);
            break;

            case 2:
                cell_voltages[4]  = build_word(1, 2);
                cell_voltages[5]  = build_word(3, 4);
                cell_voltages[6]  = build_word(5, 6);
            break;

            case 3:
                cell_voltages[7]  = build_word(1, 2);
                cell_voltages[8]  = build_word(3, 4);
                cell_voltages[9]  = build_word(5, 6);
            break;

            case 4:
                cell_voltages[10]  = build_word(1, 2);
                cell_voltages[11]  = build_word(3, 4);
                cell_voltages[12]  = build_word(5, 6);
            break;

            case 5:
                cell_voltages[13]  = build_word(1, 2);
                cell_voltages[14]  = build_word(3, 4);
                cell_voltages[15]  = build_word(5, 6);
            break;

            case 6:
                cell_voltages[16] = build_word(1, 2);
            break;
        }

        if (g_frame_number == 6)
        {
            b_reading_cell_voltage_frames = false;

            Serial.print(" | ");

            for (byte i = 1; i < 17; i++)
            {
                Serial.print(cell_voltages[i]);

                if (i != 16)
                {
                    Serial.print("|");
                }

                //if (i == 8) Serial.println();
            }

            g_frame_number = 0;

            Serial.println();

            delay(DELAY_POST_VOLTAGES);
        }

        g_can_read_msg_return_code = 5;
    }
}


/*!
 * -----------------------------------------------------------------------------
 * @brief Setup routine -- runs once
 * -----------------------------------------------------------------------------
 */
void setup()
{
    Serial.begin(G_BAUD_RATE_HW);
    delay(500);

    mcp2515.reset();
    mcp2515.setBitrate(CAN_250KBPS, MCP_8MHZ);
    mcp2515.setNormalMode();

    Serial.print("\nReady to query BMS ... v");
    Serial.println(CODE_VERSION);

    Serial.print("Compiled at: ");
    Serial.print(__DATE__);
    Serial.print(", ");
    Serial.println(__TIME__);
}


/*!
 * -----------------------------------------------------------------------------
 * @brief Loop -- runs continuously
 * -----------------------------------------------------------------------------
 */
void loop()
{
    g_can_read_msg_return_code = 5;
    g_can_msg_read_timeout_counter = 0;

    // all messages but message 5 = battery cell voltages
    if (0 == b_reading_cell_voltage_frames)
    {
        // 20240820-1400: tests
        // any single, no cellVoltage
        // any single, plus any second, we have cellVoltages

        get_battery_pack_data();
        //get_min_max_cell_voltages();
        //get_min_max_temperatures();
        //get_mosfet_charge_status();

        delay(1000);
    }
/*
    if ((0 == g_frame_number) && (0 == b_reading_cell_voltage_frames))
    {
        b_reading_cell_voltage_frames = true;
        send_can_query(CAN_DATA_ID_CELL_VOLTAGES);
    }

    get_cell_voltages();
*/
    // 20240818: disabled loop_counter();
}

// end of file

Just some obervations.
Your receving code assumes that the first message you retreive from the MCP2515 is a response to the query message you just sent, however, the chip has a 2 slot FIFO receive buffer so it's possible that the first message you receive is actually an old message that was sent from the BMS before it received your query.

Secondly your aren't checking the ID of the receiving message so you may be attempting to decode a heartbeat message or some other status message that the BMS is routinely sending.

Perhaps a change of strategy is required. Treat the sending of queries and the receiving of responses as two independent tasks. Use the main loop to continuously poll the MCP2515 for messages and check the ID of each message to see if it needs to be decoded. The continuous polling makes sure that you don't get confused by looking at old data. Secondly use the 'blink without delay' programming example to periodically pause the polling, send a query and then resume polling for incoming messages.

2 Likes

Thank you for your feedback.

Yes... I now realise (and I apologise) that I have forgotten to mention that this BMS communication differs from (what I perceive as) 'normal' CANbus behaviour, due to the BMS not sending any messages at all, unless it is being queried. This means I have to send a query, in order to get a response... hence the (weird) structure of the program.

In this case, I literally have to send a query for, say, 0x90, to get the 0x90 response; otherwise it is 'quiet' on the bus. This did my head in initially, as I was listening and nothing happened.

Correct, because, as per above, there will be only this (as in the queried) message in the read buffer.

BTW: querying only msg ID 0x90 since I posted initially, I have received almost 30,000 messages without fail.

29727692 | MsgID 90 sent (29440) -->  | 02 | 0B | 00 | 00 | 74 | BC | 02 | D9 | 523|29884|729 | Battery is discharging | 52.3 V | -11.6 A | 72.9 %
29728700 | MsgID 90 sent (29441) -->  | 02 | 0B | 00 | 00 | 74 | D8 | 02 | D9 | 523|29912|729 | Battery is discharging | 52.3 V | -8.8 A | 72.9 %
29729707 | MsgID 90 sent (29442) -->  | 02 | 0B | 00 | 00 | 75 | 0A | 02 | D9 | 523|29962|729 | Battery is discharging | 52.3 V | -3.8 A | 72.9 %
29730714 | MsgID 90 sent (29443) -->  | 02 | 0B | 00 | 00 | 75 | 30 | 02 | D9 | 523|30000|729 | Battery is discharging | 52.3 V | 0.0 A | 72.9 %

What is puzzling, querying another ID, as in a second or even third one, will eventually lead to the program failing, due to corruption. This can happen at a random number of iterations through the loop(). And I have not figured out yet, which or more so why some memory or variable gets corrupted.

Why I was suspecting, maybe I should destroy the response frame struct; though I don not understand how these work, other than assuming it is a placeholder for ID, data length and data, that gets constantly written to... or are there endless copies of it, eventually leading to memory corruption?

In any case, I think the communication protocol of this BMS is somehow crap. Maybe I think this out of frustration more than anything else.

What I also do not understand is the how the consecutive frames for ID 0x95 are handled. The protocol seems to deal with one frame at the time; issuing a subsequent messageRead(), will result in the next frame number (not CAN message ID).

To explain:
Message ID 0x95 looks like any other message:

|CAN ID|DLC|DATA (8 byte) = 0, 1, 2, 3, 4, 5, 6, 7|

... but contains the consecutive frame number in data byte 0; as 0x01..0x0F
Where are these frames coming from (in my case 16 cells = 6 frames)?
Is my query resulting in one, and each readMessage() pulls the next frame and so on?
I have not been able to determine how this really works.
Did the query send back 6 frame messages? When I do a readMessage(), am I reading some buffer on my end? Or does the readMessage() pull it from the BMS?

I am surprised I got this working as it is now, because I also mentioned adding a function or delay at some places the program won't work as expected any more.

Yes, I am aware of non-blocking delays or timings, I could even use a state machine, and may try these in my desperation. :slight_smile:

Alright, I figured it out.

Unless there is a pure resistive load on the battery, the BMS is actually accurately reflecting the dirty power requirements on the AC side.

I basically disconnected the battery, connected a bunch of 12 V lights in series, and connected this to the battery.
The result:
a) the disconnected battery showed a stable 0 A.
b) when connected to the resistive load it showed a stable -3.4 A.
c) put the inverter back on, and the wobble comes back. The wobble changes in frequency, hence, it is not a 50 Hz hum that made its way into these measurements.

To get a more stable value, I decided to sample 15 values into an array, FIFO it and add the latest value to the mix.
While this flattens the peaks, at least it 'looks' better. :slight_smile:

Thanks for the all the feedback.