PZEM-004t и Ардуино

bifurkas
Offline
Зарегистрирован: 27.10.2013

Доброго времени, уважаемые! Появилась необходимость соединить модуль контроля электроэнергии PZEM-004t с Ардуино по UART. Есть библиотека: https://github.com/olehs/PZEM004T , но беда в том, что частота опроса порта в этой библиотеке 1 раз в секунду, а мне нужно 10 раз в секунду. Попробовал в файле PZEM004T.cpp поменять значение PZEM_DEFAULT_READ_TIMEOUT с 1000 на 100, белиберда получается. Помогите пожалуйста!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

bifurkas пишет:
Попробовал в файле PZEM004T.cpp поменять значение PZEM_DEFAULT_READ_TIMEOUT с 1000 на 100

Код в студию.

bifurkas
Offline
Зарегистрирован: 27.10.2013
#include "PZEM004T.h"

#define PZEM_VOLTAGE (uint8_t)0xB0
#define RESP_VOLTAGE (uint8_t)0xA0

#define PZEM_CURRENT (uint8_t)0xB1
#define RESP_CURRENT (uint8_t)0xA1

#define PZEM_POWER   (uint8_t)0xB2
#define RESP_POWER   (uint8_t)0xA2

#define PZEM_ENERGY  (uint8_t)0xB3
#define RESP_ENERGY  (uint8_t)0xA3

#define PZEM_SET_ADDRESS (uint8_t)0xB4
#define RESP_SET_ADDRESS (uint8_t)0xA4

#define PZEM_POWER_ALARM (uint8_t)0xB5
#define RESP_POWER_ALARM (uint8_t)0xA5

#define RESPONSE_SIZE sizeof(PZEMCommand)
#define RESPONSE_DATA_SIZE RESPONSE_SIZE - 2

#define PZEM_BAUD_RATE 9600
#define PZEM_DEFAULT_READ_TIMEOUT 1000

#define PZEM_ERROR_VALUE -1.0


PZEM004T::PZEM004T(uint8_t receivePin, uint8_t transmitPin)
{
    SoftwareSerial *port = new SoftwareSerial(receivePin, transmitPin);
    port->begin(PZEM_BAUD_RATE);
    this->serial = port;
    this->_readTimeOut = PZEM_DEFAULT_READ_TIMEOUT;
    this->_isSoft = true;
}

PZEM004T::PZEM004T(HardwareSerial *port)
{
    port->begin(PZEM_BAUD_RATE);
    this->serial = port;
    this->_readTimeOut = PZEM_DEFAULT_READ_TIMEOUT;
    this->_isSoft = false;
}

PZEM004T::~PZEM004T()
{
    if(_isSoft)
        delete this->serial;
}

void PZEM004T::setReadTimeout(unsigned long msec)
{
    _readTimeOut = msec;
}

float PZEM004T::voltage(const IPAddress &addr)
{
    uint8_t data[RESPONSE_DATA_SIZE];

    send(addr, PZEM_VOLTAGE);
    if(!recieve(RESP_VOLTAGE, data))
        return PZEM_ERROR_VALUE;

    return (data[0] << 8) + data[1] + (data[2] / 10.0);
}

float PZEM004T::current(const IPAddress &addr)
{
    uint8_t data[RESPONSE_DATA_SIZE];

    send(addr, PZEM_CURRENT);
    if(!recieve(RESP_CURRENT, data))
        return PZEM_ERROR_VALUE;

    return (data[0] << 8) + data[1] + (data[2] / 100.0);
}

float PZEM004T::power(const IPAddress &addr)
{
    uint8_t data[RESPONSE_DATA_SIZE];

    send(addr, PZEM_POWER);
    if(!recieve(RESP_POWER, data))
        return PZEM_ERROR_VALUE;

    return (data[0] << 8) + data[1];
}

