diy solar

diy solar

DIY BMS design and reflection

interesting! thanks for the links to read

regarding AC inverting, it seems 50 Hz or 60 Hz are the most common for gridline stuff

i've dealt with sinusoidal error in time series ADC before by characterizing the error component as sinusoidal by visualizing, finding the frequency, then averaging integer number of cycles to null the partial cycle averaging error

but that time, i used a fixed number of samples, so if the frequency of it changed, error would immediately creep back into the averaged value output

however, it would be nice for user to not need to set 50/60 Hz mode for such a feature to operate

a buffer of say 6 cycles of 60 Hz would be 0.1 second, at 300 Hz sampling, that's only 30 samples to hold in memory

5 cycles of 50 Hz would be 0.1 second, at 300 Hz sampling, 30 samples

to calculate average value, i would maybe go backwards from the start of the buffer of samples and find the local min and max to easily mark the cycle peaks and valleys. then average over a configurable number of AC cycles. this ought to handle 50/60 Hz aliasing decently.

fitting a sinusoid to the same data might provide higher quality output, but it's heavier than minmax cycle detect (at least the algorithm im aware of)

my dream ideal would be that the number of detected cycles to average would be determined or matched by the BMS data refresh rate, e.g. if reporting values at 1 Hz output, keep minimum 1 second of ADC sample buffer and calculate over the entire buffer each time. this ought to remove a lot of error resulting from subsampling

this thread is super neat ☺️?

You forgot that the problem isn't to sample a nice 60 Hz sinus, the problem is the waveform is much more complex and has much higher frequency components in it, and they are non-predictable so you can't do that kind of SW adaptative stuff. But, given the highest frequency we want to sample is quite low in this case my guess is an ADC with a few kSps is good enough in conjunction with a proper low-pass anti-aliasing filter (and the price is still reasonable) ;)
 
Something like performing FFT, but only need to do that for my one target frequency component. 11 MHz (or whatever exact value) in my case. With sample window spanning a number of cycles, accuracy is improved. FFT can only find frequencies whos period is an integral fraction of sample window (otherwise it attempts to reproduce even a pure tone of single sine wave by adding together many other sine waves.) In my application, quite high sample rate needed to reject the (correlate) harmonics. If uncorrelated random noise or frequencies not associated with the fundamental, then modest sample rate but many cycles would do the trick. But my issue was harmonics.

Why don't you use a low-pass filter?
 
just adding an LC filter tuned appropriately should allow the silly SW hack to work?
 
Absolutely - if you're coulomb counting then you need either fast sampling, or analog integration before digital sampling.

The only problem is having a HW LPF with a low enough cut-off frequency to reject inverter ripple is a problem for things like short term over-current detection, etc... (let alone doing an e-fuse where fraction of a µs matters)

There's a third solution which is what I plan to do and consist of sampling at much lower rate than what you should per the Nyquist law, but with a random delay added between each sampling to avoid aliasing errors. That way you still have an instantaneous value you can use for over-current protection, etc. and with averaging (probably some weighted sliding average would be the best here I'd say, but need to confirm, I'm not designing this part yet) you can get an accurate value for coulomb counting, etc.


For a BMS, one ADC channel reading unfiltered current shut output could allow cell IR calculation, while another qualified through RC filters would be better for SoC.

Ah well, that's exactly what I described above (but with the LPF in SW rather than HW) ?

