Пример интерфейса через Blynk и Народный мониторинг

Простая моргалка на ESP8266,  напряжение и ток измеряются с помощью INA226.

Схема:

SH16-ESP8266-INA226-P-180915

Алгоритм никак не контролирует зарядный процесс, постоянно измеряет Rimp с помощью зарядных импульсов, через каждые 50 циклов измеряет Rgost разрядным импульсом по ГОСТовской методике.

В данном примере использовалась сильно засульфатированная батарея, поэтому и результаты соответствующие.

При каждом измерении Rg результаты выводятся через Blynk на телефон:

phone

И каждые 5 минут дублируются в базу Народного мониторинга:

NarMon

NarMon2

Скетч:


#define BLYNK_PRINT Serial
#include
#include
#include
#include
#include
#define postingInterval 330000 // интервал между отправками данных в миллисекундах (5 минут)
unsigned long lastConnectionTime = 0; // время последней передачи данных
char auth[] = "код Blynk";
char ssid[] = "точка доступа";
char pass[] = "пароль";
int pin = 16;
int pinR67 = 14;
int pinR6 = 15;
unsigned long t;
unsigned long t1;
unsigned long t2;
int busvolt = 0;
int shuntvolt = 0;
float Uakb = 0;
float Iakb = 0;
float UAK = 0;
float U1 = 0;
float I1 = 0;
float I = 0;
float Rimp = 0;
float U2 = 0;
float I2 = 0;
float R = 0;
float Rg = 0;
int iii = 0;
#define debug true // вывод отладочных сообщений
String Hostname; //имя железки - выглядит как ESPAABBCCDDEEFF т.е. ESP+mac адрес.
void setup() {
Serial.begin(115200);
pinMode(pin, OUTPUT); // - на затвор мосфета заряда
digitalWrite(pin, LOW); //
pinMode(pinR67, OUTPUT); // - на затвор мосфета разряда
digitalWrite(pinR67, LOW); //
pinMode(pinR6, OUTPUT); // - на затвор мосфета разряда
digitalWrite(pinR6, LOW); //
Wire.begin();
ina_write(0x00, 0x8000); //reset
ina_write(0x00, 0x41ff);// значение конфигурационного регистра по даташиту
// 0100 000 111 111 111 = 0x41ff 1 8244 8244 cont
// 0100 000 110 110 011 = 0x41b3 1 4156 4156 trig
// 0100 000 100 100 011 = 0x4123 1 1100 1100 trig
// 0100 000 010 010 011 = 0x4093 1 322 322 trig
delay2(20);
int busvolt = ina_read(0x02);
float Uakb = (float)busvolt / 1000 * 1.25; // LSB=1.25mv
int shuntvolt = ina_read(0x01);
if (shuntvolt > 32000) shuntvolt = (65535 - shuntvolt) * (-1);
float Iakb = (float)shuntvolt / 1000000 * 2.5 / 0.01; //LSB=2.5mkv Rsh=0.01 Ohm
Serial.println();
Serial.print(Uakb, 6); Serial.println(" Uakb, V");
Serial.print(Iakb, 6); Serial.println(" Iakb, A");
Serial.println();
Serial.print(ina_read(0x00), BIN); Serial.print(" / ");
Serial.println(ina_read(0x05));
Serial.println();
delay2(1000);
Blynk.begin(auth, ssid, pass);
Hostname = "ESP" + WiFi.macAddress();
Hostname.replace(":", "");
WiFi.hostname(Hostname);
// wifimanstart();
Serial.println(WiFi.localIP()); Serial.println(WiFi.macAddress()); Serial.print("Narodmon ID: "); Serial.println(Hostname);
}
bool SendToNarodmon() { // Собственно формирование пакета и отправка.
WiFiClient client;
// DeviceAddress tempDeviceAddress;
String buf;
buf = "#" + Hostname + "\r\n"; // заголовок
buf = buf + "#UAK#" + String(UAK) + "\r\n";
buf = buf + "#U1#" + String(U1) + "\r\n";
buf = buf + "#I#" + String(I) + "\r\n";
buf = buf + "#Rg#" + String(Rg) + "\r\n";
buf = buf + "#Rimp#" + String(Rimp) + "\r\n";
buf = buf + "##\r\n"; // закрываем пакет
if (!client.connect("narodmon.ru", 8283)) { // попытка подключения
Serial.println("connection failed");
return false; // не удалось;
} else
{
client.print(buf); // и отправляем данные
if (debug) Serial.print(buf);
while (client.available()) {
String line = client.readStringUntil('\r'); // если что-то в ответ будет - все в Serial
Serial.print(line);
}
}
return true; //ушло
}
void loop() {
Blynk.run();
Rimp = 0;
t = micros();
for (int j = 1; j <= 100; j++) { ina_write(0x00, 0x8000); ina_write(0x00, 0x4093); delayMicroseconds2(950); busvolt = ina_read(0x02); UAK = (float)busvolt / 1000 * 1.25; digitalWrite(pin, HIGH); // ina_write(0x00, 0x8000); ina_write(0x00, 0x4093); delayMicroseconds2(950); busvolt = ina_read(0x02); shuntvolt = ina_read(0x01); digitalWrite(pin, LOW); // U1 = (float)busvolt / 1000 * 1.25; if (shuntvolt > 32000) shuntvolt = (65535 - shuntvolt);
I = (float)shuntvolt / 1000000 * 2.5 / 0.01; //LSB=2.5mkv Rsh=0.01 Ohm
Rimp += (U1 - UAK) / I;
}
Rimp = Rimp / 100;
t = micros() - t;
Serial.print(UAK, 3); Serial.print(" UAK, V ");
Serial.print(U1, 3); Serial.print(" U1, V ");
Serial.print(I, 3); Serial.print(" I, A ");
// Serial.print(t); Serial.print(" mks , imp ");
Serial.print(Rg, 6); Serial.print(" Rgost, Ohm ");
Serial.print(Rimp, 6); Serial.println(" Rimp, Ohm ");
// Serial.println(iii);
iii ++;
if (iii > 50) {
iii = 0;
Blynk.virtualWrite(V0, UAK); //U НРЦ
Blynk.virtualWrite(V1, U1); //U Имп
Blynk.virtualWrite(V2, I); //ток
Blynk.virtualWrite(V3, Rg); //R ГОСТ
Blynk.virtualWrite(V4, Rimp); //R ИМП
if (millis() - lastConnectionTime > postingInterval) { // ждем 5 минут и отправляем
if (WiFi.status() == WL_CONNECTED) { // ну конечно если подключены
if (SendToNarodmon()) {
lastConnectionTime = millis();
} else {
lastConnectionTime = millis() - postingInterval + 15000; //следующая попытка через 15 сек
}
} else {
lastConnectionTime = millis() - postingInterval + 15000; //следующая попытка через 15 сек
Serial.println("Not connected to WiFi");
}
}
digitalWrite(pinR67, HIGH); //
ina_write(0x00, 0x41ff);
delay2(3000);
t1 = micros();
busvolt = ina_read(0x02);
shuntvolt = ina_read(0x01);
t1 = micros() - t1;
U1 = (float)busvolt / 1000 * 1.25; // LSB=1.25mv
if (shuntvolt > 32000) shuntvolt = (65535 - shuntvolt);
I1 = (float)shuntvolt / 1000000 * 2.5 / 0.01; //LSB=2.5mkv Rsh=0.01 Ohm
digitalWrite(pinR6, HIGH); //
ina_write(0x00, 0x41ff);
delay2(1000);
t2 = micros();
busvolt = ina_read(0x02);
shuntvolt = ina_read(0x01);
t2 = micros() - t2;
digitalWrite(pinR67, LOW); //
digitalWrite(pinR6, LOW); //
U2 = (float)busvolt / 1000 * 1.25; // LSB=1.25mv
if (shuntvolt > 32000) shuntvolt = (65535 - shuntvolt);
I2 = (float)shuntvolt / 1000000 * 2.5 / 0.01; //LSB=2.5mkv Rsh=0.01 Ohm
Rg = (U1 - U2) / (I2 - I1);
// Serial.print(U1, 3); Serial.print(" U1, V ");
// Serial.print(I1, 3); Serial.print(" I1, A ");
// Serial.print(t1); Serial.println(" mks t1 ");
// Serial.print(U2, 3); Serial.print(" U2, V ");
// Serial.print(I2, 3); Serial.print(" I2, A ");
// Serial.print(t2); Serial.println(" mks t2 ");
// Serial.print(Rg, 6); Serial.println(" Rgost, Ohm ");
delay2(1000);
// Serial.println();
}
} // loop
// функция записи в конфигурационные регистры INA2**
void ina_write(byte adr, int cfg) {
Wire.beginTransmission(0x40);
Wire.write(adr);
Wire.write((cfg >> 8) & 0xFF);
Wire.write(cfg & 0xFF);
Wire.endTransmission();
}
//функция чтения данных из регистров INA2**
int ina_read(byte adr) {
Wire.beginTransmission(0x40);
Wire.write(adr);
Wire.endTransmission();
Wire.requestFrom(0x40, 2);
int value = ((Wire.read() << 8) | Wire.read());
return value;
}
void delay2(long mill) {
unsigned long tim = millis();
do {
yield();
}
while (millis() - tim < mill);
}
void delayMicroseconds2(long micr) {
unsigned long tim = micros();
do {
yield();
}
while (micros() - tim < micr);
}