float PZEM004T::energy(const IPAddress &addr)
{
    uint8_t data[RESPONSE_DATA_SIZE];

    send(addr, PZEM_ENERGY);
    if(!recieve(RESP_ENERGY, data))
        return PZEM_ERROR_VALUE;

    return ((uint32_t)data[0] << 16) + ((uint16_t)data[1] << 8) + data[2];
}

bool PZEM004T::setAddress(const IPAddress &newAddr)
{
    send(newAddr, PZEM_SET_ADDRESS);
    return recieve(RESP_SET_ADDRESS);
}

bool PZEM004T::setPowerAlarm(const IPAddress &addr, uint8_t threshold)
{
    send(addr, PZEM_POWER_ALARM, threshold);
    return recieve(RESP_POWER_ALARM);
}

void PZEM004T::send(const IPAddress &addr, uint8_t cmd, uint8_t data)
{
    PZEMCommand pzem;

    pzem.command = cmd;
    for(int i=0; i<sizeof(pzem.addr); i++)
        pzem.addr[i] = addr[i];
    pzem.data = data;

    uint8_t *bytes = (uint8_t*)&pzem;
    pzem.crc = crc(bytes, sizeof(pzem) - 1);

    while(serial->available())
        serial->read();

    serial->write(bytes, sizeof(pzem));
}

bool PZEM004T::recieve(uint8_t resp, uint8_t *data)
{
    uint8_t buffer[RESPONSE_SIZE];

    if(_isSoft)
        ((SoftwareSerial *)serial)->listen();

    unsigned long startTime = millis();
    uint8_t len = 0;
    while((len < RESPONSE_SIZE) && (millis() - startTime < _readTimeOut))
    {
        if(serial->available() > 0)
        {
            uint8_t c = (uint8_t)serial->read();
            if(!c && !len)
                continue; // skip 0 at startup
            buffer[len++] = c;
        }
        yield();	// do background netw tasks while blocked for IO (prevents ESP watchdog trigger)
    }

    if(len != RESPONSE_SIZE)
        return false;

    if(buffer[6] != crc(buffer, len - 1))
        return false;

    if(buffer[0] != resp)
        return false;

    if(data)
    {
        for(int i=0; i<RESPONSE_DATA_SIZE; i++)
            data[i] = buffer[1 + i];
    }

    return true;
}