Ideally the perfect ADC for a future design would be one that has a fast enough sampling rate (let's says 5 kSsps) but which does averaging on its own so you don't need to use the MCU for that and you can just get the averaged result at a few dozens Sps. I don't know if that concept even exists in a ready made IC but that would be really useful. Lots of applications are in need of over sampling + averaging so I bet they would have a decent market for it.
 
Why don't you use a low-pass filter?

Let's say my signal is 700 Vpp at 11 MHz, and there is 3rd harmonic 33 MHz down -60 dB, 0.7V
I need to measure 700 Vpp at 100 ppm or better, so error less than 0.07V

Can I make a LPF that attenuates at least 20 dB in slightly more than one octave, but doesn't attenuate the fundamental even as much as 100 ppm (0.01%)?

This is why for a digital/ADC approach, I think I need samples with little to no filtering, sample width a few nanoseconds or less.


Ah well, that's exactly what I described above (but with the LPF in SW rather than HW) ?

In your case, I think LPF for current sensor and for cell voltage sensor would take out the large AC cycles and let you use one reading.
"LPF" could be capacitors hanging off a resistor in the sense path, and use a FET to ground it when you want averaged reading (but then you need to allow time for filter to settle).
Alternate is two sampling paths, one with LPF. More channels to mux.
 
Let's say my signal is 700 Vpp at 11 MHz, and there is 3rd harmonic 33 MHz down -60 dB, 0.7V
I need to measure 700 Vpp at 100 ppm or better, so error less than 0.07V

Can I make a LPF that attenuates at least 20 dB in slightly more than one octave, but doesn't attenuate the fundamental even as much as 100 ppm (0.01%)?

Probably not, but the idea was to calibrate the thing and not worry about that.


In your case, I think LPF for current sensor and for cell voltage sensor would take out the large AC cycles and let you use one reading.
"LPF" could be capacitors hanging off a resistor in the sense path, and use a FET to ground it when you want averaged reading (but then you need to allow time for filter to settle).
Alternate is two sampling paths, one with LPF. More channels to mux.

Yea but that would mean adding an op-amp and I don't really have a mux input available anyway. I'll redesign the current measurement signal chain on a future version, it would be too much work to change the current design and I'd like to have a working BMS before next century if possible ?
 
Last edited:
Just might do it. but ...


$1050 each! :ROFLMAO:

Maybe for a higher end mass spec. Kind of hoped to keep PCBA cost under that figure; this was just an RGA for process control.
16 bits seems good for better than 1 part in 10,000. But ENOB = 11.5 bits? Something to do with accuracy at speed maybe? I'm not really up on the finer points of mixed signal.
I was wondering if someone would look it up. If you're not sampling at 1GHz what's the point, right? ;)

Pretty soon the BMS will be sporting DDR, a quad core processor, and a mixed signal FPGA "for future expansion".
 
I know it's been quite some time I posted an update here but don't worry, the project is still progressing. I just didn't had much time available and my laptop decided to die for good this time; but at least now I have a proper desktop with nice selected components that will last and I'm on linux too so no more windows crap.

Of course I had to re-install Kicad and I took the opportunity to switch to the new version so I had to migrate all the schematics and PCB layouts, which was not so bad even if a bit lengthy and tedious. I still have a few things to change about Kicad's config but other than that I'm back to being operational :)

I also took quite a bit of time to make the EEPROM map (currently only 12 bytes to spare...): https://www.klgrth.io/paste/xpzcy

A bit more details about the section from 0x3D to 0x41 (and the one from 0x42 to 0x46): it is to store the trigger condition of the associated output. It can include one or two conditions (if two you can combine them with an AND, OR, XOR, NAND, NOR or XNOR operator; e.g. A AND B) which include an input (from the list you can find under the main table), a comparison operator (<, >, =) and a constant value to compare the input value to.

A few examples (NB: they don't necessarily make sense in the real world, I just had to find different cases):

Code:
00110 01 11111110110 000 00000 00 00000000000 --> ambient temperature < -10 --> the output' SSR will close if the ambient temperature goes under -10 °C
10100 10 00000001100 000 00000 00 00000000000 --> ABS(current) > 12 --> the output' SSR will close if the current goes above 12 A or under -12 A
11111 11 00000000001 001 00001 01 00010011000 --> master warning = 1 AND SOC < (152 / 10) --> the output' SSR will close if there's any active warning and if the state of charge goes below 15.2 %
10110 01 00000101010 010 10110 10 01010001110 --> cell to cell connection resistance < (42 * 10) OR cell to cell connection resistance > (654 * 10) --> the output' SSR will close if any of the cell to cell connection resistance is below 420 µOhm or above 6540 µOhm.

Please tell me if I forgot anything or if I made any error. I can also replace some of the inputs by other ones for the output triggers; in theory I could expand the list to 63 inputs instead of 31 but we would loose the NAND, NOR and XNOR operators, altho the NAND and NOR aren't really needed as they can be emulated with an AND or OR plus inverting the comparisons direction, and the XNOR will probably never be used anyways. So if you think something is missing in the list don't hesitate to comment ;)

I also did an index for the relevant parts of this thread which should allow you to go directly to whatever subject you're interested in without scrolling pages after pages; you can find it just after this post :)
 
Last edited:
General

What I need/want
Discussion on the modular design aspect
Short description of the different boards and their names
Board level block diagrams


Measurement

