Добрый вечер, уважаемые форумчане. Пытаюсь опросить счетчик электроэнергии Энергомера 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В и обмен таки происходит из родного софта производителя счетчика на той же физике, то, видимо, какие-то проблемы в коде. В чем может быть проблема? Заранее спасибо за ответы.
Проверьте подключение RS-485. Вероятность перепутать А и В равна 50%. Просто поменяйте их местами. Проверьте родная скорость на которой счетчик работает 9600 или меньше. И проверьте настройку порта, смущает 7 бит и бит четности.
Спасибо за ответ. Но я конечно же все это уже сделал и не раз. Формат символов заложен в стандарте на протокол обмена (ГОСТ - МЭК 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 идентичен им. Я не очень хорошо разбираюсь в этом вопросе, но есть подозрение, что тип данных не соответствует тому, который ждет счетчик. Гуру программирования, проясните этот момент пожалуйста.
"Элемент массива укладывается в байт. Значит, все правильно. счетчик вообще не разбирается ни в каких типах данных. Типы данных - для человекообразных. Внутри счетчика нули и единицы. Через что и как эти нули и единицы отправить и принять - это задача программиста. Через какую абстракцию он это сделает - счетчику фиолетово.
Прошу меня простить, я неправильно выразился. Вопрос в правиле формирования этого запроса в счетчик, например функции Serial.write и Serial.print, в случае с espruino, делают это, если я правильно понимаю, по-разному. А по изначальному вопросу вы можете высказать какие-нибудь предположения?
Посмотрите, если порт настроен на передачу только 7 бит, то максимальное число которое можно передать 0х7F, а у вас в коде явно есть байты больше 0x7F.
Тож очевидно, настроили 7 бит, отправили команду типа byte cmd1[] = {0xaF,0x3F,0x21,0x8D,0x0A}; она долетела в как 0x2F,0x3F,0x21,0x0D,0x0A и что он должен ответить?
Именно для оптопорта он, есть редакция 61107-2011, но не суть, на 485-м интерфейсе немножко другой протокол у энергомера. Пакеты не так кодируются.
Спасибо всем за ответы. Решение пока окончательно не оформилось, но появилась пара новых мыслей. Вы правы. Я как-то упустил этот момент. И, судя по всему, это и есть ключ к пониманию того, почему ничего не работает. Я натолкнулся на одну статью, в которой автор пишет: Т.е., в вышеприведенном скетче, soft serial и перекодирование команд не спроста. В любом случае, проверю эту гипотезу. Да нет. Параграф 3.1 как раз про RS-485. Но я не уверен, что это ценная для вас информация. Это описание для другой модели счетчика. В моем случае модель - CE301 (без M в конце), там другая система команд. У Энергомеры все как-то сложно.
для освоения работы со счетчиком Энергомера рекомендую использовать простую свистульку USB<->RS485 в связке с их софтом AdminTool. У AdminTool есть монитор обмена что делает на порядок понятнее и прозрачнее понимание алгоритма опроса счетчика, т.к. обмен идет с контрольными суммами и битами четности. Просто так послать от балды запрос на счетчик и получить от него ответ не получиться. Нужна авторизация и установка режима. Если нужен будет простецкий скетч для ардуины с 485 интерфейсом, то выложу. https://yandex.ru/video/preview/?te...80&wiz_type=vital&filmId=14571320762010708128