uint8_t PZEM004T::crc(uint8_t *data, uint8_t sz)
{
    uint16_t crc = 0;
    for(uint8_t i=0; i<sz; i++)
        crc += *data++;
    return (uint8_t)(crc & 0xFF);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А Ваш-то код где? Которым Вы это читаете?

Кстати, зачем Вы меняли таймаут? Это же просто время ожидания, а вовсе не частота чтения. Меняйте "в зад".

И давайте свой код.

bifurkas
Offline
Зарегистрирован: 27.10.2013

Код взят из примера, идущего с библиотекой. Вот он:

#include <SoftwareSerial.h> // Arduino IDE <1.6.6
#include <PZEM004T.h>

PZEM004T pzem(&Serial1);
IPAddress ip(192,168,1,1);

void setup() {
  Serial.begin(9600);
  pzem.setAddress(ip);
}

void loop() {
  float v = pzem.voltage(ip);
  if (v < 0.0) v = 0.0;
  Serial.print(v);Serial.print("V; ");

  float i = pzem.current(ip);
  if(i >= 0.0){ Serial.print(i);Serial.print("A; "); }
  
  float p = pzem.power(ip);
  if(p >= 0.0){ Serial.print(p);Serial.print("W; "); }
  
  float e = pzem.energy(ip);
  if(e >= 0.0){ Serial.print(e);Serial.print("Wh; "); }

  Serial.println();

//  delay(1000);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, ну что ж из Вас всё клещами-то надо тянуть? В коде есть печати. Давайте лог - чего печатает-то?

Правильно ли я понимаю, что у Вас строка 28 тоно такая (с комментарием). Печать валится постоянно, но меняется только раз в секунду? Или с чего Вы взяли, что там частота опроса раз в секунду?

И ещё. Вы выложили код библиотеки, но... Вы же говорили, что меняли там константу, а выложили что? Без изменений!

давайте Вы вылодите ТОЧНО ИМЕННО ТОТ код, который запускаете и заодно скопируете протокол печати - что печатает.

bifurkas
Offline
Зарегистрирован: 27.10.2013

Прошу прощения, если плохо объясняю.

Под рукой устройства сейчас нет, монитор порта выложу вечером. Код в Ардуино точно тот, который выложил выше. Монитор порта выдаёт значения напряжения, тока, мощности и потребления раз в секунду (значения меняются раз в секунду). Строчка 28 как в выложенном коде. Пробовал раскомментировать - ничего не меняется. Из этого я сделал вывод, что частота опроса заложена в библиотеке.

Код библиотеки (константу) я поменял, результат не получил и вернул всё обратно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

bifurkas пишет:
Монитор порта выдаёт значения напряжения, тока, мощности и потребления раз в секунду (значения меняются раз в секунду).

Не понял приписки в скобках. Давайте конкретно.

1. Значения выдаются раз в секуднк?

или

2. Значения выдаются часто, но одни и те же, а изменяются раз в секунду.

Это большая разница.

И в общем, я жду протокола монитора порта. ТОлько добавьте в печатьи ещё и время (просто значение millis печатайте), чтобы видны были задержки.

bifurkas
Offline
Зарегистрирован: 27.10.2013

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Хорошо, я тогда посмотрю, буду ждать.

bifurkas
Offline
Зарегистрирован: 27.10.2013

Ниже скрин монитора порта. На счёт millis не знаю как сделать, программист я никудышный. Новая строка со значениями появляется в мониторе раз в секунду. На самом PZEM-004t имеются 4 индикатора, показания которых совпадают с показаниями в мониторе и обновляются в один и тот же момент времени. Это навело меня сейчас на мысль, что возможно частота выдачи данных из PZEM фиксированная и не зависит от частоты посылаемых запросов. Надо будет даташит посмотреть.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

У меня тоже такое ощущение, потому, что в библиотеке никаких специальных задержек нет.

bifurkas
Offline
Зарегистрирован: 27.10.2013

Перерыл даташиты - ничего не нашёл. Подключил терминал и попробовал отослать запросы с частотой, чаще 1сек... И тут всё стало понятно, PZEM не обрабытывает запросы чаще двух раз в секунду.

ЕвгенийП, спасибо за уделённое мне внимание, тему можно закрывать.

Evg76
Offline
Зарегистрирован: 04.04.2017

ЕвгенийП пишет:

У меня тоже такое ощущение, потому, что в библиотеке никаких специальных задержек нет.

 

Уважаемый Евгений, может быть вы знаете как тогда считывать показания с PZEM004T и при этом не ждать 1 секунду ответа от функций pzem.voltage (.current, .power, .energy)? В то время, когда ардлуина ждет ответа от этих функций, она просто "висит", а это никуда не годится. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не знаю, но могу попробовать посмотреть. Только Вы делайте то, что Вас просят.

ЕвгенийП пишет:
Только добавьте в печати ещё и время (просто значение millis печатайте), чтобы видны были задержки.

В прошлый раз Вы не сделали, я и подумал, что Вам не надо.

Давайте, выложите печать как я просил и свежий скетч (тот самый, который печатал).

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Это уже другой человек. 

"PZEM allows to read max 2 values at once (per second). So if you try to read all 4 values - it will take minimum 2 second" (C)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, по любому, нужен скетч и печать, чтобы не вслепую работать, другой - так другой

sadman41 пишет:

"PZEM allows to read max 2 values at once (per second). So if you try to read all 4 values - it will take minimum 2 second" (C)

Да это то ладно. Надо быяснить обязательно ли его ждать или можно в это время другими делами заниматься. Вопрос-то, мне показалось, так стоит.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ждать не обязательно. Главное - не обращаться чаще. Лучше - раз в секунду. Иначе прибор может затупить и коннект будет по таймауту отваливаться через определенное в библиотеке время.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну Вот, Вы и ответили спрашивающему. Доводите уж теперь, чего мне лезть-то.

Evg76
Offline
Зарегистрирован: 04.04.2017

ЕвгенийП пишет:

Ну, по любому, нужен скетч и печать, чтобы не вслепую работать, другой - так другой

sadman41 пишет:

"PZEM allows to read max 2 values at once (per second). So if you try to read all 4 values - it will take minimum 2 second" (C)

Да это то ладно. Надо быяснить обязательно ли его ждать или можно в это время другими делами заниматься. Вопрос-то, мне показалось, так стоит.

Код:

#include <SoftwareSerial.h> // Arduino IDE <1.6.6
#include <PZEM004T.h>

PZEM004T pzem(10,11);  // (RX,TX) connect to TX,RX of PZEM
IPAddress ip(192,168,1,1);

void setup() {
  Serial.begin(9600);
  pzem.setAddress(ip);
}

void loop() {
  float v = pzem.voltage(ip);
  if (v < 0.0) v = 0.0;
  Serial.print(v);Serial.print("V ("); Serial.print(millis()); Serial.print("); ");

  float i = pzem.current(ip);
  if(i >= 0.0){ Serial.print(i);Serial.print("A ("); Serial.print(millis()); Serial.print("); ");}
  
  float p = pzem.power(ip);
  if(p >= 0.0){ Serial.print(p);Serial.print("W ("); Serial.print(millis()); Serial.print("); ");}
  
  float e = pzem.energy(ip);
  if(e >= 0.0){ Serial.print(e);Serial.print("Wh ("); Serial.print(millis()); Serial.print("); ");}

  Serial.println();
}

Распечатка:

224.90V (612); 0.00A (649); 0.00W (1610); 15.00Wh (1647); 
224.90V (2611); 0.00A (2648); 0.00W (3610); 15.00Wh (3646); 
224.20V (4611); 0.00A (4647); 0.00W (5609); 15.00Wh (5646); 
224.90V (6610); 0.00A (6647); 0.00W (7609); 15.00Wh (7647); 
225.00V (8610); 0.00A (8647); 0.00W (9609); 15.00Wh (9646); 
224.70V (10610); 0.00A (10647); 0.00W (11609); 15.00Wh (11645); 
224.80V (12610); 0.00A (12647); 0.00W (13608); 15.00Wh (13645); 
224.70V (14609); 0.00A (14646); 0.00W (15608); 15.00Wh (15645); 
 
Спасибо!
Evg76
Offline
Зарегистрирован: 04.04.2017

Уважаемый, sadman41!

Спасибо за ответ! Подскажите, а как не ждать, ведь функция pzem.voltage тормозит цикл на 2 секунды? Или работать с PZEM004T напрямую (без библиотеки PZEM004T.h)? Есть пример такого кода?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Функция не тормозит. Просто счетчик не готов отвечать так быстро, как вы его опрашиваете. Хоть через библиотеку, хоть напрямую. Производите чтение так, как рекомендует статья "blink без delay", а в промежутках между чтениями раз в секунду делайте еще что-то полезное в скетче.

Evg76
Offline
Зарегистрирован: 04.04.2017

Все, теперь понял. Спасибо за вразумление! :)

Если к модулю обращаться не чаще, чем 1 раз в секунду, то он данные выдает быстро – около 25мс.  Вот, распечатка задержек. В скобках время в мс за которое получили значение и вывели в порт:

V=227.60 ( 27) I=0.08 ( 26) P=11.00 ( 23) E=27.00 ( 22)
V=226.70 ( 23) I=0.09 ( 21) P=10.00 ( 19) E=27.00 ( 19)
V=225.00 ( 18) I=0.08 ( 16) P=11.00 ( 25) E=27.00 ( 24)
V=226.10 ( 25) I=0.08 ( 24) P=11.00 ( 20) E=27.00 ( 20)
V=226.10 ( 20) I=0.08 ( 19) P=11.00 ( 16) E=27.00 ( 17)

Вот код (для будущих ковыляльщиков):

#include <SoftwareSerial.h> // Arduino IDE <1.6.6
#include <PZEM004T.h>

PZEM004T pzem(10,11);  // (RX,TX) connect to TX,RX of PZEM
IPAddress ip(192,168,1,1);

unsigned long LstRd =0; 
byte Ncycle = 1;

#define RdDly  1000  // задержка мс между обращениями к PZEM004T


void setup() {
  Serial.begin(9600);
  pzem.setAddress(ip);
  LstRd = millis();
}

void loop() {
  if (Ncycle == 1 && millis() - LstRd > RdDly)
  {
  Ncycle++; LstRd = millis();
  Serial.print("V="); 
  float v = pzem.voltage(ip); if (v < 0.0) v = 0.0; Serial.print(v);
  Serial.print(" ("); Serial.print(millis()- LstRd); Serial.print(") ");
  }

  if (Ncycle == 2 && millis() - LstRd > RdDly)
  {
  Ncycle++; LstRd = millis();
  Serial.print("I="); 
  float i = pzem.current(ip); if(i < 0.0) i = 0.0; Serial.print(i);
  Serial.print(" ("); Serial.print(millis()- LstRd); Serial.print(") ");
  }
  
  if (Ncycle == 3 && millis() - LstRd > RdDly)
  {
  Ncycle++; LstRd = millis();
  Serial.print("P="); 
  float p = pzem.power(ip); if(p < 0.0) p = 0.0; Serial.print(p); 
  Serial.print(" ("); Serial.print(millis()- LstRd); Serial.print(") ");
  }
  
  if (Ncycle == 4 && millis() - LstRd > RdDly)
  {
  Ncycle = 1; LstRd = millis();
  Serial.print("E="); 
  float e = pzem.energy(ip); if(e < 0.0) e = 0.0; Serial.print(e);
  Serial.print(" ("); Serial.print(millis()- LstRd); Serial.print(") ");
  Serial.println();
  }
  
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Предлагаю упрощение:

void loop() {
 static float v, i, p, e;

 if (millis() - LstRd > RdDly)
  {
    switch (Ncycle) {
      case 1:
        v = pzem.voltage(ip); if (v < 0.0) v = 0.0; 
        Serial.print("V="); Serial.println(v);
        break;
      case 2:
        i = pzem.current(ip); if (i < 0.0) i = 0.0;
        Serial.print("I="); Serial.println(i); 
        break;
      ...
      default:
        Ncycle = 0;
        LstRd = 0;
    }
    Ncycle++; LstRd = millis();
    ..
    Serial.print(" ("); Serial.print(millis()- LstRd); Serial.println(") "); 
  }
}
Evg76
Offline
Зарегистрирован: 04.04.2017

Спасибо!

Это все-равно пока черновик. Надо еще все переделать под 3 фазы, добавить чтение 3х DS18B20, дисплей, sd-карту и отправку на MQTT через ESP8266 :)

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну вот, как раз чтение вразнобой разных метрик с трех PZEM + DS-ки + всякое другое секунду и сожрут. 3 PZEM-а можно подключить собрав все их RX-ы на один пин ардуины. Так экономится два пина и не надо резисторы выпаивать с прибора.

Evg76
Offline
Зарегистрирован: 04.04.2017

1. Да-да, так и планирую потратить секунду :)

