Исправить имеющийся скетч для wifi-шлюза (опроса modbus rtu устройств)

Тема в разделе "Закажу проект", создана пользователем Kotopes, 27 янв 2020.

  1. ИгорьК

    ИгорьК Гуру

    Хотите - потренируйтесь. Смотрите код: что происходит после соединения с wifi.
     
  2. alp69

    alp69 Форумчанин

    Он не является средством измерения. Проверить можно в реестре средств измерений.
     
    Последнее редактирование: 29 янв 2020
  3. alp69

    alp69 Форумчанин

    Да. Увидел вызов uart_setup().
    На телефоне сложно код листать.
     
  4. Kotopes

    Kotopes Нерд

    все... тупик?
     
  5. ИгорьК

    ИгорьК Гуру

    Скрипт запущен и 100% работает функционирует.

    Что вы еще хотите? Дальше - уже новый проект. Я вижу его как переписать скрипт под esp32, выводить в сериал все общение со счётчиком и смотреть что там происходит в железе (которое должно быть в наличии).

    Свой аналогичный проект я вам показал.

    Подтверждаете это - кто-то да найдётся за денежку. Это точно не я - я самодельщик.
     
  6. Kotopes

    Kotopes Нерд

    То что Вы откликнулись посмотреть и разобраться с данным скриптом, огромное спасибо! Но я бы хотел за денежку добить данный скрипт до результата (получения данных с счетчика), надеюсь кто нибудь мне в этом поможет.
     
  7. ИгорьК

    ИгорьК Гуру

    Давайте, пока мы его ждем, вы ПОДРОБНО, лучше с фото, расскажете что конкретно и как вы соединяете, а также приложите руководство на свой счетчик и какой-то даташит на протокол обмена.
    ..ибо я не думаю, что этот код нерабочий столько лет. Скорее (вероятно) дело в ваших навыках общения с электротехникой.
    "Спасение утопающих..."
     
    Последнее редактирование: 29 янв 2020
  8. Kotopes

    Kotopes Нерд

    И так, шлю собирается один как для опроса MODBUS устройств, так и для опроса по протоколу - МЭК 61107-2001 IEK61107 (если я ничего не путаю) https://mjdm.ru/forum/viewtopic.php?f=5&t=3173&hilit=энергомера

    Спецификация протокола: http://www.energomera.ru/documentations/ce102m_full_re.pdf

    Использую устройства:

    1 esp8266-01

    2 Трансивер rs485 ADM3485EARZhttps://static.chipdip.ru/lib/143/DOC000143984.pdf

    3 Модули RS485 на чипе MAX485 или вот такой https://aliexpress.ru/item/32889414931.html?spm=a2g0s.9042311.0.0.264d33edytJ4r0

    4 блок питание 3,3 v

    Схема подключения:
    upload_2020-1-29_15-38-33.png


    Как вижу схему я:

    upload_2020-1-29_15-38-47.png
     
  9. ИгорьК

    ИгорьК Гуру

    "Ну и рожа у тебя, Шарапов"...

    С чего бы оно будет работать???????????????????????????



    Там же БУКВАМИ НАПИСАНО:


    upload_2020-1-29_16-3-38.png


    Берем NodeMCU чтобы не париться и присоединяем к его 7 и 8

    upload_2020-1-29_16-13-12.png


    upload_2020-1-29_16-58-34.png


    ноге вот это:


    upload_2020-1-29_16-5-34.png


    В общем, этот код работает с 7 и 8 ногой esp-8266, никакие другие ноги к тому RS485 модулю, что я указал, присоединять не надо, только питание 3.3 вольта и землю.


    upload_2020-1-29_17-18-12.png

    С другой стороны ноги А и В присоединить к счетчику. Это пока все.
     
    Последнее редактирование: 29 янв 2020
  10. ИгорьК

    ИгорьК Гуру

    Надеюсь, за Шарапова вы на меня не обиделись, сделаем следующий шаг.
    Загрузим в модуль и и запустим следующий код:

    Код (Lua):
    result = {}
    RS485_BaudRate = 9600
    RS485_DataBits = 7
    RS485_ParityBits = uart.PARITY_EVEN
    RS485_StopBits = uart.STOPBITS_1
    RS485_TxOn_Pin = 2

    function uart_setup(urt)
        -- node.output(function(str) end, 0)
        if urt == 1 then
            uart.alt(1)
            uart.setup(0, 9600, 7, uart.PARITY_EVEN, uart.STOPBITS_1, 0)

            uart.on("data", 1, function(data)
                rx_buff = rx_buff..data
                if (#rx_buff > 256) then rx_buff = "" end
           
                -- [Пере]запускаем таймер ожидания очередного байта
                tmr.alarm(6, 5, tmr.ALARM_SINGLE, function()
                    uart_paket_rx()
                end)
            end, 0)
        else
            uart.alt(0)
            uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
            tmr.alarm(6, 1500, tmr.ALARM_SINGLE, function()
                print('Result Now!')
                table.foreach(result, print)      
            end)
        end
    end


    -- Параметры опроса счётчика
    CE102M_Addr = "" -- адрес счётчика ("" или nil для безадресного обмена)
    CE102M_CyclePeriod = 10000
    CE102M_RequestPeriod = 500
    -- Переменные

    local rx_buff = ""
    local last_param_name
    -- Запрашиваемые из счётчика параметры
    local ce102m_params = {"VOLTA","CURRE","POWEP","COS_f","FREQU"}
    local ce102m_step


    -- Считаем период передачи 1 байта данных через RS485
    --- Биты данных и старт-бит
    Bits = RS485_DataBits + 1
    --- Бит чётности
    if (RS485_ParityBits ~= uart.PARITY_NONE) then Bits = Bits + 1 end
    --- Стоп-бит
    if (RS485_StopBits == uart.STOPBITS_1) then Bits = Bits + 1
    elseif (RS485_StopBits == uart.STOPBITS_1_5) then Bits = Bits + 1.5
    else Bits = Bits + 2 end
    ByteTransmitTimeUs = RS485_BaudRate / Bits
    ByteTransmitTimeUs = 1000000 / ByteTransmitTimeUs


    -- Функция считает BCC (простая сумма всех байт с переполнением) по строке aData
    function process_bcc(aData)
        local bcc = 0x00
        for i = 1, #aData do
            bcc = bit.band(0x7F, bcc + string.byte(aData, i))
        end
        return bcc
    end

    -- Функция-обработчик входящего пакета
    function uart_paket_rx()
        -- Информационное сообщение?
        if (string.byte(rx_buff, 1) ~= 0x02) then return end
        -- Контрольная сумма сошлась?
        local bcc = process_bcc(string.sub(rx_buff, 2, #rx_buff - 1))
        if (string.byte(rx_buff, #rx_buff) ~= bcc) then return end
        -- Ищем имя параметра в пакете
        local a = 0
        for rx_buff_one in string.gmatch(rx_buff, last_param_name.."%([0-9]+%.[0-9]+%)") do
            a = a + 1    --увеличиваем счетчик
           
            local str = last_param_name.."%("
            local pos1 = string.find(rx_buff_one, str)
            local pos2 = string.find(rx_buff_one, "%)")
            if (pos1 == nil) and (pos2 == nil) then return end
       
            -- Извлекаем значение и отправляем по MQTT
            pos1 = pos1 + #str - 1
            str = string.sub(rx_buff_one, pos1, pos2 - 1)
            --print(last_param_name.." "..a.." "..str)
            --print(a)
            if (str ~= "0.00") then
                result[#result+1] = last_param_name..a..' : '..str
                --MQTT_send(MQTT_TopicString..last_param_name..a, str)
            end
        end
    end

    -- Функция настраивает UART

    -- Функция отправляет пакет в RS485
    function RS485_send(paket)
        -- gpio.write(RS485_TxOn_Pin, 1)
        uart.write(0, paket)
        tmr.delay(ByteTransmitTimeUs * #paket)
        -- gpio.write(RS485_TxOn_Pin, 0)
        rx_buff = ""
    end

    -- Функция отправляет в счётчик запрос на соединение (адресный или безадресный)
    function ce102m_start(addr)
        if (addr == nil) then addr = "" end
        RS485_send(string.char(0x2F,0x3F)..addr..string.char(0x21,0x0D,0x0A))
    end

    -- Функция выдаёт ASK, счётчик отвечает своим номером
    function ce102m_p0()
        RS485_send(string.char(0x06,0x30,0x35,0x31,0x0D,0x0A))
    end

    -- Функция запрашивает у счётчика параметр по мнемонике
    function ce102m_get_param(param_name)
        local request = string.char(0x01,0x52,0x31,0x02)..param_name.."()"..string.char(0x03)
        local bcc = process_bcc(string.sub(request, 2, #request))
        request = request..string.char(bcc)
        RS485_send(request)
        last_param_name = param_name
    end


    -- Функция отправляет в счётчик запрос на разъединение
    function ce102m_stop()
        RS485_send(string.char(0x01,0x42,0x30,0x03,0x75))
    end

    -- Функция отправляет в счётчик очередной запрос
    function NextRequest()
        if (ce102m_step == 1) then
            ce102m_start(CE102M_Addr)
        elseif (ce102m_step == 2) then
            ce102m_p0()
        elseif (ce102m_step == (#ce102m_params + 3)) then
            ce102m_stop()
        else
            ce102m_get_param(ce102m_params[ce102m_step - 2])
        end
    end

    tmr.alarm(1, CE102M_CyclePeriod, tmr.ALARM_AUTO, function()
        uart_setup(1)
        ce102m_step = 1
        result = {'Result Table data:'}
        tmr.alarm(2, CE102M_RequestPeriod, tmr.ALARM_AUTO, function()
            NextRequest(ce102m_step)
            ce102m_step = ce102m_step + 1
            if (ce102m_step > (#ce102m_params + 3)) then
                tmr.unregister(2)
                uart_setup()
            end
        end)
    end)
    Что это такое. Я выбрал из авторского кода кусок, что отвечает за общение со счетчиком, и, не меняя, заставил выводить данные в монитор порта.

    Вот как это выглядит без счетчика:

    upload_2020-1-30_9-55-7.png

    Таким образом, если написанное автором верно, вы будете в терминал получать данные от счетчика.
    Этот код, таким образом, подойдет для второго шага - проверки соединения и ответа от счетчика.

    Первый шаг - на модуле RS485, когда вы соедините его с ESP-8266 и запустите скрипт, должна начать помигивать лампочка.
     

    Вложения:

    alp69 и DetSimen нравится это.
  11. Kotopes

    Kotopes Нерд

  12. Kotopes

    Kotopes Нерд

    сегодня попробую подключиться к счетчику, посмотрим что считает...

    Если поменять местами ножки D7 и D8...esp так же отказывается перезагружается
     

    Вложения:

    Последнее редактирование: 7 фев 2020
  13. Kotopes

    Kotopes Нерд

    @ИгорьК Какие то умники оторвали провод из моего счетчика...пришлось получать разрешение на срыв пломб...процедура заняла много времени...

    сегодня получилось подключиться...

    Подключился так же как и было...А B и GND

    Подключил esp с rs открыл монитор порта, а там без изменений(

    походу приехали...((( куда смотреть, что проверять???
     

    Вложения:

    Последнее редактирование: 7 фев 2020
  14. alp69

    alp69 Форумчанин

    Не пишите в цитатах. Ваши сообщения никто не читает.
     
    parovoZZ и Daniil нравится это.
  15. Kotopes

    Kotopes Нерд

    В каком смысле?
     
  16. alp69

    alp69 Форумчанин

    Последние три ваши сообщения оформлены как цитаты. Какой смысл читать то, что уже было опубликовано? И даже если развернуть цитату, - как понять где заканчивается цитата и начинаются ваши слова?
    Если вставляете цитату, свои мысли излагайте после тега [/QUOTE]. Или перед тегом [QUOTE....]. Как удобнее по контексту.
    Например, вот цитата:
    А под ней текст, который все увидят.

    P.S. Если хотите обратиться к конкретному пользователю, не цитируя его, просто наберите его ник с символом "собаки" перед ником (без пробела). Например - @Kotopes.
     
    Последнее редактирование: 7 фев 2020
  17. Kotopes

    Kotopes Нерд

    теперь то стало понятно

    @alp69 Век живи век учись)
     
    alp69 нравится это.
  18. Kotopes

    Kotopes Нерд

    @ИгорьК Собрал стенд (счетчик, модуль Wemod d1 mini, rs485) для удобства отработки скетча. При необходимости могу выслать оборудование.

    Лампочка подмигивает.

    в порт выходит:
    > dofile("ce102m_gateP01.lua")
    > Result Now!
    1 Result Table data:
    Result Now!
    1 Result Table data:

    удалить.jpg
     
  19. ИгорьК

    ИгорьК Гуру

    Наконец дошли руки до Энергомера се102м: поехали данные на MQTT брокер через ESP32.
    Можно и через ESP8266, но у ESP32 второй железный UART и работать с настройкой с ним приятнее.



    upload_2021-8-19_11-31-46.png
     
    Последнее редактирование: 19 авг 2021
    glonas, SergeiL и parovoZZ нравится это.
  20. glonas

    glonas Нерд

    @ИгорьК день добрый , не могли бы вы поделится кодом ? Есть 8266 nodemcu , на данный момент работает через espeasy как мост wifi , хотел присобачить к HA но мозгов не хватает .
     
    Последнее редактирование: 30 май 2022