diff --git a/src/BL0942/shelly_pm_bl0942.cpp b/src/BL0942/shelly_pm_bl0942.cpp index 049e4d69..0bdca1a6 100644 --- a/src/BL0942/shelly_pm_bl0942.cpp +++ b/src/BL0942/shelly_pm_bl0942.cpp @@ -36,24 +36,40 @@ BL0942PowerMeter::BL0942PowerMeter(int id, int tx_pin, int rx_pin, BL0942PowerMeter::~BL0942PowerMeter() { } +#define BL_READ 0x58 + +#define BL_WRITE 0xA8 + +#define BL_SOFT_RESET 0x1C + +#define BL_ADDR 0x0 + +#define BL_WATT 0x6 + Status BL0942PowerMeter::Init() { if (rx_pin_ < 0 && tx_pin_ < 0) { return mgos::Errorf(STATUS_INVALID_ARGUMENT, "no valid pins"); } struct mgos_uart_config ucfg; + mgos_uart_config_set_defaults(uart_no_, &ucfg); - ucfg.baud_rate = 4800; + ucfg.baud_rate = 9600; ucfg.dev.rx_gpio = rx_pin_; ucfg.dev.tx_gpio = tx_pin_; if (!mgos_uart_configure(uart_no_, &ucfg)) { - LOG(LL_ERROR, ("Failed to configure UART%d", uart_no_)); + return mgos::Errorf(STATUS_INVALID_ARGUMENT, "Failed to configure UART"); } + mgos_uart_set_rx_enabled(uart_no_, true); + meas_timer_.Reset(meas_time_ * 1000, MGOS_TIMER_REPEAT); LOG(LL_INFO, ("BL0942 @ %d/%d", rx_pin_, tx_pin_)); + + // this->WriteReg(BL_SOFT_RESET, 0x5a5a5a5a); + return Status::OK(); } @@ -65,40 +81,59 @@ StatusOr BL0942PowerMeter::GetEnergyWH() { return aea_; } -#define BL_READ 0x58 -#define BL_ADDR 0x3 +bool BL0942PowerMeter::WriteReg(uint8_t reg, uint32_t val) { + uint8_t tx_buf[6] = {BL_WRITE | BL_ADDR, + reg, + (uint8_t) ((val >> 0) & 0xFF), + (uint8_t) ((val >> 8) & 0xFF), + (uint8_t) ((val >> 16) & 0xFF), + 0}; -#define BL_WATT 0x6 + for (int i = 0; i < 5; i++) { + tx_buf[5] += tx_buf[i]; + } + tx_buf[5] = tx_buf[5] ^ 0xFF; + mgos_uart_write(uart_no_, tx_buf, 6); + mgos_uart_flush(uart_no_); + return true; +} bool BL0942PowerMeter::ReadReg(uint8_t reg, uint8_t *rx_buf, size_t len) { uint8_t tx_buf[2] = {BL_READ | BL_ADDR, reg}; - mgos_uart_write(uart_no_, tx_buf, 2); - mgos_uart_flush(uart_no_); + size_t j = mgos_uart_write(uart_no_, tx_buf, 2); + size_t j1 = mgos_uart_write_avail(uart_no_); + //mgos_uart_flush(uart_no_); + LOG(LL_ERROR, ("tx %i %i %02X %02X", j, j1, tx_buf[0], tx_buf[1])); // Delay to allow data to be available int baud = 4800; - mgos_msleep(roundf(len * 8 / baud) * 1e3); + // mgos_msleep(roundf(len * 8 / baud) * 1e3); + bool bla = mgos_uart_is_rx_enabled(uart_no_); int read_len = mgos_uart_read(uart_no_, rx_buf, len); + LOG(LL_ERROR, ("rx %i %i", read_len, bla)); uint8_t chksum = tx_buf[0] + tx_buf[1]; - for (int i = 0; i < len - 1; i++) { + for (int i = 0; i < len; i++) { chksum += rx_buf[i]; LOG(LL_ERROR, ("%08X", rx_buf[i])); } chksum ^= 0xFF; if (read_len != len || rx_buf[len - 1] != chksum) { - LOG(LL_ERROR, ("wrong checksum") ); + LOG(LL_ERROR, ("wrong checksum")); return false; } return true; } void BL0942PowerMeter::MeasureTimerCB() { - int len = 4; // including 1 checksum byte - uint8_t rx_buf[len]; - if (this->ReadReg(BL_WATT, rx_buf, len)) { + LOG(LL_ERROR, ("timer")); + int len = 20; // including 1 checksum byte + uint8_t rx_buf[len] = {}; + // if (this->ReadReg(0xAA, rx_buf, len)) { + // } + if (this->ReadReg(BL_WATT, rx_buf, 4)) { uint32_t d = rx_buf[2] << 16 | rx_buf[1] << 8 | rx_buf[0]; if (d & (1 << 23)) { d |= 0xFF000000; diff --git a/src/BL0942/shelly_pm_bl0942.hpp b/src/BL0942/shelly_pm_bl0942.hpp index 22b8ea23..900e785a 100644 --- a/src/BL0942/shelly_pm_bl0942.hpp +++ b/src/BL0942/shelly_pm_bl0942.hpp @@ -39,6 +39,7 @@ class BL0942PowerMeter : public PowerMeter { float aea_ = 0; // Accumulated active energy, Wh. // bool ReadReg(uint8_t reg, uint8_t *rx_buf, size_t len); + bool WriteReg(uint8_t reg, uint32_t val); mgos::Timer meas_timer_; }; diff --git a/src/ShellyMini1PMGen3/shelly_init.cpp b/src/ShellyMini1PMGen3/shelly_init.cpp index f56b714c..abdbe152 100644 --- a/src/ShellyMini1PMGen3/shelly_init.cpp +++ b/src/ShellyMini1PMGen3/shelly_init.cpp @@ -40,15 +40,15 @@ void CreatePeripherals(std::vector> *inputs, sys_temp->reset(new TempSensorSDNT1608X103F3950(3, 3.3f, 10000.0f)); #endif - std::unique_ptr pm(new BL0942PowerMeter(1, 6, 7, 100, 1)); + std::unique_ptr pm(new BL0942PowerMeter(1, 6, 7, 20, 1)); // BL0942 GPIO6 TX GPIO7 RX - // const Status &st = pm->Init(); - // if (st.ok()) { - // pms->emplace_back(std::move(pm)); - // } else { - // const std::string &s = st.ToString(); - // LOG(LL_ERROR, ("PM init failed: %s", s.c_str())); - // } + const Status &st = pm->Init(); + if (st.ok()) { + pms->emplace_back(std::move(pm)); + } else { + const std::string &s = st.ToString(); + LOG(LL_ERROR, ("PM init failed: %s", s.c_str())); + } InitSysLED(LED_GPIO, LED_ON); InitSysBtn(BTN_GPIO, BTN_DOWN);