Cells voltage measurement topology
Shunt choice
Discussion about the ADC accuracy, resolution, ...
Tempco analysis of the ADC and Vref
Cells voltage measurement topology change
Discussion about cell IR measurement
Discussion about ADC accuracy and sampling aliasing


High power switch

MOSFETs
Recovery and precharge PTC choice + MOSFETs protections calculations
DPB design choices
DPB thermal design
MOSFETs gate drive explanations
Main switch topology discussion
Main switch thermal design discussion
More discussion about the main switch thermal design
Short tutorial on MOSFET selection for high-power stuff
Discussion about dV/dt turn-on immunity of MOSFETs


Balancing

Balancing board topology
Balancing strategy
Balancing board design


HMI

Discussion about the HMI
HMI design choices and annunciators list
HMI annunciators possible layouts
Ideas for the HMI
HMI bar-graphs discussion


Com

Discussion about communication protocols
Inter-board internal communication


Elec design

Timer choice
Voltage regulator conundrum
Details and explanations of the (at the time) schematic
Watchdog choice
More details and explanations of the (at the time) schematic
Discussion about connectors, power rails and grounds
Some op-amp change for a better one
Vref change for a better one
Discussion about possibly better op-amps
Discussion about precision resistors


PCB design

PCB routing discussion
Main switch board (DPB) mechanical design
PCB design discussion
 
epic update, thank you!

EEPROM map looks pretty rad at first view.

excited to more thoroughly review the map and try to parse the examples ??

congrats on the new computer and os ?

thank you for the index, and for sharing such development process!
 
Code:
00110 01 11111110110 000 00000 00 00000000000 --> ambient temperature < -10 --> the output' SSR will close if the ambient temperature goes under -10 °C
10100 10 00000001100 000 00000 00 00000000000 --> ABS(current) > 12 --> the output' SSR will close if the current goes above 12 A or under -12 A
11111 11 00000000001 001 00001 01 00010011000 --> master warning = 1 AND SOC < (152 / 10) --> the output' SSR will close if there's any active warning and if the state of charge goes below 15.2 %
10110 01 00000101010 010 10110 10 01010001110 --> cell to cell connection resistance < (42 * 10) OR cell to cell connection resistance > (654 * 10) --> the output' SSR will close if any of the cell to cell connection resistance is below 420 µOhm or above 6540 µOhm.

Please tell me if I forgot anything or if I made any error.

It's been a while since reading this forum again. Glad you're making progress. You most likely didn't make any errors, it's just that I don't understand.

SSR = solid state relay?

Does "the output' SSR will close" mean the SSR will open (no current flow)?

I thought the SSR is rated for 300A. Why the ABS 12A spec?

Regarding "the output' SSR will close if there's a master warning AND if SOC <15.2%". Should the AND be an OR function? What about low cell voltage? Would low cell voltage be listed in warnings? Why not just add low SOC in the master warnings?
 
SSR = solid state relay?

Yes ;)


Does "the output' SSR will close" mean the SSR will open (no current flow)?

No, it means its "contacts" will close so it'll conduct current, typically turning on whatever load you put on it.


I thought the SSR is rated for 300A. Why the ABS 12A spec?

It's just an example, you can put whatever you want (well, in the -1024 to 1023 range) as the threshold value.


Regarding "the output' SSR will close if there's a master warning AND if SOC <15.2%". Should the AND be an OR function? What about low cell voltage? Would low cell voltage be listed in warnings? Why not just add low SOC in the master warnings?

Again, it's just an example. Cell voltages are part of the list of inputs you can use, see the inputs 0x0E to 0x11 in the second table of the link.

I think you just missed the fact the user can change all of those. Actually, the user can change all the fields in the EEPROM that are in the user configurable section of the table (basically the addresses 0x01 to 0x46).
 
I did quite a few housekeeping changes on the BMS main board (moved J14 to match the balancing board connector position, changed some termination resistors value, moved the capacitors before the resistors in the cell voltages measurement circuit, added ground planes in the DC/DC converters area, ...).

Oh, and I can now export to PDF a color version of the schematic thanks to KiCad v6 \0/ I also added a plugin to export the PCB to PDF so no more manual screenshots which I had to crop manually and were quite low resolution :D
 

Attachments

  • BO_BMSB_16.pdf
    402.1 KB · Views: 18
  • BO_BMSB_16-PCB.pdf
    617.6 KB · Views: 16
