Sometimes it might be useful to monitor a battery's voltage or current usage over time. Here we're using an Espruino board and a few passive components to monitor voltage and current, log them, and display them as a graph on the PC.
Connect as in the circuit above. We're using:
But any analog-capable inputs will do.
We're using the Averager Library here to store data in a format that is easy to graph.
var Averager = require("Averager").Averager;
var volts, amps;
var voltAvr = new Averager({scale:1000});
var ampAvr = new Averager({scale:1000});
function onSecond() {
amps = analogRead(D29)*3.3;
volts = analogRead(D31)*3.3*(100+24)/24 - amps;
voltAvr.add(volts);
ampAvr.add(amps);
var data = {
v:Math.round(volts*100)/100,
a:Math.round(amps*100)/100
};
NRF.setAdvertising({},{
name:"\xF0\x9F\x9A\x98", // car emoji, https://apps.timwhitlock.info/emoji/tables/unicode
manufacturer:0x0590,
manufacturerData:JSON.stringify(data)
});
}
setInterval(onSecond, 1000);
NRF.setTxPower(4);
You'll need to serve this off a HTTPS link - see the Web Bluetooth page for more information.
Note: you can try this out as-is just by clicking the Try Me!
link.
<html>
<head>
</head>
<body>
<div id="data"></div>
<script src="https://www.puck-js.com/puck.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script>
<script>
var dataElement = document.getElementById("data");
var voltData, ampData;
var csvData = "";
function addChart(id, voltData, ampData, title) {
var labels = voltData.current.map((y,x)=>x);
if (id == "hrChart") labels = voltData.current.map((y,x)=>`${x>>2}:${((x&3)*15).toString().padStart(2,0)}`);
if (id == "moChart") labels = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec".split(",");
new Chart(document.getElementById(id), {
type: 'line',
data: {
labels : labels,
datasets : [
{ data: voltData.current, label: 'Volts', borderColor: "red",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
{ data: voltData.last, label: 'Last Volts', borderColor: "darkred",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
{ data: voltData.avr, label: 'Average Volts', borderColor: "grey",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
{ data: ampData.current.map(x=>x*10), label: 'Amps x10', borderColor: "green",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
{ data: ampData.last.map(x=>x*10), label: 'Last Amps x10', borderColor: "darkgreen",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
{ data: ampData.avr.map(x=>x*10), label: 'Average Amps x10', borderColor: "grey",
backgroundColor: 'rgba(0, 0, 0, 0)', fill: false, },
]
},
options: {
responsive: true,
title: {
display: true,
text: title
},
tooltips: {
mode: 'index'
}
}
});
}
function getData() {
// get the data
dataElement.innerHTML = '<span style="font-size:300%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)">Loading...</span>';
Puck.write(`\x10voltAvr.print()\n`,data=>{
// if we have a JS prompt at the end of what's printed, remove it
if (data.endsWith(">"))
data = data.slice(0,-1);
voltData = JSON.parse(data);
Puck.write(`\x10ampAvr.print()\n`,data=>{
// if we have a JS prompt at the end of what's printed, remove it
if (data.endsWith(">"))
data = data.slice(0,-1);
ampData = JSON.parse(data);
// Draw graphs
dataElement.innerHTML = `
<div><canvas id="hrChart"></div>
<div><canvas id="dayChart"></div>
<div><canvas id="moChart"></div>`;
addChart('hrChart', voltData.hours, ampData.hours, "Hourly");
addChart('dayChart', voltData.days, ampData.days, "Daily");
addChart('moChart', voltData.months, ampData.months, "Monthly");
});
});
}
Puck.modal(function() {
getData();
});
</script>
</body>
</html>
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.