Thread Tools
Jul 04, 2019, 11:45 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP
Build Log

Servo MilliAmpere Hour meter


I've been playing with this subject over the past couple of days, and have put together a breadboard of what would be required. The schematic is attached. The MilliAmpere Hour function Arduino Sketch is complete, and is working. This project will display the accumulated milliampere hours delivered from the receiver battery to the receiver during the day of flying. A pushbutton will allow clearing the stored accumulated milliampere hours prior to the flying for the day.

Next in the project is to incorporate the EErom functions that store the accumulated milliampere hours total for the day. One issue with those EEroms, is they can be worn out by repeated writing every ten seconds or so. What I'm planning is something very different. The Arduino Nano has 1024 bytes of EErom. The sketch will erase the EErom by filling it with all "FF's".

Then as each 10 milliampere hour value is accumulated, it will write "00" to the first EErom location. Next 10 Mah to the second EErom location and so on to the end of the EERom. That allows 10 X 1024 or a maximum of 10,400 mah receiver battery capacity, sufficient for most RC projects. And, this sketch design spreads out the writing to a variety of EErom cells, rather than one cell over and over.

The PCB will be around 1 3/4 inch by 3/4 inch by about a half inch high, mostly from the Arduino physical size.

More to come.
Last edited by vollrathd; Jul 04, 2019 at 11:51 PM.
Sign up now
to remove ads between posts
Jul 11, 2019, 11:22 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP

Arduino Sketch is done


This is a general purpose meter using an Arduino Nano, an 128X32 OLED, a MCP3424 Analog interface, a few resistors and not much else. With proper precision resistors, accuracy can be 0.5% or so. The sketch is configured to record milliampere hours on the receiver power input during a day of flying. Different software will allow use for measuring up to four voltages or currents.

The meter's Mah count is reset by a switch in the morning, then it accumulates milliampere hours during the day, saving the reading to EEprom. If a switch is closed on the powering up of the meter, the Sketch software clears the EErom to show 0 mah for the next day of flying.

The Arduino Nano has 1024 EEprom bytes, so multiplying that times 5 gives a maximum of 5000 mah for the day's flying. This allows only writing to a specific EErom location once per day, so the EEprom will not be worn out during many days of use.

The PCB is complete, and includes other resistor inputs for the three other A/D inputs of the MCP3424 Analog interface, making this project somewhat of a general purpose device. The current plan is to build up a few of them on PCB's for future use on other projects. All it takes is a change in the Sketch software to use it for something else.

Here is the Arduino Sketch for the MilliAmpere Hour Meter.

Code:
/* 
 ***************************************************************************************** 
 *  03/30/2019                                                                           *
 *  this program reads the MCP3424 A/D converter and sends the result to both the USB    *
 *  How it works
 *  The Arduino reads the MCP3424 every two milliseconds, and adds up the readout value
 *  When the readout value hits number 187, that represents exactly 5 milliampere hours.
 *  The sketch then updates an EErom field from 0x00 to 0XFF to represent that 5 mah, then
 *  increments the EErom address to the next location.  With 1024 EErom addresses, that 
 *  represents a maximum of 5 ma X 1000 or 5,000 Mah, sufficient for most RC use.
 *  Since the resolution is fixed at 5 mah increments, the unit will update its display 
 *  only after each 5 mah increment.  So, 24 eerom "0x00" equals 120 mah
 *  NOTE: CAN NOT USE INTERRUPT WITH MCP3424, THIS UNIT ALSO USES INTERRUPTS
 *  A switch is provided to allow resetting the unit for the beginning of the flying day
 *  Note that the full current range can easily be changed by different gain on the 
 *  MCP3424, or different shunts on the current sensing resistor
 **** ref Gainx1, max input voltage is 2.5 VDC for full scale ****
 **** ref Gainx8, max input voltage is 0.25 VDC for full scale *** 
 **** ref SRxxB is bit resolution, ranging from 12 to 18 bits  *** 
 **** ref Gain X8 plus 18bits is 0.06 VDC for full scale *********
 **** MCP 3421 has one channel input 
 **** MCP 3422 has two channel inputs
 **** MCP 3424 has four channel inputs, from CH1 to Ch4
 **********************************************************************************
 */
 //initiate functions
