Мониторим электрику: modbus PZEM-016(PZEM-004T 3.0)/ESP-32

Тема в разделе "Глядите, что я сделал", создана пользователем ИгорьК, 28 окт 2019.

  1. KindMan

    KindMan Гуру

    Это точно, зачем вся эта жесть из транзисторов?
    Там будет тот потенциал, который вы подадите на вывод, который у вас обозначен как 5V. Попробуйте просто подать туда 3,3 и всё соедините напрямую. Тока должно хватить, чтобы открыть оптопару.
     
    naz нравится это.
  2. naz

    naz Нерд

    Задача проще- мне бы с модулем пообщаться через терминал компьютера.[​IMG]
    Но он не отвечает, хотя данные передаются и светодиод у пина 5v моргает. Передаю 0x01 и другие наборы цифр. Как убедиться, что модуль рабочий?
     
    Последнее редактирование: 13 фев 2022
  3. KindMan

    KindMan Гуру

    У меня модуль второй версии. При подаче 220 он отсылает в порт 00.
    На скриншоте у вас запрос неверный. Нужна команда, адрес модуля и контрольная сумма.
    Вот сейчас попробовал на своём запрос напряжения, в HEX отправляем то, что у меня сверху. Модуль отвечает.
    amp.jpg
     
    naz нравится это.
  4. parovoZZ

    parovoZZ Гуру

    Есть замечательная прога modbus poll. Она автоматически считает контрольную сумму. В ней же можно и пакет сформировать тупо кликая мышкой.
     
    Igor68 нравится это.
  5. naz

    naz Нерд

    [​IMG]
    Пытался разные наборы посылать- тишина. Также при подаче 220в ничего не посылает..
    Модуль новый..
     
  6. KindMan

    KindMan Гуру

    Посмотрел про версию 3. Да, она отличается, и посылать нужно другие значения. У меня такой платы нет.
    Если у вас есть Ардуино и ESP то соедините их по схеме из интернета, просто скачайте библиотеку для PZEM и попробуйте стандартный пример.
    И кстати, чтобы отправить HEX из вашей программы терминала, нужно писать знак $ перед значением. т.е. запрос для моей платы должен выглядеть так - $b0$c0$a8$01$01$00$1a
    Удачи.
     
    naz нравится это.
  7. naz

    naz Нерд

    Благодарю! Да, уже понял, что через Ардуино буду искать адрес и т.д. (и надеяться, что уважаемый ИгорьК не прочитает сей пост.. а то мне не поздоровится:))
     
  8. naz

    naz Нерд

    Понял я свою ошибку. Если приёмная часть Pzem (пин Rx) питается от пина 5v, то передающая часть (пин Tx) питается от высоковольтной части Pzem, и наивно ждать ответа от модуля при неподключенных проводах 220В. Собрал Ардуину Мега с Pzem, подключил нагрузку- всё заработало.
    [​IMG]
     
  9. naz

    naz Нерд

    А вот что шлёт Ардуино в порт Pzem:
    Код (C++):
    F8 03 00 02 00 01 31 A3 F8 04 00 00 00 0A 64 64
    Видим две восьмибайтные команды, в которых адрес по умолчанию F8. Первая команда 03- Read Holding Register, вторая 04- Read Input Register
    Как это добавить в код Луа непонятно..
     
  10. naz

    naz Нерд

    Друзья, прошу подсказать такой момент: как у вас срабатывает модуль time? У меня выдаёт ошибку:
    Код (C++):
    do
    time = time.epoch2cal(time.get())
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", time["year"], time["mon"], time["day"], time["hour"], time["min"], time["sec"], time["dst"]))
    time.initntp("pool.ntp.org")
    end
     
    Код (C++):
    sendboot.lua:0: attempt to call field 'get' (a nil value)
     
    Не воспринимает функции этого модуля, на вызов любой функции даёт ошибку. Прошивка- от ИгоряК
     
  11. serg3295

    serg3295 Гуру

    Замените имя переменной time на что-нибудь другое. Например, tm.
    А то получается, что вы переименовываете модуль time.
    (На сайте не все примеры одинаково полезны...)

    Напишите вот так:
    Код (C++):
    tm = time.epoch2cal(time.get() + 10800)
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"], tm["dst"]))
     
     
    Последнее редактирование: 24 фев 2022
    naz нравится это.
  12. naz

    naz Нерд

    Код (C++):
    print(time.epoch2cal(time.get()))
    Код (C++):
    print(time.epoch2cal(time.get()))
    stdin:0: attempt to call field 'get' (a nil value)
     
     
  13. Igor68

    Igor68 Гуру

    Именно! И даже команды там заготовлены, и монитор передачи с приёмом.
     
  14. naz

    naz Нерд

    Да, так получилось.
    Код (C++):
    1970-01-01 00:36:29 DST:0
    Пытаюсь получить текущее время:
    Код (C++):
    do
    time.settimezone("EST+5")
    time.initntp()
    localTime = time.getlocal()
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", localTime["year"], localTime["mon"], localTime["day"], localTime["hour"], localTime["min"], localTime["sec"], localTime["dst"]))
    end
    Получаю
    Код (C++):
    1969-12-31 19:30:16 DST:0
     
  15. Igor68

    Igor68 Гуру

    Прошу прощения за свои 5 копеек! По первому выводу:
    Код (C++):
    1970-01-01 00:36:29 DST:0
    видно, что часы не выставлены и Вы его включили 36мин 29сек назад. И год 1970 - год начала отсчета... ну и месяц и число соответственно с начала. Значит Вы время получаете уже. Осталось только записать в модуль значение типа uint64_t соответственно текущему реальному времени. И наверное там должна быть батарейка часов... наверное, но не знаю.
     
  16. serg3295

    serg3295 Гуру

    Не обязательно использовать localtime и timezone. Можно просто плюсовать секунды к time.get в зависимости от часового пояса.
    Код (C++):
    wifi.start()

    time.initntp("ntp1.stratum2.ru")
    print(time.ntpenabled())


    tt=time.epoch2cal(time.get() )
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", tt["year"], tt["mon"], tt["day"], tt["hour"], tt["min"], tt["sec"], tt["dst"]))

    -- TZ MSK
    tm = time.epoch2cal(time.get() + 10800)
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"], tm["dst"]))

    time.settimezone('EST-3')  -- здесь я просто подогнал ответ. Не знаю какая строка в TZ тут сработает
    tl = time.getlocal()
    print(string.format("%04d-%02d-%02d %02d:%02d:%02d DST:%d", tl["year"], tl["mon"], tl["day"], tl["hour"], tl["min"], tl["sec"], tl["dst"]))
     
     
    naz нравится это.
  17. naz

    naz Нерд

    Спасибо. У меня почему-то функция time.get() возвращает секунды не с 1970г., а с момента старта esp32. Внешний сервер доступен:
    Код (C++):

    do
    sk = net.createConnection(net.TCP, 0)
    sk:dns("ntp1.stratum2.ru", function(conn, ip)
        print("ntp1.stratum2.ru = ",ip)
        sk = nil
        time.initntp("ntp1.stratum2.ru")
        print('time.ntpenabled = ', time.ntpenabled())
        local sec, usec = time.get()
        print('sec = ', sec)
        time.ntpstop()
    end)
    end
     
    Код (C++):

    ntp1.stratum2.ru =     88.147.254.230
    time.ntpenabled =     true
    sec =     362

     
     
    Последнее редактирование: 25 фев 2022
  18. serg3295

    serg3295 Гуру

    Зачем вы все запихнули в асинхронный callback? Да ещё сразу убиваете модуль time через time.ntpstop.
    Код (C++):
    do
        time.initntp("ntp1.stratum2.ru")
    sk = net.createConnection(net.TCP, 0)
    sk:dns("ntp1.stratum2.ru", function(conn, ip)
        print("ntp1.stratum2.ru = ",ip)
        sk = nil
        print('time.ntpenabled = ', time.ntpenabled())
        local sec, usec = time.get()
        print('sec = ', sec)
    end)
        -- time.ntpstop()
    end
     
  19. naz

    naz Нерд

    Код (C++):
    do
    time.initntp("ntp1.stratum2.ru")
    sk = net.createConnection(net.TCP, 0)
    sk:dns("ntp1.stratum2.ru", function(conn, ip)
        print("ntp1.stratum2.ru = ",ip)
        sk = nil
        print('time.ntpenabled = ', time.ntpenabled())
        local sec, usec = time.get()
        print('sec = ', sec)
    end)
    end
     
    Код (C++):
    ntp1.stratum2.ru =     88.147.254.230
    time.ntpenabled =     true
    sec =     4657
     
    Увы, результат тот же. А у Вас как выдаёт time.get()?
     
  20. serg3295

    serg3295 Гуру

    2022-02-25_11-53.png
     
    naz нравится это.