Espruino:Примеры/Отслеживание заряда батареи

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Отслеживание заряда батареи[1]

DIY Car Battery monitor

Иногда может пригодиться возможность отслеживать напряжение батареи, а также динамику энергопотребления в течение некоторого промежутка времени. В этом руководстве мы при помощи Espruino и нескольких пассивных компонентов создадим проект, который будет отслеживать напряжение и силу тока, записывать их и показывать на графике на ПК.

Вам понадобятся

  • Интерфейсная плата MDBT42Q, но подойдет и любая другая Bluetooth-плата Espruino (хотя Puck.js придется питаться самому, т.к. у него нет регулятора напряжения)
  • Один резистор на 1 Ом (мощностью 1 ватт или больше)
  • Два резистора на 100 кОм
  • Один резистор на 24 кОм
  • Два конденсатора (в этом примере используется конденсатор на 0.1 мкФ, но подойдет и почти любой другой)

Подсоединение

Подсоединяем компоненты как на схеме выше:

  • 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>

См.также

Внешние ссылки