#include <TimerOne.h>
#include <MCP3424.h>
#include <Wire.h>
#include <EEPROM.h>
#define OLED_RESET 4
#include <Adafruit_SH1106.h>
   Adafruit_SH1106 display(OLED_RESET); 
   MCP3424 adc(PIN_FLOAT, PIN_FLOAT);
   byte int_count=0;  //define variable
   double  mah_value = 0;
   double mah_total = 0;
   unsigned int mah_hours = 0;
   byte flag;  //flag for interrupt
   float test = 0;
   int counter;
   byte value = 0;
   bool blocking = false;                        //allows for repeating read commands
//****************  Setup Routines **************************************************  
void setup()
//****************  Setup Routines **************************************************   
{
   pinMode(12, INPUT);  //used for oscilloscope timing
   pinMode(13, OUTPUT);   //used for reset EEprom on power up
   display.begin(SH1106_SWITCHCAPVCC,0x3C);//initialize 128/64 with the I2C addr 0x3C 
   Serial.begin(9600);
   display.clearDisplay();
   pinMode(LED_BUILTIN, OUTPUT);
   display.clearDisplay();                  //Set the display up, text size and color
   display.setTextSize(2); 
   display.setTextColor(WHITE);
//MCP3424 setup
   adc.generalCall(GC_RESET);
   adc.startNewConversion(CH4);

   adc.creg[CH1].bits = {GAINx8, SR12B, CONTINUOUS, CH1, 1 };                  //Amps
   adc.creg[CH2].bits = {GAINx8, SR12B, CONTINUOUS, CH2, 1 };            //Volts 1&16
   adc.creg[CH3].bits = {GAINx4, SR18B, CONTINUOUS, CH3, 1 };//0.126 Volts Max X4 18B
   adc.creg[CH4].bits = {GAINx8, SR18B, CONTINUOUS, CH4, 1 };        //0.06 Volts max  

   display.clearDisplay();                      
   display.setTextSize(4);
   display.setTextColor(WHITE);
 } 
//********************************************************************************** 
 void Clear_EErom(void)
{ digitalWrite(13, LOW);
  if (test == 0)                               //test if switch pushed to zero EErom
   {
   display.clearDisplay();   
   display.setTextSize(4);
   display.setCursor(0,00);
   display.print("Reset");
   display.display(); 
   delay(1000);
 for (counter = 0 ; counter < 1000 ; counter++)           //preset EErom to all FF's
  {
   EEPROM.write(counter, 0XFF);
  }
 }
   display.clearDisplay();   
   digitalWrite(13, HIGH);   
   display.clearDisplay();                               //delay for time to read it
   display.setCursor(0,0); 
   display.print("Start");
   display.display();
   delay (1000);
 }
