Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

66%
+2 −0
Q&A Dealing with multiple CAN terminations in a master-slave-BMS setup

Your bus length is so short that you can consider the battery connection a stub. As long as there is 60Ω between CANH and CANL and the cable to the battery is not ridiculously long (many meters), i...

posted 11mo ago by Lundin‭  ·  edited 11mo ago by Lundin‭

Answer
#4: Post edited by user avatar Lundin‭ · 2025-10-17T13:06:15Z (11 months ago)
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120ohm.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is bitrate x bits x 128.
  • - 500kbps = (1/500*10^3) = 2us per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2us x 46 = 92us
  • - 92us x 128 = 11.78ms.
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • I've encountered problems with this in real life when someone attempted to do with this with an even slower relay, which therefore brought down the whole bus sporadically, depending on how the relay contact bouncing ended up.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60Ω between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/120 + 1/120 = 1/R<sub>tot</sub>) 40Ω, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120Ω.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If its error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is: bit rate * bits * 128.
  • - 500kbps = (1/500*10^3) = 2μs per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2μs x 46 = 92μs
  • - 92μs x 128 = 11.78ms
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, initialize everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • I've encountered problems with this in real life when someone attempted to do with this with an even slower relay, which therefore brought down the whole bus sporadically, depending on how the relay contact bouncing ended up.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120Ω resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
#3: Post edited by user avatar Lundin‭ · 2025-10-10T14:32:17Z (11 months ago)
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120ohm.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is bitrate x bits x 128.
  • - 500kbps = (1/5000*10^3) = 2us per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2us x 46 = 92us
  • - 92us x 128 = 11.78ms.
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • I've encountered problems with this in real life when someone attempted to do with this with an even slower relay, which therefore brought down the whole bus sporadically, depending on how the relay contact bouncing ended up.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120ohm.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is bitrate x bits x 128.
  • - 500kbps = (1/500*10^3) = 2us per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2us x 46 = 92us
  • - 92us x 128 = 11.78ms.
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • I've encountered problems with this in real life when someone attempted to do with this with an even slower relay, which therefore brought down the whole bus sporadically, depending on how the relay contact bouncing ended up.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
#2: Post edited by user avatar Lundin‭ · 2025-10-09T09:13:49Z (11 months ago)
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120ohm.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is bitrate x bits x 128.
  • - 500kbps = (1/5000*10^3) = 2us per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2us x 46 = 92us
  • - 92us x 128 = 11.78ms.
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
  • Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine.
  • If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames).
  • You usually just get problems when there is one or several missing terminators and you get >120ohm.
  • ---
  • > I came across an application note that uses an optocoupler to control termination.
  • It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.
  • CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.
  • So the critical time is bitrate x bits x 128.
  • - 500kbps = (1/5000*10^3) = 2us per bit
  • - Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
  • - 2us x 46 = 92us
  • - 92us x 128 = 11.78ms.
  • Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.
  • I've encountered problems with this in real life when someone attempted to do with this with an even slower relay, which therefore brought down the whole bus sporadically, depending on how the relay contact bouncing ended up.
  • What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.
  • ---
  • > where should I put the control circuit?
  • Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.
  • The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.
  • The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.
#1: Initial revision by user avatar Lundin‭ · 2025-10-09T09:10:20Z (11 months ago)
Your bus length is so short that you can consider the battery connection a stub. As long as there is 60 ohm between CANH and CANL and the cable to the battery is not ridiculously long (many meters), it will work just fine. 

If you add a third termination you end up with (1/120 + 1/20 + 1/20 = 1/Rtot) 40 ohm, which isn't recommended, but in practice that will very likely work too (I do this all the time by mistake on all manner of CAN hardware and have yet to see it fail or causing error frames). 

You usually just get problems when there is one or several missing terminators and you get >120ohm.


---

> I came across an application note that uses an optocoupler to control termination.

It needs to be fast enough to switch on before CAN communication goes live and accumulates too many errors. If you are using something like a generic Cortex M then it boots out of power-on very fast. On the other hand if you have lots of overhead like RTOS, or in case you run on some low frequency = low power oscillator, then it won't.

CAN error frames are always expected during the boot-up stage because not all nodes will start in sync, someone has to be the first one and not getting anyone to talk with. That first node will send an error frame and then keep trying. If it's error counter passes 127 then it will go error passive and depending on how you deal with errors that could be a problem. 128 more errors and it goes bus off.

So the critical time is bitrate x bits x 128. 

- 500kbps = (1/5000*10^3) = 2us per bit
- Assume worse case = no payload and 11 bit id, around 46 overhead bits in a CAN frame (+/- some stuffing).
- 2us x 46 = 92us
- 92us x 128 = 11.78ms.

Meaning that if the optocoupler has 5ms toggle time, the MCU then has 11.78 - 5 = 6.78 ms to come out of power-on reset, init everything and send out a CAN frame. That can either be an eternity or far too quick, depending on which MCU you've got, how you clock it and how much boot-up code there is.

What's recommended instead of an optocoupler is an analog switch IC. And if you need galvanic isolation (doesn't sound like you do in this specific case) then add that on the line controlling the analog switch. Preferably with an inductive "digital isolator" rather than an optocoupler, since they are faster.

---

> where should I put the control circuit?

Usually you do _not_ want to control termination through the MCU, because normally the MCU will not have a clue of what hardware configuration that is present.

The plain and simple way is instead to add something like a terminal block connector to the board and if you put a wire between pin 1 and 2 on it, then a SMD 120ohm resistor on-board is connected between CANH and CANL, otherwise it just sits floating connected to just one of them. If you pick a terminal block with a removable cable connector part, then you can just move that cable part around between boards depending on where the termination needs to be.

The advantage of this is no soldering, so all boards are the same and even the end user can be taught to do it.