2. А как это "собрав все их RX-ы на один пин ардуины"? Я пока их все по разным софт-портам раскидываю (PZEM004T pzemA(10,11), pzemB(3,4), pzemC(5,6); )

 

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Evg76 пишет:

2. А как это "собрав все их RX-ы на один пин ардуины"? Я пока их все по разным софт-портам раскидываю (PZEM004T pzemA(10,11), pzemB(3,4), pzemC(5,6); )

Если ног хватает, то можно и так. Но, когда приходится кроить, то можно этак: https://github.com/zbx-sadman/zabbuino/issues/8 . Так же: сбором RX-ов на один пин - тогда ардуина одновременно командует всем, а слушает ответ у одного. Или, наверное, можно попробовать TX-ы собрать (но, наверняка не будет работать без выпайки резисторов) - ардуина будет говорить по отдельному проводу, а слушать общий. Типа этого: PZEM004T pzemA(10,11), pzemB(10,4), pzemC(10,6). Софтсериалу-то пофигу, за какой провод дергать.

Evg76
Offline
Зарегистрирован: 04.04.2017

Спасибо за наводку!

Вы как, шабашки берете? А то у меня это хобби-диверсификация, и очень мало времени на допиливание до ума.

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Беру иногда. wrk.sadman@gmail.com

