My simple Ni-mh battery discharger mah calculator Arduino project Mark II

Original is here:

just updated my little project a little, both hardware and software, any suggestion will be great!!

#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
/*
int leds[8]={0,1,2,3,4,5,6,7};
int Vohm[2]={A0,A1};
int Button[4]={A2,A3,A4,A5};*/

int sec=0;
int minu=0;
int hr=0;
unsigned long time=0;
unsigned long pstimer=0;

float DV=0;
float BV=1;

int ma=0;
float mah=0;
float mahnow=0;

int timerx=1;

//========================================================================================================================

void setup() {  
lcd.begin(16,2);

pinMode (7, OUTPUT);
pinMode (5, OUTPUT);
pinMode (3, OUTPUT);

pinMode (A2, INPUT); // battery voltage
pinMode (A5, INPUT);// resistor drop voltage

pinMode (A3, INPUT); //Display changing button

digitalWrite (7,HIGH);
digitalWrite (5,HIGH);
digitalWrite (3,HIGH);

}


//========================================================================================================================
void loop() {
  
  
if(BV<0.1){
digitalWrite (7,LOW);
digitalWrite (5,LOW);
digitalWrite (3,LOW);
timerx=0;
}  

unsigned long timer= millis();
 if(timer-pstimer > 1000){
   sec++;
   
   float BV1 = analogRead(A2);
   BV = BV1/1023*5.18;  // compensate for resistor, need to check for the real volt and the volt from the arduino are the same! 

   float DV1 = analogRead(A5);
   DV = DV1/1023*4.98;   // check the 5V arduino to ground. Usually, it's less than 5 volts.
   
   ma=DV*1000;
   
   mahnow=DV/3.6;
   if (BV>0.1){
   mah=mah+mahnow;}
   
   lcd.setCursor(0,0);
   lcd.print( "      " );

   pstimer = timer;
 }  
 
 
if(sec==60){
 sec=0; 
 if (timerx==1){
 minu++;}
}

if(minu==60){
 minu=0;
 hr++;
} 
    
//================================Time and mah

char szTime[8];
sprintf( szTime, "T%02d:%02d", hr, minu );
lcd.setCursor(0,0);
lcd.print( szTime );

lcd.setCursor(7,0);
lcd.print(mah);

lcd.setCursor(13,0);
lcd.print("Mah");

//================================Batttery volt and current in ma

lcd.setCursor(0,1);
lcd.print("B:");

lcd.setCursor(1,1);
lcd.print(BV);

lcd.setCursor(5,1);
lcd.print("V");

char maC[6];
sprintf (maC, "%04d   Ma",ma);

lcd.setCursor(7,1);
lcd.print(maC);




}

auto stop discharging works! after a deep discharge, voltage go back to 1.21V

Why not replace the transistor with a MOSFET and adjust the gate voltage to give a specific discharge current? In the "linear" portion of their characteristic curve they act like a good precision variable resistor with the gate voltage controlling the resistance between source and drain.

thanks for the advise. So I use pwm to control the MOSEFT, and use a smaller resistor instead of 1 ohm here, and so I can have a constant current at different discharge rate I want, is this what you mean? This is interesting, and I will definitely try that.

majenko:
Why not replace the transistor with a MOSFET and adjust the gate voltage to give a specific discharge current? In the "linear" portion of their characteristic curve they act like a good precision variable resistor with the gate voltage controlling the resistance between source and drain.

arduinomagbit:
thanks for the advise. So I use pwm to control the MOSEFT, and use a smaller resistor instead of 1 ohm here, and so I can have a constant current at different discharge rate I want, is this what you mean? This is interesting, and I will definitely try that.

majenko:
Why not replace the transistor with a MOSFET and adjust the gate voltage to give a specific discharge current? In the "linear" portion of their characteristic curve they act like a good precision variable resistor with the gate voltage controlling the resistance between source and drain.

If you use PWM you want to low-pass filter it to create a DC voltage. Otherwise the MOSFET would be just doing PWM. A better solution would be to use a good high quality DAC, like the MCP4821, which can give you 0 - 2.047V at 0.5mV steps, or 0 - 4.095V at 1mV steps.

Of course, it'll get hot so be sure to use one that can cope with the power dissipation and give it adequate heat-sinking.

In that wiring the pwm will not work properly as the current will depend on Vd (the voltage on the resistor), not only on the filtered Vgs..
I would connect the n-mosfet with Source to gnd, the 1ohm resistor into Drain. I would measure the voltage at the resistor differentially (or with two analog inputs connected to low and high side of the resistor, being the high-side voltage the actual battery voltage).

pito:
In that wiring the pwm will not work properly as the current will depend on Vd (the voltage on the resistor), not only on the filtered Vgs..
I would connect the n-mosfet with Source to gnd, the 1ohm resistor into Drain. I would measure the voltage at the resistor differentially (or with two analog inputs connected to low and high side of the resistor, being the high-side voltage the actual battery voltage).

There are special current sense amplifiers you can get that are designed for high-side current sensing. I can't remember the part number off hand, but I think it was Analog Devices I used last time. Very useful. Good for if the voltages are higher than your sensing aparatus.

But for this, yes, read both sides of the resistor in a high side position and subtract one from the other to get the voltage drop.

Something like this (R1C1 is an example only, it has to be calculated properly for given pwm frequency):

batdisch.jpg

why it doesn't work if the MOFEF does the PWM? Can't I just make that sampling time interval to 1ms, so it is fast enough to react to the PWM change and record the correct current and simply do the math to get the mah and try to vary the PWM to get a constant current? I am not sure if this work or not, but I will try it out. Failure is always the mother of success!!

majenko:

arduinomagbit:
thanks for the advise. So I use pwm to control the MOSEFT, and use a smaller resistor instead of 1 ohm here, and so I can have a constant current at different discharge rate I want, is this what you mean? This is interesting, and I will definitely try that.

majenko:
Why not replace the transistor with a MOSFET and adjust the gate voltage to give a specific discharge current? In the "linear" portion of their characteristic curve they act like a good precision variable resistor with the gate voltage controlling the resistance between source and drain.

If you use PWM you want to low-pass filter it to create a DC voltage. Otherwise the MOSFET would be just doing PWM. A better solution would be to use a good high quality DAC, like the MCP4821, which can give you 0 - 2.047V at 0.5mV steps, or 0 - 4.095V at 1mV steps.

Of course, it'll get hot so be sure to use one that can cope with the power dissipation and give it adequate heat-sinking.

pito:
Something like this (R1C1 is an example only, it has to be calculated properly for given pwm frequency):

Thanks for the chart. the PWM frequency is 490 Hz, but wait, can't I just sample the VD using 1ms interval, so ignore the PWM frequency and simply add a 1M ohm resistor to the gate and ground ?