Подключение к ИБП

Добрый день. Хочу снимать параметры ИБП Powerman Online 1000 Plus по порту RS232 вместо штатной UPSilon2000. Подключил переходник RS232-UART, к нему обычный USB-UART на чипе CP2102. Поставил снифер Serial Port Monitor и запустил UPSilon2000. Посмотрел, что приходит в порт. Протокол тут другой, чем у APS. Для запуска обмена отправляется F\r, потом Q1\r. После чего приходит строка с данными.

Подключился через Putty, 8N1 2400, вручную отправляю F\r, потом Q1\r, получаю данные.

Написал по примеру https://arduino.ru/forum/apparatnye-voprosy/smart-ups?page=1#comment-576028 из темы smart-ups такой скетч

#include <SimpleTimer.h> 
#include <SoftwareSerial.h> 
#define t1_interval 2000 
byte n; 
unsigned int timer0,timer1; 
SoftwareSerial mySerial(2, 3); // RX, TX
SimpleTimer timer;

void setup(){ 
 Serial.begin(9600);
 mySerial.begin(2400); 
 timer1 = timer.setInterval(t1_interval, send_Q1); 
} 

 void loop(){
 timer.run(); 
} 

void send_Q1(){ 
n++;
if(!mySerial.available()){ if(n == 5){n = 0;mySerial.write("F\r");Serial.println("F");} else {mySerial.write("Q1\r");Serial.println("Q1");} } 
opros();
 }
 
void opros(){
 if(mySerial.available() > 0){String str = Serial.readString(); Serial.println(str); }
 } 

Проверил между 2 ардуинами, работает. А ИБП ничего не отправляет. Может кто подскажет, что я делаю не так? В коде на один F отправляю 4 Q1.
P.S. Еле разобрался, как писать и форматировать текст. ИМХО, старый форум был как то лучше. Интуитивно понятней.

На протокол Megatec похоже.

Даже не просто похож, а скорее всего, это он и есть.
А как вашим uart_megatec.cpp воспользоваться?

Не увидел где вы читаете mySerial

Точно, в скетче нет. Видимо ошибся когда редактировал скетч для форума. Исправил скетч.

Напрямую - никак. Просто как пример рассматривать.
В принципе там никаких приколов, как с APC, не было. Кинул команду - получил ответ и распарсил.

1 лайк

Так вот кидаю запрос, а ответа нет. Что не так в моем скетче?

Если вообще ничего нет в ответе - может вы попутали Rx Tx ???

Ну как перепутать? USB-UART подключаю всё работает, подключаю другую ардуину, тоже работает. А от ИБП ответа нет.

Вы выкладываете заведомо не рабочий скетч. Пишите, что исправили, но по факту как не было чтения mySerial, так и нет.
Что у вас в рабочем скетче, не известно.
Напишите рабочий тестовый скетч, который реально запускаете.
Сначала попробуйте отправлять только команду F\r На нее ведь должен быть ответ?
Из замеченного - Сейчас у вас n++ не логичен - начинается не с отправки F, возможны перескакивания через значения, т.к. ++ в любом случае, а проверка только если буфер пустой. Не пишите вложенные if на одной строке (хотя бы когда спрашиваете), трудно читать.

1 лайк

Сейчас внимательно глянул. Вы совершенно правы и я тут же нашёл свои ошибки. Исправил скетч, по Вашим замечаниям и он заработал.

#include <SimpleTimer.h>
#include <SoftwareSerial.h>

#define t1_interval   2000
byte n;
unsigned int timer0,timer1; 
//------------------------------------------------------
SoftwareSerial mySerial(2, 3); // RX, TX
SimpleTimer timer;
//------------------------------------------------------
void setup(){
    Serial.begin(9600);
    mySerial.begin(2400);
    timer1 = timer.setInterval(t1_interval, send_Q1);
}
//------------------------------------------------------
void loop(){
     timer.run();
} 
//------------------------------------------------------
void send_Q1(){
  n++;
  if(!mySerial.available()){
     if(n >10){n = 0;mySerial.write("F\r");Serial.println("F");}
     else     {mySerial.write("Q1\r");Serial.println("Q1");}
  }
    opros();
}
//------------------------------------------------------
void opros(){
   while(mySerial.available() > 0){
   String str = mySerial.readString();
       Serial.println(str);
  }
}
//END---------------------------------------------------

Вот ответ:
F
#220.0 005 024.0 50.0

Q1
(241.8 000.0 000.0 000 50.1 2.27 25.0 00000001

Q1
(240.4 000.0 000.0 000 50.1 2.27 25.0 00000001

Q1
(240.4 000.0 000.0 000 50.1 2.27 25.0 00000001

Q1
(241.8 000.0 000.0 000 50.1 2.27 25.0 00000001

Q1
(241.8 000.0 000.0 000 50.1 2.27 25.0 00000001

Огромное спасибо за помощь. Теперь буду думать как данные парсить.

Да совершенно верно, но пока не соображу, как сделать иначе. Ответ начинается после последовательности F, Q1. Приходится часть Q1 пропускать впустую, пока не придет F. Потом всё начинает идти по порядку.
И ещё не понятно, в скетче n = 10. А количество Q1 и соответственно ответов в половину меньше. Странно, почему так?

Зачем вам F, если в Q1 всё уже есть?

В F установленные параметры. В принципе не надо. Но UPSilon2000 периодически опрашивает его. Пусть будет. К тому же наблюдая за обменом, информация появляется после комбинации F, Q1. Вдруг если собьется, то при таком варианте опять восстановится.

Строку “252.9 000.0 219.6 080 50.1 28.30 28.5 00000001” сумел спарсить вот так:

char *data = "252.9 000.0 219.6 080 50.1 28.30 28.5 00000001";
char var1[6];
char var2[6];
char var3[6];
char var4[6];
char var5[6];
char var6[6];
char var7[6];
char number[10];

sscanf(data,"%5s %5s %5s %3s %4s %5s %4s %8s",
&var1,&var2,&var3,&var4,&var5,&var6,&var7,number);

Работать то работает, но может сделать проще?

Что такое “проще”?
Меньше строк уже не будет.

Через Union не заработает что ли ?

В принципе там более-менее фиксированные поля, но с юнионом всё равно писанины больше.

…хотел вставить цитату с раскладкой байт, но всё перекорёжилось.

Значит пойдет такая конструкция. Спасибо. Буду делать дальше. Сделаю http сервер на esp8266 и буду отправлять туда.
Да кстати, заодно спрошу, строка в ИБП начинается со ( или # . Как в scanf отбросить первый символ?

Сдвинуть указатель …

1 лайк