KVL80
Offline
Зарегистрирован: 12.01.2018

БОЛЬШОЕ спасибо, за эту тему! Очень помогла!!! Уже неделю мучился, просил помощи на других сайтах... на которых ОЧЕНЬ сильно УМНИЧАЮТ и СПЕЦОВ из себя корчат. А реально никто помочь не желает. Хочешь решить проблему, плати-один ответ. Ещё раз СПАСИБО!

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Если ног хватает, то можно и так. Но, когда приходится кроить, то можно этак: https://github.com/zbx-sadman/zabbuino/issues/8 . Так же: сбором RX-ов на один пин - тогда ардуина одновременно командует всем, а слушает ответ у одного. Или, наверное, можно попробовать TX-ы собрать (но, наверняка не будет работать без выпайки резисторов) - ардуина будет говорить по отдельному проводу, а слушать общий. Типа этого: PZEM004T pzemA(10,11), pzemB(10,4), pzemC(10,6). Софтсериалу-то пофигу, за какой провод дергать.

Я правильно понял что можно подключить 3шт PZEM004T паралельно на 2 пина всего лишь выпаяв R15 на двух из них? Можно пример кода? По ссылке не нашёл.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Совсем параллельно (на два вывода) я сам не пробовал, но у товарища по ссылке работало. Только каждому предварительно нужно назначить свой адрес (который похож на IP Address). А со сбором RX-ов на один пин можно даже тупо объекты SoftwareSerial-а создавать каждый раз на другие пины, опрашивать PZEM и утилизировать объект. Всё достаточно быстро происходит на 328-м МК.