//********************************************************************************** 
  void Read_EErom(void)
{
  mah_hours = 0;
 for (counter =0; counter<1000;counter++) 
  {
   value = EEPROM.read(counter);
   Serial.println(value, DEC);
  } 
}
//********************************************************************************** 
void Retrieve_mah(void)       //routine scans EErom, adding up mah hours on each "0"
{
   mah_hours = 0;
 for (counter =0; counter<1000;counter++) 
  {
   value = EEPROM.read(counter);
  if (value == 0)
   {
    mah_hours = counter;                      //adds 5 mah per 'zero', stops at 1000
   }
  } 
   display.clearDisplay();                   //display accumulated milliampere hours                     
   display.setCursor(0,0); 
   display.print(mah_hours*5);//its 5 mah per EEprom memory location filled with "0"
}
//*********************************************************************************** 
void Get_mah(void)
//*********************************************************************************** 
{ 
 for (counter = 0;counter<1000;counter++)     //read MCP3424 1000 times in 0.7 seconds
 {
 //   digitalWrite(12, HIGH);                      // turn the LED on (scope monitor)
   ConvStatus err = adc.read(CH4, mah_value,blocking);   
   mah_total = mah_total+mah_value;  //add up total mah counts
 if (mah_total>272)                                 //number 272 equals exactly 5 mah 
  {
   mah_hours = mah_hours+1;
   mah_total = 0;
   EEPROM.write(mah_hours, 0X00);
   display.clearDisplay();                      
   display.setCursor(0,20);
   display.print(mah_hours*5); 
   display.display();
  }
 }  
}
//**********************************************************************************    
//Main program need to install switch reset
void loop()
{ 
  display.setTextSize(5);
  digitalWrite (12,HIGH);                           //turn on pull up resistor on D12
  counter = digitalRead(12);                                      //test for key push
 if(counter==LOW)                                        //if key pushed, reset EErom
  {
   Clear_EErom(); 
  }
   Retrieve_mah();
   display.clearDisplay();
   display.setCursor(0,20); 
   display.print(mah_hours*5 ); 
   display.display();
// go into endless loop for mah capacity
  for(;;)                                                              //endless loop
  {
   Get_mah();
 if(mah_hours>1000)
  {
   display.clearDisplay();
   display.setCursor(0,20); 
   display.print("OVER");
   display.display();
   delay(300);
   display.clearDisplay();
   display.setCursor(0,20); 
   display.print("    ");
   display.display();
   delay(100);
   }
  } 
}
//********  End of Sketch Program***************************************************
Last edited by vollrathd; Jul 12, 2019 at 08:56 PM. Reason: Minor clarification in Arduino Sketch
Jul 12, 2019, 08:49 AM
Registered User
I would strongly recommend adding an RC filter to the ADC input to average the current monitor voltage. It will be far more accurate that way since that current monitor signal is going to be very spiky.
Jul 12, 2019, 10:04 AM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP
Quote:
Originally Posted by Volt_Ampere
I would strongly recommend adding an RC filter to the ADC input to average the current monitor voltage. It will be far more accurate that way since that current monitor signal is going to be very spiky.
My prototype has an RC filter, forgot it on the schematic diagram and PCB layout.

I ran into major inaccuracy problems while testing the prototype on my pulse generator that generated PWM pulse currents from 1% to 99% at 3 peak Amperes.

It took a day to figure out the problem. Turned out that the grounded USB 5 Volt negative interacted with the grounded scope lead on my $1200 scope.

That interaction was eliminated by going to my battery powered $25.00 DSO 150 scope from EBay. That cheap scope is used a lot. And, It's trace is far less noisy at 5 mv inputs than that $1200 Siglent scope!
Last edited by vollrathd; Jul 12, 2019 at 11:11 PM.
Jul 12, 2019, 11:45 AM
Registered User
Coulomb counting (which is what you are doing to measure mAH) is tricky to do well with widely varying currents. There are some chips out there that are designed to do that but I have not fooled with any of them. I have done what you are doing and it's at best a rough approximation.
Jul 12, 2019, 09:05 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP

Schematic of prototype Servo Mah meter


Here are the schematics of the Servo Mah meter, plus the PCB layouts. The PCB layouts include the Mah meter, along with the PCB layout for the 200 Amp meter in a different RCGroup thread.

The 200 Amp meter current logging is designed to be downloaded through the Arduino USB port to the PC. An OLED was added to allow multiple use of the PCB with just different Sketch firmware.

Right now, I'm performing a MilliAmpere hour test with this meter with a peak current of 1.94 Amps, switched on and off at a 26% duty cycle at 45 Hertz. The power source is a fully charged two cell A123 battery. The battery will be topped off after 800 mah is pulled out of it with the pulse current setup.

That will allow real world comparison on what the MilliAmpere Hour meter, the Astroflight Wattmeter shows against what it actually takes to top off that A123 pack after the discharge test. Right now at 200 total discharged mah, this meter matches the Astro Wattmeter exactly.
Last edited by vollrathd; Jul 12, 2019 at 10:42 PM.
Jul 12, 2019, 10:40 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP

Results are in!


I just completed a 100 minute run with a current discharge value of 1.89 Amps at a 26% 45 Hertz duty cycle. The maximum current was measured with my Fluke 87V meter with its 1 millisecond peak response function. That calculates out to a total value of 815 MilliAmpere hours on the Fluke meter. The Astro Wattmeter shows 785 Mah, the meter on this project shows 805 Mah, just over one percent error.

