Software apps and online services
Lead-acid batteries from seasonal equipment, classic cars, etc. are often kept alive with trickle chargers, float chargers or some type of battery maintainer. This is done to prevent a battery from freezing and sulfation, both of which can occur if a battery is stored in a discharged state. Both of these conditions can easily happen over a long cold winter if the battery is not kept in a charged state.
Hydrogen gas is one of the by-products of the charging process of flooded lead-acid batteries. The amount is very little with small charge currents, but still, it is safer to charge lead-acid batteries in a well ventilated area where you are not too concerned about the other hazards of working around them due to the sulfuric acid they contain. This is why I charge most of my seasonal batteries in an outdoor shed with gable vents.
Simply put - battery clips. They have a habit of corroding when left connected to the lead posts of a lead-acid battery. For this reason, I used to go out to the shed with a multimeter to check my batteries regularly over the winter to make sure the chargers were still working. You can see my setup in the video below.
- Eliminate trips out to the shed in the middle of winter unless there is a problem that needs to be corrected.
- Provide insight on the characteristics of a battery charger.
- No modifications to a battery charger.
- Detect a battery charger failure.
- Provide access to the data anywhere internet access is available.
The Battery Charger Monitor can measure the following:
- Voltage (peak)
- Current (peak & average)
Each group of measurements is associated with a date, time and index number. The measurements are sent in JSON format over a wireless link by a Helium Atom to a Helium Element access point and then to the Helium Dashboard via an Ethernet connection every 20 seconds.
The JSON format payload of the packets can be viewed in the Helium Dashboard, which also indicates the RSSI of the RF signal from the Atom.
Plots of the measurements can be made, revealing characteristics of the charger and whether or not it is charging the battery. The plots can be viewed with a web browser so I can check up on things anywhere I have access to the internet.
- Some battery chargers do not have a constant current output. By that I mean the current is delivered to the battery as a series of pulses where the amplitude and duty cycle of the pulses determine the amount of current delivered to the battery. I had to find a way to sample the current often enough that I could measure the current accurately. The current is measured over 6000 times a second (due to the fact that the pulses are so narrow) to facilitate measuring the peak and average levels. The oscilloscope pictures below are with the BatteryMINDer Plus charger in float mode. The 3rd picture shows that the peak current (IP) is what was measured with the oscilloscope and the average current (IA) is much less, as expected.
- Some battery chargers use such a high current pulse that it affected voltage measurements if the measurement happened to be made when the current was on. I was initially measuring the voltage once per 20 seconds through just a voltage divider. In order to make more accurate voltage measurements an RC filter was added and the voltage is measured every 250 ms.
- I started out using the Arduino JSON library but ran into suspected stack space issues. I had to find a more memory efficient way to create the JSON formatted payload that is sent via the Helium Atom.
I have 4 different models of small chargers intended to maintain batteries. They all have a different approach to charging batteries as the following plots show.
The first plot was taken after I recorded the video. The positive clip did not make a good connection when I put it back on the battery and I only discovered that the next morning when I looked at the data being captured. The voltage was staying at a steady 11.65 volts and the current was zero amps. So I went to the shed and twisted the positive clip back and forth a few times. The charger immediately started charging the battery.
The plot also shows that this charger uses a constant current mode. I was able to determine that it charges in that mode at 0.88 amps which is 10% more than the 0.8 amp rating on it. When it exits this mode the current gently tapers off until about 1/2 an amp (when the voltage reached 14.64 volts) and then drops to zero.
This particular charger lets the battery voltage drop back down to about 12.8 volts and then charges it up again. It took the battery about 3 hours to drop that low.
It took about 35 minutes to charge the battery after it sat all night with a bad connection to the charger and about 15 minutes the next charge cycle.
I also discovered that the battery gets charged more often when the temperature is higher. At high temperatures it was charged about every 2 hours and at low temperatures it was charged about every 3 hours. I am looking forward to seeing how often it will be charged when it is -30 degrees. The following plot also shows that it is possible to dress up the plots to make them look quite nice. You will also notice that there appears to be some thermal lag since the inter-charge times were shortest when the shed was past the maximum temperature and cooling down. This is likely due to the mass of the battery.
The next charger I tested is a float charger that is rated at 0.75 amps. I suspected it was not working because I had never seen a voltage from it higher than about 12.8 volts, which seems like a very low float voltage according to the article "Float voltage" in Wikipedia. For this reason I had stopped using it. For this test I decided to discharge the battery with a 50 amp load tester for about 15 seconds to see if that would make a difference. I disconnected the battery clips from the monitor while I did the load test so the voltage and current dropped to zero during that time.
To my surprise the charger actually did charge the battery when I reconnected the battery clips. It even exceeded the 0.75 amp rating on the charger by over 250 mA. However, the thing I don't like about it is shown in the next plot. It lets the battery voltage drop down to somewhere between 12.7 and 12.82 volts and keeps it there. The current is only 5 mA most of the time with the occasional pulse of 49 mA.
I really like this one. It initially charged the battery after I did another load test. The peak current was 1.22 amps which tapered off as the battery voltage rose to 14.4 volts which the manual stated is the charge termination voltage.
After the battery reached the termination voltage it maintained a very steady float voltage of 13.49 volts which took about 60 mA to do.
The first 3 chargers can only charge 12V batteries but this one can charge 6V or 12V batteries. It uses pulses of current that are in sync with zero crossings of the AC supply (60 Hz where I live) as can be seen in the oscilloscope picture below. As already mentioned I had to find a way to measure the peak and average current on chargers that use pulses. The measurement technique precludes the use of any delay statements in the firmware and is very light on memory usage. I found it to be surprisingly accurate and did not have to resort to fixed point math to accomplish this since even with some floating point math operations there are around 130, 000 to 140, 000 samples per reporting period.
So far, I think it is evident that a lot can be learned about battery chargers with this project. The fact it was already able to detect a failed connection of a battery clip validates it as having the potential to meet my primary goal of not having to regularly go out to the shed with my multimeter to measure the battery voltage in the middle of winter.
It will help me steer clear of chargers that may not keep my batteries fully charged and will detect outright failures of the battery charger itself.
This project also met the goal of not making any modifications to the battery chargers. This is because all of the battery chargers (from 4 different manufacturers) use the same plug with the same polarity. This allows them to connect to battery clips or to a harness with a fuse and ring terminals. I will actually be using some of the ring terminal harnesses with proper battery clamps in an attempt to avoid the corrosion that occurs with the battery clips.
As far as access is concerned, I can even view the data on my phone.
By far, the most time spent was in figuring out how to setup the Google Cloud Platform to deal with the measurements sent to it via the Helium Dashboard and make them available for plotting by Google Data Studio.
It can be overwhelming at first when you see how flexible the Google Cloud Platform is, so I decided to provide some details on what is involved to make it easier for others to work with it. Having said that, there are probably other ways to have done this. Certainly, most of it can also be done using the Google Cloud SDK that you can install locally. Then you can set things up using the command line if you wish.
Depicted below is the path the data will take from the Battery Charger Monitor to to a web browser. As you can see, I am only using a subset of the Google Cloud Platform.
To get started you will need accounts for both the Helium Dashboard and Google IoT Core.
There are many helpful tutorials and lists of instructions such as the ones shown here. I have marked the steps to follow.
Actually, step 1 in the instructions above may be missing if you are already signed into Google. Expect to see the following if you are not signed in.
Go to the Manage Resources Page
Create a project.
The following page should appear. You can access billing information and see which APIs are enabled by default at this point if you wish. If you don't do it now that is not a problem. When I created my first project on the site and tried to use certain features it prompted me to enable billing and certain APIs when that was necessary.
Create a registry in Google Cloud IoT Core.
There is a navigation menu on the left side of the title bar. Clicking it will allow you to navigate to other pages. Select "IoT Core" in the BIG DATA group to go there.
This is one of those instances where Google will prompt you to enable an API so go ahead and click the "Enable API" button.
It will then prompt you to create a device registry.
Once you have entered a name for the "Registry ID", selected a "Region" and selected the "Protocols", you need to create a "Default telemetry topic". A popup window appears where you enter a topic name. In my case, I entered "Meas" and clicked the "CREATE" button. This will dismiss the popup window and allow you to click the "Create" button at the bottom left of the page.
Create a service account.
Make sure "New service account" is selected. Give the service account a name of your choice and select the "Owner" Role. Make sure the Key type is "JSON" and click the "Create" button.
Clicking the Create button causes a private key file to be generated and stored on your computer. Make sure you know where it is being stored. It will be needed to create a channel to the Google Cloud IoT Core on the Helium Dashboard.
Add the Helium Atom and Element to the Helium Dashboard. When you created your Helium account you probably noticed they have a very clean looking dashboard. It doesn't matter which one you do first.
The instructions for adding the Helium Atom are very clear.
The instructions for adding the Helium Element are the same.
Create a channel for communication with Google Cloud IoT Core.
On the channels page you can select which type of channel you want to create. Click on "Google Cloud IoT Core" in the group of channel types they allow you to create.
Fill in the "Registry ID" with the name you used when you created the registry in Google Cloud IoT Core (step 4 above). You have to type in the "Region" even though there is a shaded one present when you reach this page. If you neglect to do this you will not be able to scroll down to step 3 on this page.
Open the private key file that was created in step 5 above with a text editor. Copy the entire contents of the file and paste it into the "JSON Private Key" box.
Now that these fields are filled in you should be able to scroll down to step 3 on this page.
Enter the "Channel Name" you want to use in the Helium Dashboard to identify this channel. This name will be used in the code you write and will also appear in the sample code that is automatically generated for you by the fine folks at Helium. The code is generated for three different platforms and they have done an awesome job of getting you up and running quickly so you can verify the Atom is able to communicate with the Element access point and the Dashboard. Step 4 will appear after you click the "Next" button.
In order to compile the code you first need to install the Helium library. Then you can copy the code they have generated and paste it into the Arduino IDE. The only problem I ran into was a missing header file called "Board.h", which I found in their example programs.
Once you are able to compile and load the program you should be able to see data packets being sent from the Atom to the Dashboard via the Element.
The Battery Charger Monitor will be sending much larger packets and the data will be in JSON format as shown below. Since the shed is further away from where I was running the generated code from the Dashboard there is also a difference in the RSSI, as expected.
Enable the Pub/Sub API.
If you have not enabled the API yet you will be prompted to do so.
You should now see the entire path of the topic name you created in step 4.
NOTE: I strongly suggest you save this in a text file so it can be easily copied and pasted into another form later.
Create a BigQuery Database.
First make sure the correct project is selected.
Once the project is selected you need to create a new dataset.
Enter a "Dataset ID", select the "Data location" nearest you and click the "OK" button.
Now that we have a dataset it is time to create a table.
We will create an empty table and give it a "Destination Table" name.
For each column in the table we need to give it a "Name", select a "Type" and click the "Add Field" button.
Once all of the fields have been added you need to click the "Create Table" button.
After the table has been created the "Table Details" will be displayed. Click the "Query Table" button.
Add the "Names" from the table as a comma separated list. Also, now is an excellent time to copy the complete path of the table. I strongly suggest you save this in the same text file you hopefully created in step 8 so it can be easily copied and pasted into another form later.
Running a query by clicking the "RUN QUERY" button should show you the column header and indicate that the query returned zero records. This is correct since no records have been added to the table yet.
Set up a Dataflow job.
The first time you enter Dataflow they want to guide you through a tutorial. I found that if you do not go through the tutorial there are certain permissions that are not set up. Save yourself a lot of grief and go through the tutorial. The needed APIs will be enabled and a storage bucket will be created which you can use later.
As in steps 8 and 9, copy the path of the bucket you create as part of the tutorial and save it in the same text file used for the topic and table path names. All paths will be needed when setting up the Dataflow job.
After you have finished the tutorial click the "CREATE JOB FROM TEMPLATE" button.
Enter a "Job name" for the job and select the "PubSub to BigQuery" template from the "Cloud Dataflow template" list.
Select the "Regional endpoint". Next, simply copy and paste the topic, table and storage bucket paths you have in the text file you created for them. Note that I have added "/tmp" to the end of the "Temporary Location". When finished entering all of the information click the "Run job" button.
You should see the job start up on the page that appears after you clicked the "Run job" button.
Nothing will be displayed to the left of "LOGS" on the top line if there are no problems. If there are errors, click on the "LOGS" button to view the error messages.
Go to the Google Data Studio site and create nice looking plots (graphs).
You can enter a new name for the report or you can do that later. At this point we need to add a data source.
Find BigQuery and select it.
This will present a page that allows you to select the "Project", "Dataset" and "Table"
After clicking the "CONNECT" button a page will appear with a summary of the data names in the table. Clicking the "ADD TO REPORT" button will cause a confirmation popup to appear.
In the main window click on "Combo chart".
Drag out an outline of how large you want the chart to be.
Use the "DATA" and "STYLE" tabs on the right to select the items you want to display and how you want to display it. There are many things you can do here so explore the options available to you in DataStudio.
You can see the TX jumper is on pin 8 and the RX jumper is on pin 9 on the shield near the SMA connectors for the antennas. All connections were made with male to female jumper wires and ring terminals at the binding posts. The binding posts are used as test points so a multimeter or oscilloscope can be used to read the voltage and current locally.
In the shed I let the BME680 board sit just out of the box so it is reading the shed temperature instead of the temperature inside the box.
To compile the code you need to install the following libraries:
- BlueDot BME680
Do the same for the Helium library. After a library is installed it will show the version and say "INSTALLED".
The flow diagram shows the concept used to ensure that current measurements are given priority. This makes it possible to measure the narrow pulses of current.