Мой исходник тут: https://github.com/zbx-sadman/zabbuino/blob/master/src/uart_pzem.cpp , но не знаю, чем он Вам поможет. Есть библиотека для PZEM, но она с ошибкой - с одним экземпляром счетчика работает, а с тремя - глючит.

Кстати, эксперименты показали, что на 2 раза в секунду таки лучше не расчитывать - в редкие моменты случается у счетчика затуп. Стоит рассматривать период чтения от секунды и более.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:
Есть библиотека для PZEM, но она с ошибкой - с одним экземпляром счетчика работает, а с тремя - глючит

Вот эта глючит? https://github.com/olehs/PZEM004T

А существуют другие версии библиотеки? Так как надо именно с 3 счётчиками.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Я сталкивался со странным поведением, если создать несколько инстансов (по каждому на счетчик). Но зацикливаться на этом не стал. 

Других версий не знаю, обмен пишу сам, если надо.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Я сталкивался со странным поведением, если создать несколько инстансов (по каждому на счетчик). Но зацикливаться на этом не стал. 

Других версий не знаю, обмен пишу сам, если надо.

А в чём выражается страннось? Хоть знать с чем столкнусь. Увы, я не обладаю в программиовании настолько что-бы писать обмен самостоятельно.  Поэтому пользуюсь тем что есть.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Да читал он только с первого объявленного, по-моему.