I did more housekeeping things on the HMI board and I also finished the routing of the balancing board ?

I still need to do a few modifications on the main board (mainly changing the solderable jumpers by dip-switches for the convenience) and add fiducials and other silkscreen graphics (open hardware logo, my name, the version, ...) to all of the boards but right now they're pretty much done.

Then comes the prototyping phase but the component shortage will be a big PITA (the main mosfets are still almost twice the price and restock is expected 2023-08 for example...). Fortunately all the logic stuff is standard 74 logic, etc... so I should be able to test 90 % of the full BMS as soon as it's assembled.

I will also have to chose between a few LEDs references I already selected for each color as I need the brightest possible ones with a large angle and only IRL tests will tell me which ones are the best for what I want to do.
 

Attachments

  • BO_HMIB.pdf
    305.7 KB · Views: 7
  • BO_HMIB-PCB.pdf
    621.4 KB · Views: 6
  • BO_RBB_16.pdf
    218.6 KB · Views: 5
  • BO_RBB_16-PCB.pdf
    348.9 KB · Views: 6
Update of the EEPROM map: https://www.klgrth.io/paste/bz2jk

I added a lot of inputs to the list (I decided to change the logical operator field from 3 bits to 2 so I could have 6 bits instead of 5 for the input IDs) for the ouputs' trigger conditions.

I also added a list of the errors which can be logged in the 0xE0-0xFB section. It's probably not complete as I'm sure I'll add plenty of new errors I haven't thought of yet when I'll do the code. The events subsection of the table will only be logged if a debug mode is enabled on the BMS.

Updated version of the ouputs' trigger conditions format:

A bit more details about the section from 0x3D to 0x41 (and the one from 0x42 to 0x46): it is to store the trigger condition which will trigger the associated output SSR to close. It can include one or two conditions (if two you can combine them with an AND, OR or XOR operator; e.g. A AND B) which include an input (from the list you can find under the main table), a comparison operator (<, >, =) and a constant value to compare the input value to (boolean input values like 'precharging', 'on', ... can only be equal to 0 or 1).

The format is: [input ID A] [comparison operator A] [constant value A] [logical operator] [input ID B] [comparison operator B] [constant value B]

If there's only one input to check then the logical operator field and all the input B related fields just need to be set to 0 (like in the first two examples below).

A few examples (they don't necessarily make sense in the real world, I just needed to find different cases):

Code:
000110 01 11111110110 00 000000 00 00000000000 --> ambient temperature < -10 --> the output' SSR will close if the ambient temperature goes under -10 °C
010100 10 00000001100 00 000000 00 00000000000 --> ABS(current) > 12 --> the output' SSR will close if the current goes above 12 A or under -12 A
111101 11 00000000001 01 000001 01 00010011000 --> master warning = 1 AND SOC < (152 / 10) --> the output' SSR will close if there's any active warning and if the state of charge goes below 15.2 %
011010 01 00000101010 10 011010 10 01010001110 --> cell to cell connection resistance < (42 * 2) OR cell to cell connection resistance > (654 * 2) --> the output' SSR will close if any of the cell to cell connection resistance is below 84 µOhm or above 1308 µOhm.

Of course you will not need to input binary by hand, the web GUI will have a user friendly interface for all of this ;)

As always, don't hesitate to tell me if I forgot something or if I made a mistake.
 
Last edited:
This is the already existing internal EEPROM of the ATMega4809 and I don't really have any spare I/O to communicate with an external EEPROM (in theory I could use the SPI bus but I'd still need to allocate one of the I/O for the SS line...) and so far the 256 Bytes are enough, I currently have 12 spare bytes.

I'm also quite limited on board space (and I have lots of things which would be hard to move because they would interfere with other things or because it's inter board connectors so I would need to reroute the other boards too.

If I do a v2 I'll add a shift register which will instantly free 3 I/Os (the 3 address lines for the ADC input mux) and add 2 more I/Os so I could add an external EEPROM and still have 4 more I/Os for the user to play with ;) I saw that possibility a bit too late as I already routed the whole board. I'm also not 100 % happy with the power distribution layout as it is now but again, I would need to reroute the whole board (plus I would probably switch to a 4 layers PCB too) and it would be great to have a working BMS before the sun runs out of hydrogen...?

So in short: available I/Os are very limited and board space are the reasons.
 
Last edited:
Back
Top