chciałem:
1. zastosować INA3221 do pomiaru 3 prądów i stworzyć 4 KPOPy - możliwość podłączenia do 3 INA.
2. niestety wywala się - wzorowałem się na przykładach, ale nie podoba pewnie się sposób inicjacji KPOP w zależności od wykrytych INA adresów na i2c..
@klew pomożesz?
Code: Select all
// ===== ESP32-C3 mini/esp8266 + auto-discovery INA3221 (1..3 szt.) + KPOP =====
//Użycie biblioteki Wire w wersji 1.0 z folderu: C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\Wire
//Użycie biblioteki Adafruit INA3221 Library w wersji 1.0.3 z folderu: C:\Users\Grzeg\OneDrive\Dokumenty\Arduino\libraries\Adafruit_INA3221_Library
//Użycie biblioteki Adafruit BusIO w wersji 1.17.2 z folderu: C:\Users\Grzeg\OneDrive\Dokumenty\Arduino\libraries\Adafruit_BusIO
Użycie biblioteki SPI w wersji 1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\SPI
Użycie biblioteki SuplaDevice w wersji 25.2 z folderu: C:\Users\Grzeg\OneDrive\Dokumenty\Arduino\libraries\SuplaDevice
Użycie biblioteki ESP8266WiFi w wersji 1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WiFi
Użycie biblioteki ESP8266WebServer w wersji 1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WebServer
Użycie biblioteki ESP8266HTTPUpdateServer w wersji 1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPUpdateServer
Użycie biblioteki EEPROM w wersji 1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\EEPROM
Użycie biblioteki LittleFS w wersji 0.1.0 z folderu: //C:\Users\Grzeg\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\LittleFS
#include <Wire.h>
#include <Adafruit_INA3221.h>
#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
// ---------- I2C / PŁYTKA ---------- pod esp8266
#ifndef SDA_PIN
#define SDA_PIN 4
#endif
#ifndef SCL_PIN
#define SCL_PIN 5
#endif
// Potencjalne adresy INA3221 (A0/A1 konfiguracja)
const uint8_t INA_ADDRS[] = {0x40, 0x41, 0x42, 0x43};
const size_t INA_ADDRS_CNT = sizeof(INA_ADDRS)/sizeof(INA_ADDRS[0]);
// Rezystory bocznikowe (Ω) kanałów 0..2 — wpisz realne!
const float SHUNT_OHMS[3] = {0.01, 0.01, 0.01};
// ---------- SUPLA ----------
Supla::ESPWifi wifi("UUU", "UUUUU);
// Losowe GUID/AUTHKEY (16 bajtów)
char GUID[SUPLA_GUID_SIZE] = {
UUUUUUUUUU
};
char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {
UUUUUUUUUUUUUUUUUUU
};
// ---------- MAX 3 szt. INA3221 ----------
struct INAEntry {
uint8_t addr;
Adafruit_INA3221 dev;
bool ok = false;
} ina[3]; // zainicjujemy dynamicznie wg liczby wykryć INA
uint8_t ina_found = 0;
// ---------- KPOP: do 10 kanałów (3/6/9 prądów + 1 suma) ----------
static const uint8_t MAX_KPOP = 10;
Supla::Sensor::GeneralPurposeMeasurement* KPOP[MAX_KPOP] = {nullptr};
uint8_t kpop_cnt = 0; // ile faktycznie utworzono
int sum_idx = -1; // index kanału sumy
// Etykiety
String chTitle(uint8_t idx) {
// idx 0..(3*ina_found-1): przeliczymy na (ina#, ch#)
uint8_t ina_idx = idx / 3;
uint8_t ch = idx % 3; // 0..2
return "INA" + String(ina_idx+1) + "_CH" + String(ch+1);
}
void addKPOP(const String& title, const char* unit="A", uint8_t prec=3) {
if (kpop_cnt >= MAX_KPOP) return;
KPOP[kpop_cnt] = new Supla::Sensor::GeneralPurposeMeasurement();
KPOP[kpop_cnt]->setDefaultUnitAfterValue(unit);
KPOP[kpop_cnt]->setDefaultValuePrecision(prec);
KPOP[kpop_cnt]->setInitialCaption(title.c_str());
kpop_cnt++;
}
void setup() {
Serial.begin(115200);
delay(200);
Wire.begin(SDA_PIN, SCL_PIN);
// --- Skan/Initialize INA3221 (max 3 sztuki) ---
for (size_t a = 0; a < INA_ADDRS_CNT && ina_found < 3; ++a) {
uint8_t addr = INA_ADDRS[a];
// szybki ping I2C (opcjonalnie)
Wire.beginTransmission(addr);
uint8_t err = Wire.endTransmission();
if (err != 0) continue;
// próbujemy .begin()
INAEntry &slot = ina[ina_found];
slot.addr = addr;
if (slot.dev.begin(addr, &Wire)) {
for (uint8_t ch=0; ch<3; ch++) slot.dev.setShuntResistance(ch, SHUNT_OHMS[ch]);
slot.ok = true;
ina_found++;
Serial.printf("INA3221 #%u OK @0x%02X\n", ina_found, addr);
}
}
if (ina_found == 0) {
Serial.println("Nie znaleziono INA3221 na I2C (0x40..0x43).");
}
// --- KPOP: 3/6/9 prądów + 1 suma (1→4, 2→7, 3→10) ---
uint8_t wanted = (ina_found * 3) + (ina_found ? 1 : 0);
if (wanted > MAX_KPOP) wanted = MAX_KPOP;
// prądy
for (uint8_t i = 0; i < ina_found*3 && i < MAX_KPOP-1; ++i) {
addKPOP(chTitle(i)); // jednostka "A", prec 3
}
// suma
if (ina_found > 0 && kpop_cnt < MAX_KPOP) {
addKPOP("INA_total");
sum_idx = kpop_cnt - 1;
}
// --- SUPLA start ---
SuplaDevice.begin(GUID, "svrUU.supla.org", "[email protected]", AUTHKEY);
Serial.printf("Znaleziono INA: %u, utworzono KPOP: %u (sum_idx=%d)\n",
ina_found, kpop_cnt, sum_idx);
}
void loop() {
SuplaDevice.iterate();
static uint32_t t = 0;
if (millis() - t < 1000) return;
t = millis();
if (ina_found == 0) return;
// odczyt prądów i publikacja
double sum = 0.0;
uint8_t out_idx = 0;
for (uint8_t n = 0; n < ina_found; ++n) {
INAEntry &e = ina[n];
if (!e.ok) continue;
for (uint8_t ch = 0; ch < 3; ++ch) {
if (out_idx >= kpop_cnt || (sum_idx >= 0 && out_idx == sum_idx)) break;
double amps = (double)e.dev.getCurrentAmps(ch);
if (amps < 0) amps = 0; // obcięcie szumu ujemnego
if (out_idx < MAX_KPOP) {
KPOP[out_idx]->setValue(amps);
}
sum += amps;
out_idx++;
}
}
if (sum_idx >= 0 && sum_idx < kpop_cnt && KPOP[sum_idx]) {
KPOP[sum_idx]->setValue(sum);
}
// Serial diagnostyka
Serial.print("I: ");
for (uint8_t i = 0; i < kpop_cnt; ++i) {
// wypisz wszystkie
Serial.print(i == 0 ? "" : ", ");
if (i == sum_idx) Serial.print("SUM");
else Serial.print(chTitle(i));
}
Serial.print(" | suma=");
Serial.println(sum, 3);
}