dodther
Offline
Зарегистрирован: 30.11.2018

Да, проблема вылезла сразу.


1: 220.20V; 0.00A; 0.00W; 11.00Wh; 
2: 0.00V; 0.00A; 0.00W; 42.00Wh; 
3: 0.00V; 
1: 220.00V; 0.00A; 0.00W; 11.00Wh; 
2: 0.00V; 0.00A; 
3: 0.00V; 
----------------------------------------------
1: 220.10V; 0.00A; 0.00W; 11.00Wh; 
2: 222.60V; 0.00A; 0.00W; 42.00Wh; 
3: 0.00V; 
1: 222.30V; 0.00A; 0.00W; 11.00Wh; 
2: 224.40V; 0.00A; 0.00W; 42.00Wh; 
3: 0.00V;
----------------------------------------------
1: 220.80V; 0.00A; 0.00W; 11.00Wh;
2: 0.00V;
3: 110.80V; 0.00A; 0.00W; 25.00Wh;
1: 227.80V; 0.00A; 0.00W; 11.00Wh;
2: 0.00V;
3: 113.90V; 0.00A; 0.00W; 25.00Wh;

Верхняя часть, до разделителя - это подключены 3шт. Видно как втупляет чтение с 2 и 3. Разделитель - это я выдернул датчик №3 с дуины. Первые два сразу нормальзовались. Второй разделитель - это я выдернул 2, а 3 воткнул. Сответственно 1 и 3 стали  показывать норм. Это я всё на горячую делал, без перезапуска дуины.

Плата - ардуино нано.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну, вобщем, что-то такое было и у меня. Решал врукопашную.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Ну, вобщем, что-то такое было и у меня. Решал врукопашную.

А поподробнее?

Попробовал третий посадить на серийный порт самой дуины. Все 3 датчика читает, но тот что на серийном весит лезет мусор какой-то.

1: 234.20V; 0.00A; 0.00W; 42.00Wh; 
2: 116.60V; 0.00A; 0.00W; 25.00Wh; 
3: ⸮⸮⸮ 232.80V; ⸮⸮⸮0.00A; ⸮⸮⸮0.00W; ⸮⸮⸮11.00Wh; 

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

dodther пишет:

А поподробнее?

Подробнее уже было - "обмен пишу сам, если надо". Дальше уже только писать за вас прошивку остается.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Если ног хватает, то можно и так. Но, когда приходится кроить, то можно этак: https://github.com/zbx-sadman/zabbuino/issues/8 . Так же: сбором RX-ов на один пин - тогда ардуина одновременно командует всем, а слушает ответ у одного. Или, наверное, можно попробовать TX-ы собрать (но, наверняка не будет работать без выпайки резисторов) - ардуина будет говорить по отдельному проводу, а слушать общий. Типа этого: PZEM004T pzemA(10,11), pzemB(10,4), pzemC(10,6). Софтсериалу-то пофигу, за какой провод дергать.

У меня глучило при варианте собранных TX(PZEM004T) на один пин ардуины. При сборке RX(PZEM004T) на один пин вообще не работало. Сейчас сделал 2 датчика с одним TX(PZEM004T) и 3й на отдельных пинах. Вроде пашет.

1: 230.20V; 0.16A; 35.00W; 44.00Wh; 
2: 114.70V; 0.00A; 0.00W; 26.00Wh; 
3: 227.40V; 0.00A; 0.00W; 0.00Wh;

 

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Если ног хватает, то можно и так. Но, когда приходится кроить, то можно этак: https://github.com/zbx-sadman/zabbuino/issues/8 . Так же: сбором RX-ов на один пин - тогда ардуина одновременно командует всем, а слушает ответ у одного. Или, наверное, можно попробовать TX-ы собрать (но, наверняка не будет работать без выпайки резисторов) - ардуина будет говорить по отдельному проводу, а слушать общий. Типа этого: PZEM004T pzemA(10,11), pzemB(10,4), pzemC(10,6). Софтсериалу-то пофигу, за какой провод дергать.