And, for recharging the A123 battery pack, it took 902 mah. The discharge milliampere capacity on the meter was 805 mah, plus another 46 mah for powering the Arduino Nano battery mah meter itself. So, it's 902 mah divided by (805 plus 46 mah) or the A123 charging was 106% over what was pulled out of the A123 pack. That matches my previous tests on the efficiency of charging those A123 cells.
Last edited by vollrathd; Jul 12, 2019 at 10:53 PM.
Jul 13, 2019, 02:30 AM
Entropy is happening!
Jim.Thompson's Avatar
Subscribed, and reading further.
Thanks Vollrathd!
Jul 15, 2019, 12:10 AM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP
Quote:
Originally Posted by Jim.Thompson
Subscribed, and reading further.
Thanks Vollrathd!
Hi Jim
The PCB's are ordered and 9 of them should show up this week. If you like, I can send you one of the PCB's for the cost of the postage via a letter or similar means. You all ready have some of the parts involved, the MCP 3424 A/D converter is readily available on Ebay for around $5.00 USA. Send me a PM if you are interested in one of the PCB's.

I'll be building up a couple of them and will post photos on how they turn out.

https://www.ebay.com/itm/MCP3424-ADC...QAAOSwUmtbFQ4m

(I also ran a test on this meter with a 3 % duty cycle at 2 Amp peak currents. It came in within 5% of the calculated value.)
Last edited by vollrathd; Jul 15, 2019 at 12:25 AM.
Jul 15, 2019, 09:18 AM
Registered User
Nice job!
Jul 16, 2019, 07:33 PM
Registered User
GeoffS's Avatar
For storage you might consider one of the micro sd card boards out there. That would give you gonna of storage and an easy way to get the record to a pc.
Jul 16, 2019, 08:48 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP
Quote:
Originally Posted by GeoffS
For storage you might consider one of the micro sd card boards out there. That would give you gonna of storage and an easy way to get the record to a pc.
I bought a half dozen of them through EBay. They are not really small.

That will be a good project during the winter season. It might be a good fit to incorporate into my BATTIR project.
Jul 17, 2019, 02:19 AM
Entropy is happening!
Jim.Thompson's Avatar
Quote:
Originally Posted by vollrathd
Hi Jim
..........................Send me a PM if you are interested in one of the PCB's.
...........................)
PM sent.
Jul 17, 2019, 01:59 PM
Registered User
GeoffS's Avatar
Quote:
Originally Posted by vollrathd
I bought a half dozen of them through EBay. They are not really small.
I just got some too. They are larger than a Pro Mini board...

D'oh.

I'm going to have to get some of the 3424 A/D boards. They look really handy.
Jul 17, 2019, 02:21 PM
Retired Electronics Specialist
vollrathd's Avatar
Thread OP
[QUOTE=GeoffS;42319263


I'm going to have to get some of the 3424 A/D boards. They look really handy.[/QUOTE]

You will like them. They are programmable to have full scale 0-0.06 Volts to 0-2.5 Volts full scale, 12 bits to 18 bits resolution.

You will need the MCP3424 library. I can send a link for it.

They have a precision 2.500 Volt built in voltage reference, along with differential inputs on all 4 channels.

I built a precision four wire micro-ohmmeter with one that is posted in RCGroups. It only uses a few parts, and is quite accurate. It has two auto ranges, The MicroOhmmeter has two auto ranges, 0-50 MilliOhms (0-50,000 uOhms), and 0 - 2 Ohms. It can easily measure the resistance of a 4 inch piece of #12 copper wire.

Here you go!
MicroOhmmeter Project
https://www.rcgroups.com/forums/show...t#post41711449
Last edited by vollrathd; Jul 17, 2019 at 10:57 PM.


Quick Reply
Message:

Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Question Taranis X9D plus, X8R recvr, vario-- why is altitude spoken in "milliamp hours"? aeronaut999 Radios 4 Jan 05, 2017 12:17 AM
Higher milliamp hours = longer flying time? tritonfx Batteries and Chargers 12 Jun 27, 2009 03:15 PM
Where can I get a Milliamp Meter? mrebman Batteries and Chargers 1 Apr 24, 2004 11:35 AM
The milliamp-hour is a unit of... Miami Mike Batteries and Chargers 14 Feb 21, 2004 01:00 AM