i want to read all battery cell voltages (10 series lithium-ion cells)
i have made a circuit like this that switches between different battery series wires and gives them to a 5v ADC. It works with only 1 battery but as soon as I add more the multiplexer gets hot. i have also attached my code. I'm very new to everything here it's actually my first time learning to code and tinkering with hardware.
void loop()
{
//there are these code blocks responsible for measuring each battery total code blocks are 10 i
//have decided only to put 2 here for you to get an idea.
mux1channel(0); // sets multiplexer1 channel to 1. so SIG1 and B1 is connected
mux2channel(1); // sets multiplexer2 channel to 2. so SIG2 and B2 is connected
delay(100);
voltage = adc_1.getResult_V(); // gets voltage difference between SIG1 and SIG2 using the adc
WebSerial.println("Bat1: ");
WebSerial.println(voltage); // Prints that voltage difference on screen
delay(3000);
mux1channel(1); // sets multiplexer1 channel to 2. so SIG1 and B2 is connected
mux2channel(2); // sets multiplexer2 channel to 3 so SIG2 and B3 is connected
delay(100);
voltage = adc_1.getResult_V(); // gets voltage difference between SIG1 and SIG2 using the adc
WebSerial.println("Bat2: ");
WebSerial.println(voltage); //prints voltage.
delay(3000);
}
Please help me my brain isn't big enough to figure out a solution but i think i need to add resistors to each battery series wire to limit current?
It will not work because all the voltages the Arduino measured are referenced to ground. So when you try and measure the other batteries these are shorted out to ground. Hence the multiplexer gets hot.
This has been covered many times over the years. My favourite solution is with a flying capacitor implemented by relays, but there are others as a forum search will show.
Sorry, i forgot to write in the original post that I'm using an external ADS1115 i2c controlled ADC which is still powered by the shared 5v line and gnd. i have programmed it so it does not measure voltage to the ground but measure voltage between pin 1 and 2. it has 4 adc pins essentially like a multimeter which is voltage limited to 5v and it sends that data to the Arduino via i2c.
Code for that if anyone is curious.
void setup()
{
adc_1.setVoltageRange_mV(ADS1115_RANGE_6144); //adc range
adc_1.setMeasureMode(ADS1115_CONTINUOUS); //continous measuring
adc_1.setCompareChannels(ADS1115_COMP_0_1); //compare voltage between pins 1 and 2
}
Whenever you have a voltage is is measured between two points. One point is the thing you are measuring, like the voltage on your battery, the other is the point of reference normally ground, which means the common voltage. This is how electricity works.
When you have some electronics like a multiplexer on an I2C control, that multiplexer automatically is switching voltages with reference to ground. That is why to get any external component to work you need to connect the ground. The exception to this is when an input signal is electrically isolated, like when you use an optical isolator.
Yes.
By measuring the difference between two voltages one differential input is at 4.2V and the other signal is at 8.4V, with reference to ground. Now look at the data sheet of your multiplexer, and look at the maximum input voltage it can take. You will see that it can't handle signals outside of its power rails, which are 0 to 5V.
Now you can use an optical isolator to measure the signals, but the problem with this is that basically these are digital devices, so the output is not a true reflection of the input. You can make an analogue optical isolator by using a optical isolator that has one emitter and two receivers in the same package. You then use that second receiver in an operational amplifier circuit that modifies the voltage applied to the emitter to keep the output linear. This is another way to solve your problem, but:-
You will have to compensate for the none linearity in each analogue optical isolator, because they will not be all the same.
The operation amplifier will have to be capable of working at the maximum voltage you will use on the input side. Which in your case is 4.7 * 10 = 47V.
Have you done any searching yet?
This is the circuit of a flying capacitor isolator. The idea is that you charge up a capacitor with the voltage across one cell, and then using a double pole change over relay, you switch that capacitor to the analogue input of the Arduino either directly or through a multiplexer.
Hi, @rasil1127
Can I suggest you draw a COMPLETE schematic, with all connections drawn, that way you will see where your gnds are and what potential you have on each of the cell connections.
Remember your ADC is not floating, it uses gnd as its reference, the same gnd as your battery pack.
The flying capacitor as described by @Grumpy_Mike is the simplest and most logical method to measure each individual cell.
As the currents in the circuit are very small, very small relays can be used.
If you look at one of the published schematics for a lithium pack battery charger, they use voltage dividers to get the 10 voltages into the measurable range and then measure each. For example, they might use no divider on B1 and measure that (2.5-4.2V) against Ground (B0). On B2 they would use a 2:1 divider to get a total of the first two cells (5 to 8.4V) down to a readable range (2.5 to 4.2) and measure the total, multiply by 2, and subtract the B1 reading to get B2. On B3 they might use a 3:1 divider, multiply the reading by 3 to get all three cells, then subtract the B2+B1 reading to get B3.
thanks for the response i thought of it that way but if i do it the inaccuracies of resistors add up too much towards the 10s cell that is why i went the shift register route (even if its non-functional)
hello, i understand i find problem with Mike's schematic because i want it to be somewhat small and easily producible those relays will be too bulky and small one will be quite expensive.. by floating adc i find that interesting is there no way to isolate the ground from the battery and logic? or something if not i understand i need to look into some ic that can read all cell voltages like the BQ769x0 series
You don't seem to know much about components and are making your assumptions based on bulky hobby relay boards. How small do you think you can get a relay?
i did some more research about this topic and i found some "CPC1017N" solid-state relays that say: "optically coupled MOSFET technology to provide 1500Vrms of input/output isolation."
Will these be enough to do this? also does this circuit require 2 relays for charging up the capacitor? i don't quite read this schematic i tried searching for it but online there are different circuits and i cant find an explanation for this one
No.
Why do you think a solid state relay would help?
They are outputs not inputs, nothing to do with your problem.
It takes one relay with double pole change over contacts. That dotted line across the contact means they are double pole. That is for a single coil you have two sets of change over contacts.
I think i got it, with a resistor network and a bit of math it seems to be working properly. voltage not accurate enough because I'm using 1% resistors. ideally 0.1% is needed
the first image shows 4 cells in series and each cell bank's voltage in mV the first number being 1st cell and the last number being 4th cell.
then the multimeter measures the last cell bank, to show the problem that resistor networks cause with incorrect voltages as you add more series cell is solved.
The diagram from post#14 drains cell#1 the most, resulting in uneven discharge.
If you don't use a balance charger, then the pack (cell#4) could eventually die from over-charging.
This problem is of course 10x worse with a 10s pack.
Leo..
Idea was to have the Arduino discharge cells which are charged too high.. so normal battery plus and minus can be used to charge the whole thing and all overcharged cells will be discharged through a 5w resistor to balance cells while charging and after.
The diagram from post#14 drains cell#1 the most
why would that be? it's a normal series configuration like how all batteries are made.. charge disbalance is caused by the batteries having differences in resistance and that is normal hence the need for a balancer. so cell 1 is being used the same as cell 3 or cell 4. uneven discharge is not possible unless the cells are mixed and matched
Diagram post#14.
Cell#2 not only carries the current for it's own voltage divider,
but also the current for the dividers of cell#3 and cell#4.
Cell#4 only carries it's own voltage divider current.
Which is normally done with a balance board.
A balance board is like a zener diode across each cell, which is set to 4.2volt.
This is not a common zener, but a combination of a reference voltage and a power transistor.
Best to leave such an important task to dedicated hardware, not to a microprocessor.
Balance boards do not discharge cells. They divert charging current away from the cell when the cell is fully charged. That diverted current is turned into heat.
Leo..
Every bms i have worked with in the past years use a bq769x0 (or similar) paired with a microcontroller or a 1s cell protector ic. zener diode method is not good for larger capacity batteries where more current is required to balance the cells. also the voltage is just being read not used from the voltage dividers so there's basically to no current going through them even if they were all calculated for and it will certainly not impact any imbalance that will affect the cells noticeably. for example, i have a pack connected like that for over 2 weeks and the voltages are exactly the same just dropped due to parasitic charge but defiantly not become unbalanced
First time you mentioned "large capacity".
Don't know what you mean with that if you don't put any numbers with it.
The 10-cell BQ76930 seems to work with the flying capacitor principle.
Looking at page#1 of the datasheet, you see the caps across the cells.
So why don't you use that chip.
Leo..