Опрос счетчика Энергомера по RS-485

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем hrimfaxi, 28 янв 2019.

  1. hrimfaxi

    hrimfaxi Нуб

    Добрый вечер, уважаемые форумчане.

    Пытаюсь опросить счетчик электроэнергии Энергомера CE301 по RS-485, но пока ничего не получается.
    Использую Iskra JS и ESP32, прошитой espruino. В качестве конвертеров TTL<->RS-485 использую самые обычные китайские модули на базе MAX485 и MAX3485 (в случае с ESP32). Код, для начала, самый простой:
    Код (Javascript):
    Serial3.setup(9600, {
      tx: P1,
      rx: P0,
      bytesize: 7,
      parity: 'even',
      stopbits: 1,
      flow: 'none'
    });

    digitalWrite(P3, 1);

    Serial3.write([0x2F,0x3F,0x21,0x0D,0x0A]);

    digitalWrite(P3, 0);

    Serial3.on('data', function(data) {
        console.log('Serial: ', data);
    });
    т.е. устанавливаем Serial в режим заданный производителем счетчика (7E1), переводим конвертер в режим передачи, передаем некоторый hex, согласно протокола обмена, переводим ковертер в режим чтения, ждем ответа. В теории, счетчик должен ответить hex'ом: 0x2F 0x45 0x4B 0x54, но в ответ не приходит ничего. Учитывая, что между Икрой и ESP обмен происходит, т.е. модули рабочие, шина питается от отдельного БП на 9В и обмен таки происходит из родного софта производителя счетчика на той же физике, то, видимо, какие-то проблемы в коде. В чем может быть проблема?

    Заранее спасибо за ответы.
     
  2. Radius

    Radius Гик

    Проверьте подключение RS-485. Вероятность перепутать А и В равна 50%. Просто поменяйте их местами. Проверьте родная скорость на которой счетчик работает 9600 или меньше. И проверьте настройку порта, смущает 7 бит и бит четности.
     
    Последнее редактирование: 29 янв 2019
  3. hrimfaxi

    hrimfaxi Нуб

    Спасибо за ответ. Но я конечно же все это уже сделал и не раз. Формат символов заложен в стандарте на протокол обмена (ГОСТ - МЭК 61107-2001), поэтому тут вроде все правильно.

    Я ознакомился с примером, который нашел у господ ардуинщиков на их форуме (в любом случае, спасибо автору за этот скетч и, надеюсь, он не обидится, что я выложу его здесь):
    Код (C++):
    #include <SoftwareSerial.h>
    long Previous = 0;
    int val = 0;
    int Time_1 = 1;    
    int Time_2 = 2;      
    int Time_3 = 3;
    int Time_4 = 4;
    int Time_5 = 15;

    // открываем сессию
    byte cmd1[] = {0xaF,0x3F,0x21,0x8D,0x0A};
    // читаем тип счетчика
    byte cmd2[] = {0x06,0x30,0x35,0xb1,0x8d,0x0a};
    // снимаем показания
    byte cmd3[] = {0x81,0xd2,0xb1,0x82,0xc5,0xd4,0x30,0x50,0xc5,0x28,0xa9,0x03,0xb7};
    // напряжения на фазах
    byte cmd4[] = {0x81,0xd2,0xb1,0x82,0x56,0xcf,0xcc,0xd4,0x41,0x28,0xa9,0x03,0x5f};

    #define DIR 8 // пин управления прием/передача

    SoftwareSerial RS485 (7, 6); // RX, TX

    void setup()
    {
      Serial.begin(9600);
      RS485.begin(9600);
      pinMode(DIR, OUTPUT);
      digitalWrite(DIR, HIGH);
    }
    void loop()
    {
       if (RS485.available())
        {
        char response = RS485.read();
        response &= 0x7F;// convert 8N1 to 7E1
        Serial.print(response);
        }
        if (millis() - Previous > 1000)
      {
        Previous = millis();    
        val ++;

           if (val == Time_1)
           {
             digitalWrite(DIR, HIGH);
             RS485.write (cmd1,5);
             digitalWrite(DIR, LOW);
           }

           if (val == Time_2)
           {
            digitalWrite(DIR, HIGH);
             RS485.write (cmd2,6);
            digitalWrite(DIR, LOW);
           }

           if (val == Time_3)
           {
             digitalWrite(DIR, HIGH);
             RS485.write (cmd3,13);
             digitalWrite(DIR, LOW);
           }

           if (val == Time_4)
           {
             digitalWrite(DIR, HIGH);
             RS485.write (cmd4,13);
             digitalWrite(DIR, LOW);
           }

           if (val == Time_5)
           {
             val = 0;
           }
      }
    }
     
    Вроде все понятно, но меня смущает, что массивы (это же массивы?) с командами имеют тип byte. Не совсем уверен, что мой массив, который отправляет Serial.write идентичен им. Я не очень хорошо разбираюсь в этом вопросе, но есть подозрение, что тип данных не соответствует тому, который ждет счетчик. Гуру программирования, проясните этот момент пожалуйста.
     
  4. parovoZZ

    parovoZZ Гуру

    "Элемент массива укладывается в байт. Значит, все правильно.
    счетчик вообще не разбирается ни в каких типах данных. Типы данных - для человекообразных. Внутри счетчика нули и единицы. Через что и как эти нули и единицы отправить и принять - это задача программиста. Через какую абстракцию он это сделает - счетчику фиолетово.
     
  5. hrimfaxi

    hrimfaxi Нуб

    Прошу меня простить, я неправильно выразился. Вопрос в правиле формирования этого запроса в счетчик, например функции Serial.write и Serial.print, в случае с espruino, делают это, если я правильно понимаю, по-разному.

    А по изначальному вопросу вы можете высказать какие-нибудь предположения?
     
  6. parovoZZ

    parovoZZ Гуру

    Замкни tx с rx и посмотри, что возвращается.
     
  7. Radius

    Radius Гик

    Посмотрите, если порт настроен на передачу только 7 бит, то максимальное число которое можно передать 0х7F, а у вас в коде явно есть байты больше 0x7F.
     
  8. parovoZZ

    parovoZZ Гуру

    почитал по диагонали - ГОСТ для IrDA, а речь в топике про провода.
     
  9. Тож очевидно, настроили 7 бит, отправили команду типа byte cmd1[] = {0xaF,0x3F,0x21,0x8D,0x0A}; она долетела в как 0x2F,0x3F,0x21,0x0D,0x0A и что он должен ответить?
     
  10. Именно для оптопорта он, есть редакция 61107-2011, но не суть, на 485-м интерфейсе немножко другой протокол у энергомера. Пакеты не так кодируются.
     
  11. parovoZZ

    parovoZZ Гуру

    на одном форуме прочитал, что у челдона после настройки 8 бит и 1 бит стопа все заработало.
     
  12. parovoZZ

    parovoZZ Гуру

    таки 8 бит))
     
  13. hrimfaxi

    hrimfaxi Нуб

    Спасибо всем за ответы.

    Решение пока окончательно не оформилось, но появилась пара новых мыслей.

    Вы правы. Я как-то упустил этот момент. И, судя по всему, это и есть ключ к пониманию того, почему ничего не работает. :) Я натолкнулся на одну статью, в которой автор пишет:

    Т.е., в вышеприведенном скетче, soft serial и перекодирование команд не спроста. В любом случае, проверю эту гипотезу.

    Да нет. Параграф 3.1 как раз про RS-485. Но я не уверен, что это ценная для вас информация. :)

    Это описание для другой модели счетчика. В моем случае модель - CE301 (без M в конце), там другая система команд. У Энергомеры все как-то сложно. :)
     
  14. Siv62

    Siv62 Нуб

    для освоения работы со счетчиком Энергомера рекомендую использовать простую свистульку USB<->RS485 в связке с их софтом AdminTool.
    У AdminTool есть монитор обмена что делает на порядок понятнее и прозрачнее понимание алгоритма опроса счетчика, т.к. обмен идет с контрольными суммами и битами четности. Просто так послать от балды запрос на счетчик и получить от него ответ не получиться. Нужна авторизация и установка режима. Если нужен будет простецкий скетч для ардуины с 485 интерфейсом, то выложу.
    https://yandex.ru/video/preview/?te...80&wiz_type=vital&filmId=14571320762010708128

    [​IMG]