Espruino:Примеры/Отслеживание заряда батареи: различия между версиями
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Myagkij (обсуждение | вклад) (Новая страница: «{{Espruino/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[ www.espruino.com - ]</ref>= <syntaxhighligh...») |
Myagkij (обсуждение | вклад) Нет описания правки |
||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=<ref>[ www.espruino.com - ]</ref>= | =Отслеживание заряда батареи<ref>[https://www.espruino.com/Battery+Monitor www.espruino.com - ]</ref>= | ||
[https://www.youtube.com/watch?v=VNjZB92O88U&feature=emb_title DIY Car Battery monitor] | |||
Иногда может пригодиться возможность отслеживать напряжение батареи, а также динамику энергопотребления в течение некоторого промежутка времени. В этом руководстве мы при помощи [[Espruino]] и нескольких пассивных компонентов создадим проект, который будет отслеживать напряжение и силу тока, записывать их и показывать на графике на [[ПК]]. | |||
== Вам понадобятся == | |||
* Интерфейсная плата [https://www.espruino.com/MDBT42Q MDBT42Q], но подойдет и любая другая Bluetooth-плата Espruino (хотя [https://www.espruino.com/Puck.js Puck.js] придется питаться самому, т.к. у него нет регулятора напряжения) | |||
* Один резистор на [[1 Ом]] (мощностью 1 ватт или больше) | |||
* Два резистора на [[100 кОм]] | |||
* Один резистор на [[24 кОм]] | |||
* Два конденсатора (в этом примере используется конденсатор на [[0.1 мкФ]], но подойдет и почти любой другой) | |||
== Подсоединение == | |||
[[File:espruino_Battery_Monitor.jpg|center]] | |||
Подсоединяем компоненты как на схеме выше: | |||
* '''D31''' – для считывания напряжения | |||
* '''D29''' – для считывания силы тока | |||
== Код == | |||
Мы воспользуемся здесь [https://www.espruino.com/Averager библиотекой Averager], где есть формат, упрощающий вывод данных на график. | |||
<syntaxhighlight lang="javascript" enclose="div"> | <syntaxhighlight lang="javascript" enclose="div"> | ||
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", // эмодзи машинки, https://apps.timwhitlock.info/emoji/tables/unicode | |||
manufacturer:0x0590, | |||
manufacturerData:JSON.stringify(data) | |||
}); | |||
} | |||
setInterval(onSecond, 1000); | |||
NRF.setTxPower(4); | |||
</syntaxhighlight> | |||
==Веб-страница== | |||
Эту страницу нужно будет хостить с помощью [[HTTPS]] – более подробно читайте [https://www.espruino.com/Web+Bluetooth тут]. | |||
'''Примечание:''' Можете попробовать код ниже как есть, просто нажав на кнопку '''«Попробуй!»''' под кодом. | |||
<syntaxhighlight lang="html5" enclose="div"> | |||
<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() { | |||
// считываем данные: | |||
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=>{ | |||
// если в конце напечатанного текста стоит JS-символ приглашения, | |||
// удаляем его: | |||
if (data.endsWith(">")) | |||
data = data.slice(0,-1); | |||
voltData = JSON.parse(data); | |||
Puck.write(`\x10ampAvr.print()\n`,data=>{ | |||
// если в конце напечатанного текста стоит | |||
// JS-символ приглашения, удаляем его: | |||
if (data.endsWith(">")) | |||
data = data.slice(0,-1); | |||
ampData = JSON.parse(data); | |||
// рисуем графики: | |||
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> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Версия от 22:23, 28 февраля 2021
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Отслеживание заряда батареи[1]
Иногда может пригодиться возможность отслеживать напряжение батареи, а также динамику энергопотребления в течение некоторого промежутка времени. В этом руководстве мы при помощи Espruino и нескольких пассивных компонентов создадим проект, который будет отслеживать напряжение и силу тока, записывать их и показывать на графике на ПК.
Вам понадобятся
- Интерфейсная плата MDBT42Q, но подойдет и любая другая Bluetooth-плата Espruino (хотя Puck.js придется питаться самому, т.к. у него нет регулятора напряжения)
- Один резистор на 1 Ом (мощностью 1 ватт или больше)
- Два резистора на 100 кОм
- Один резистор на 24 кОм
- Два конденсатора (в этом примере используется конденсатор на 0.1 мкФ, но подойдет и почти любой другой)
Подсоединение
![](/ruwiki/images/1/17/Espruino_Battery_Monitor.jpg)
Подсоединяем компоненты как на схеме выше:
- D31 – для считывания напряжения
- D29 – для считывания силы тока
Код
Мы воспользуемся здесь библиотекой Averager, где есть формат, упрощающий вывод данных на график.
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", // эмодзи машинки, https://apps.timwhitlock.info/emoji/tables/unicode
manufacturer:0x0590,
manufacturerData:JSON.stringify(data)
});
}
setInterval(onSecond, 1000);
NRF.setTxPower(4);
Веб-страница
Эту страницу нужно будет хостить с помощью HTTPS – более подробно читайте тут.
Примечание: Можете попробовать код ниже как есть, просто нажав на кнопку «Попробуй!» под кодом.
<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() {
// считываем данные:
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=>{
// если в конце напечатанного текста стоит JS-символ приглашения,
// удаляем его:
if (data.endsWith(">"))
data = data.slice(0,-1);
voltData = JSON.parse(data);
Puck.write(`\x10ampAvr.print()\n`,data=>{
// если в конце напечатанного текста стоит
// JS-символ приглашения, удаляем его:
if (data.endsWith(">"))
data = data.slice(0,-1);
ampData = JSON.parse(data);
// рисуем графики:
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>
См.также
Внешние ссылки