Разобрался с подключением 3шт на 2 ноги.  Сначала подключаем по одной и через setAddress назначаем каждой свой адресс. Этот адресс хранится во внутренней памяти датчика и не сбрасывается при отключении питания. А потом выпаеваем сопротивления у всех кроме одной и собираем вместе на 2 ноги. А в коде уже получаем данные через pzem.voltage(ip1), pzem.voltage(ip2) и т.д.

Заодно собрал програмный сброс количества учтённых ватт. А то сбрасывать на кнопку как-то несерьёзно.

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

dodther пишет:

Разобрался с подключением 3шт на 2 ноги.  Сначала подключаем по одной и через setAddress назначаем каждой свой адресс. Этот адресс хранится во внутренней памяти датчика и не сбрасывается при отключении питания. А потом выпаеваем сопротивления у всех кроме одной и собираем вместе на 2 ноги. А в коде уже получаем данные через pzem.voltage(ip1), pzem.voltage(ip2) и т.д.

Вобщем-то это и написано было по ссылке. Сбор ног одно типа - это уже чтобы не лезть паяльником в PZEM. Забудешь потом чего у кого отпаял.

С другой стороны - адреса надо тоже запоминать. Или подписывать на счетчике. Он же, гад, если адрес не тот ему суешь, молчит как партизан. От сломанного и не отличить.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Вобщем-то это и написано было по ссылке.

Да я вок как-то только сейчас допёр. Мне почему-то казалось что setAddress надо делать в setup()

sadman41 пишет:

 Сбор ног одно типа - это уже чтобы не лезть паяльником в PZEM. Забудешь потом чего у кого отпаял.

С другой стороны - адреса надо тоже запоминать. Или подписывать на счетчике. Он же, гад, если адрес не тот ему суешь, молчит как партизан. От сломанного и не отличить.

Так это видно сразу. А и учёт ЭЭ не то устройство которое надо постоянно разбирать и собирать. Сделал раз, поставил в щит и забыл.

 

 

 

 

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вот именно - забыл )) Через годик решил апгрейд сделать: в щит добавить чего, в прошивке чего-нить улучшить и сиди, думай чего ты там кому назначил, у кого что отпаял. Стандартное попадалово. Конечно, если память эдейтическая, то проще.

dodther
Offline
Зарегистрирован: 30.11.2018

sadman41 пишет:

Вот именно - забыл )) Через годик решил апгрейд сделать: в щит добавить чего, в прошивке чего-нить улучшить и сиди, думай чего ты там кому назначил, у кого что отпаял. Стандартное попадалово. Конечно, если память эдейтическая, то проще.

А тут надо не ленится и писать документацию. :)

Pahanovna
Offline
Зарегистрирован: 25.03.2019

Добрый день. Я так и не понял, у вас получается прочитать все четыре параметра раз в секунду? Или на чтение каждого параметра нужна секунда?
Другими словами, я могу раз в секунду получать значения сразу и напряжения, и тока, и мощности, и энергии? Или чтобы получить все четыре эти значения, мне придётся затратить четыре секунды?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Одно обращение к счетчику в секунду. За одно обращение получаем только одну метрика (параметр/значение/...). Сразу всё не получить.

Pahanovna
Offline
Зарегистрирован: 25.03.2019

Аааа! Какое же бесполезное нецензурное слово, эта плата! Ладно когда датчик температуры или влажности воздуха так себя ведёт. Но это же датчик тока! Я уже готов был смириться с тем, чтобы получать все параметры раз в секунду. Слишком редко, но хоть как-то. Но цикл замеров раз в две секунды минимум (остальное можно вычислить), когда электричество скачет как попало - это просто ни о чём.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Найдите другой... Мне тоже было бы интересно узнать, как зовут недорогой счетчик с цифровым интерфейсом и возможностью одновременного получения всех параметров измерительного "среза".