термостат BHT-1000
Модератор: immortal
-
- Сообщения: 17
- Зарегистрирован: Чт июн 18, 2015 6:20 pm
- Благодарил (а): 2 раза
- Поблагодарили: 0
термостат BHT-1000
Добрый день!
Проошу помощи в подключении термостата с RS485.
Сделал следующее:
Majordomo развернут на расбери. К нему переходник RS485-USB. Поднял ser2net. Его настройки:
5331:telnet:600:/dev/ttyUSB0:2400 8DATABITS NONE 1STOPBIT banner
У термостата такое дано описание:
BaudRate 2400
ByteSize 8 Bit
StopBits 1
Parity None
ParityCheck None
Затем создал класс в Majordomo с методом чтения данных (это пока просто для теста)
$Ip=$this->getProperty("Ip"); //=192.168.1.117
$Port=$this->getProperty("Port"); //=5331
$Address=$this->getProperty("Address"); //=10
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $Ip, $Port);
$dev_addr = dechex($Address);
$cda = '0x'.$dev_addr;
/*
0xA0 - Read all data 160
0xA4 - On/Off device 164
0xA9 - Temp setting 169
0xAA - Clock setting 170 CMD,DEV_ID0,DEV_ID1,DATA0,DATA1,DATA2,DATA3,CHKSUM
*/
$checksum = dechex(($cmd + $cda + 0x00 + $data0 + $data1 + $data2 + $data3) & 0xFF ^ 0xA5);
$str = "A0".$dev_ip."000000000015"; // Get all data
$t = pack("H*",$str); // Упаковывает данные в бинарную строку 16го формата с верхнего разряда
socket_write($socket, $t, strlen($t)); // отправляем строку
usleep(200 * 1000); //Откладывает выполнение на микросекунды
$line = socket_read($socket,64); // чтение строки длинной 64 бита (8 байтов)
$hex = (string)join("", unpack("H*", $line));
$res = str_split($hex,2); // Преобразует строку в массив по 2 бита
$this->setProperty('FloorTemperature',implode(",", $res));
$this->setProperty('RoomTemperature',$hex); // присвоить свойству RoomTemperature этого же объекта считанное значение
socket_close($socket);
В последних строчках это я временно вывожу значения в свойства для того чтобы понять что получаю.
В RoomTemperature записывается вот что: 506f727420616c726561647920696e207573650a0d
В FloorTemperature записывается вот что: 50,6f,72,74,20,61,6c,72,65,61,64,79,20,69,6e,20,75,73,65,0a,0d
А по мануалу ответ от термостата должен быть типа:50 10 00 10 14 FF 23 05 2D 15 1B AD;
Где ответ разбирается таким образом:
resposne: 0x50 OK
Data package:0x50 + ID0 + ID1 + Data0 + Data1 + Data2 + Data3 + Data4 + Data5 +
Data6 + Data7 + CheckSum
ID0,ID1 => IP
Data0 => Bit0-Bit1 sensor type
00 -> internal and external sensor
01 -> internal sensor only
10 -> external sensor only
11 -> standby
Bit2-Bit3 Valve Control Selectionon
00 -> Valve is controlled by thermostat
01 -> PC open the valve (thermostat can not control)
10 -> PC close the valve (thermostat can not control)
11 -> Standby
Bit4 turn-on/off
0 -> turn-off
1 -> turn-on
Bit5 Standby
Bit6 low temperature protection flag
0-> need low temperature protection
1-> cancel low temperature protection
Bit7 high temperature protection flag
0-> need high temperature protection
1-> cancel high temperature protection
Data1 => Bit0 lock mode
0-> Buttons are locked except on/off.
1-> All bottons are locked.
Bit1 Lock status
0->unlock
1->lock
Bit2 Load status
0-> load close
1-> load open
Bit3 Sensor status
0-> sensor normal
1-> sensor error
Bit4~bit7 deadzone temperature(1℃~5℃)
Data2 => calibration temperature(-9℃~9℃)
Data3 => seng temperature(5℃~35℃)
Data4 => low temperature protecctioon (5℃~10℃)
Data5 => high temperature protection (35℃~70℃)
Data6 => Room Temperature
Data7 => Floor Temperature
CheckSum
Т.е приходит полная ерунда. И не могу понять, где косяк. Толи отправляю, толи разбираю ответ не правильно, толи ошибка в настройках ser2net?
Подскажите, пожалуйста.
Проошу помощи в подключении термостата с RS485.
Сделал следующее:
Majordomo развернут на расбери. К нему переходник RS485-USB. Поднял ser2net. Его настройки:
5331:telnet:600:/dev/ttyUSB0:2400 8DATABITS NONE 1STOPBIT banner
У термостата такое дано описание:
BaudRate 2400
ByteSize 8 Bit
StopBits 1
Parity None
ParityCheck None
Затем создал класс в Majordomo с методом чтения данных (это пока просто для теста)
$Ip=$this->getProperty("Ip"); //=192.168.1.117
$Port=$this->getProperty("Port"); //=5331
$Address=$this->getProperty("Address"); //=10
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $Ip, $Port);
$dev_addr = dechex($Address);
$cda = '0x'.$dev_addr;
/*
0xA0 - Read all data 160
0xA4 - On/Off device 164
0xA9 - Temp setting 169
0xAA - Clock setting 170 CMD,DEV_ID0,DEV_ID1,DATA0,DATA1,DATA2,DATA3,CHKSUM
*/
$checksum = dechex(($cmd + $cda + 0x00 + $data0 + $data1 + $data2 + $data3) & 0xFF ^ 0xA5);
$str = "A0".$dev_ip."000000000015"; // Get all data
$t = pack("H*",$str); // Упаковывает данные в бинарную строку 16го формата с верхнего разряда
socket_write($socket, $t, strlen($t)); // отправляем строку
usleep(200 * 1000); //Откладывает выполнение на микросекунды
$line = socket_read($socket,64); // чтение строки длинной 64 бита (8 байтов)
$hex = (string)join("", unpack("H*", $line));
$res = str_split($hex,2); // Преобразует строку в массив по 2 бита
$this->setProperty('FloorTemperature',implode(",", $res));
$this->setProperty('RoomTemperature',$hex); // присвоить свойству RoomTemperature этого же объекта считанное значение
socket_close($socket);
В последних строчках это я временно вывожу значения в свойства для того чтобы понять что получаю.
В RoomTemperature записывается вот что: 506f727420616c726561647920696e207573650a0d
В FloorTemperature записывается вот что: 50,6f,72,74,20,61,6c,72,65,61,64,79,20,69,6e,20,75,73,65,0a,0d
А по мануалу ответ от термостата должен быть типа:50 10 00 10 14 FF 23 05 2D 15 1B AD;
Где ответ разбирается таким образом:
resposne: 0x50 OK
Data package:0x50 + ID0 + ID1 + Data0 + Data1 + Data2 + Data3 + Data4 + Data5 +
Data6 + Data7 + CheckSum
ID0,ID1 => IP
Data0 => Bit0-Bit1 sensor type
00 -> internal and external sensor
01 -> internal sensor only
10 -> external sensor only
11 -> standby
Bit2-Bit3 Valve Control Selectionon
00 -> Valve is controlled by thermostat
01 -> PC open the valve (thermostat can not control)
10 -> PC close the valve (thermostat can not control)
11 -> Standby
Bit4 turn-on/off
0 -> turn-off
1 -> turn-on
Bit5 Standby
Bit6 low temperature protection flag
0-> need low temperature protection
1-> cancel low temperature protection
Bit7 high temperature protection flag
0-> need high temperature protection
1-> cancel high temperature protection
Data1 => Bit0 lock mode
0-> Buttons are locked except on/off.
1-> All bottons are locked.
Bit1 Lock status
0->unlock
1->lock
Bit2 Load status
0-> load close
1-> load open
Bit3 Sensor status
0-> sensor normal
1-> sensor error
Bit4~bit7 deadzone temperature(1℃~5℃)
Data2 => calibration temperature(-9℃~9℃)
Data3 => seng temperature(5℃~35℃)
Data4 => low temperature protecctioon (5℃~10℃)
Data5 => high temperature protection (35℃~70℃)
Data6 => Room Temperature
Data7 => Floor Temperature
CheckSum
Т.е приходит полная ерунда. И не могу понять, где косяк. Толи отправляю, толи разбираю ответ не правильно, толи ошибка в настройках ser2net?
Подскажите, пожалуйста.
-
- Сообщения: 254
- Зарегистрирован: Ср июл 09, 2014 3:48 pm
- Благодарил (а): 6 раз
- Поблагодарили: 41 раз
Re: термостат BHT-1000
Может, бодовую скорость неправильно выставили?
А вообще-то если вы что-то передаете по RS485, это вовсе не означает, что приемник RS485 получит точно то же самое. Работа с RS485 заметно отличается от RS232. Основная разница в том, что в паузах между пакетами на входах приемников RS232 ничего нет, а на входы всех приемников RS485, если нет резисторов подтяжки, все время лезет мусор. Поэтому в RS485 надо как-то избавлятся от этого мусора, прежде чем передавать/принимать пакет. Или хотя бы подтяжку ставить, линию А на +5В, линию В на землю, резисторы по 1к.
По-хорошему, передатчик RS485, прежде чем гнать пакет, должен включить свой шинный формирователь в режим передачи, но некоторое время (несколько байт-интервалов) ничего не передавать из UART. Во время этой паузы на выходе передатчика (и, соответственно, на входе приемника, которому идет передача) статический уровень, поэтому приемник, используя тайм-ауты, может избавиться от мусора, принятого в UART ранее. После этого пакет может быть принят правильно.
Ну и во время передачи пакета надо гарантировать, что пауза между соседними байтами отсутствут или мала. Иначе приемник по тайм-ауту вычистит все принятое ранее, так же, как он вычищает мусор.
Есть и другие способы, описанное выше - это работа в стиле Модбас, т.е. типичный случай.
А вообще-то если вы что-то передаете по RS485, это вовсе не означает, что приемник RS485 получит точно то же самое. Работа с RS485 заметно отличается от RS232. Основная разница в том, что в паузах между пакетами на входах приемников RS232 ничего нет, а на входы всех приемников RS485, если нет резисторов подтяжки, все время лезет мусор. Поэтому в RS485 надо как-то избавлятся от этого мусора, прежде чем передавать/принимать пакет. Или хотя бы подтяжку ставить, линию А на +5В, линию В на землю, резисторы по 1к.
По-хорошему, передатчик RS485, прежде чем гнать пакет, должен включить свой шинный формирователь в режим передачи, но некоторое время (несколько байт-интервалов) ничего не передавать из UART. Во время этой паузы на выходе передатчика (и, соответственно, на входе приемника, которому идет передача) статический уровень, поэтому приемник, используя тайм-ауты, может избавиться от мусора, принятого в UART ранее. После этого пакет может быть принят правильно.
Ну и во время передачи пакета надо гарантировать, что пауза между соседними байтами отсутствут или мала. Иначе приемник по тайм-ауту вычистит все принятое ранее, так же, как он вычищает мусор.
Есть и другие способы, описанное выше - это работа в стиле Модбас, т.е. типичный случай.
-
- Сообщения: 136
- Зарегистрирован: Вс июл 14, 2013 2:42 pm
- Благодарил (а): 6 раз
- Поблагодарили: 27 раз
Re: термостат BHT-1000
Доброго времени суток.
5331:telnet:600:/dev/ttyUSB0:2400 8DATABITS NONE 1STOPBIT banner - Каждый раз при открытии порта туда выплевывается баннер. Это лишнее.
У Вас в ответе в конце 0x0A 0x0D это перевод строки и перевод каретки. Да и судя по длине ответ термостата смешивается с чем ещё. Уберите баннер в ser2net и попробуйте. Если не получится то тогда план Б:
P.S.
Ещё вместо telnet поставьте raw
План Б:
Попробуйте воткнуть ваш RS485-USB в комп с виндой, поставьте Modbus Poll, настройте порт, скорость, четность и подключитесь. Будут сыпаться ошибки, не обращаем внимания и нажимаем Alt+T. В верхней строке пишете: A0 10 00 00 00 00 00 15 и жмете Send.
Внизу должен быть ответ от термостата.
Отвечая на вопрос в личке, простите только что увидел, скажу: Термостаты отличные,ничего не сломалось, все работает прекрасно. Есть два неприятных момента: низкая скорость и не настоящий Modbus. Но последний факт полностью снимает вопрос со скоростью, потому что в общую сеть modbus эти термостаты включить не получится.
5331:telnet:600:/dev/ttyUSB0:2400 8DATABITS NONE 1STOPBIT banner - Каждый раз при открытии порта туда выплевывается баннер. Это лишнее.
У Вас в ответе в конце 0x0A 0x0D это перевод строки и перевод каретки. Да и судя по длине ответ термостата смешивается с чем ещё. Уберите баннер в ser2net и попробуйте. Если не получится то тогда план Б:
P.S.
Ещё вместо telnet поставьте raw
План Б:
Попробуйте воткнуть ваш RS485-USB в комп с виндой, поставьте Modbus Poll, настройте порт, скорость, четность и подключитесь. Будут сыпаться ошибки, не обращаем внимания и нажимаем Alt+T. В верхней строке пишете: A0 10 00 00 00 00 00 15 и жмете Send.
Внизу должен быть ответ от термостата.
Отвечая на вопрос в личке, простите только что увидел, скажу: Термостаты отличные,ничего не сломалось, все работает прекрасно. Есть два неприятных момента: низкая скорость и не настоящий Modbus. Но последний факт полностью снимает вопрос со скоростью, потому что в общую сеть modbus эти термостаты включить не получится.
-
- Сообщения: 17
- Зарегистрирован: Чт июн 18, 2015 6:20 pm
- Благодарил (а): 2 раза
- Поблагодарили: 0
Re: термостат BHT-1000
Geban.
Собственно план Б я испробовал первым делом сразу после покупки и там все работает хорошо.
План А попробую в самое ближайшее время.
А про качество термостатов я спрашивал потому что у меня с ними есть проблемы.
Когда проскакивает разряд между рукой и рамкой, он отключается. Причем у меня их 4. И такое на всех.
Вот тут видео снимал. Отсылал продавцу на али.
https://youtu.be/8Dv7qPJrEAM
Что касается скорости. То я думаю ее достаточно. Температура процесс с инертный и с большим запаздыванием. Поэтому думаю хватит.
Собственно план Б я испробовал первым делом сразу после покупки и там все работает хорошо.
План А попробую в самое ближайшее время.
А про качество термостатов я спрашивал потому что у меня с ними есть проблемы.
Когда проскакивает разряд между рукой и рамкой, он отключается. Причем у меня их 4. И такое на всех.
Вот тут видео снимал. Отсылал продавцу на али.
https://youtu.be/8Dv7qPJrEAM
Что касается скорости. То я думаю ее достаточно. Температура процесс с инертный и с большим запаздыванием. Поэтому думаю хватит.
-
- Сообщения: 136
- Зарегистрирован: Вс июл 14, 2013 2:42 pm
- Благодарил (а): 6 раз
- Поблагодарили: 27 раз
Re: термостат BHT-1000
Ну тогда дело точно в ser2net. а по поводу статики.. печально.. можно конечно попробовать разобрать их и изолировать эту рамку... наверно. но у меня такого эффекта нет
-
- Сообщения: 17
- Зарегистрирован: Чт июн 18, 2015 6:20 pm
- Благодарил (а): 2 раза
- Поблагодарили: 0
Re: термостат BHT-1000
Метод А не сработал. Настройил так: 5331:raw:600:/dev/ttyUSB0:2400 8DATABITS NONE 1STOPBIT
Решил тестить код. Упростил его до минимума.
$Ip='192.168.1.117';
$Port='5331';
$Address='10';
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $Ip, $Port);
$str = "A010000000000015"; // Get all data
$t = pack("H*",$str); // Упаковывает данные в бинарную строку 16го формата с верхнего разряда
socket_write($socket, $t, strlen($t)); // отправляем строку
usleep(200 * 1000); //Откладывает выполнение на микросекунды
$line = socket_read($socket,64); // чтение строки длинной 64 бита (8 байтов)
print_r($line);
получаю в браузере следующую строку:
�������� ser2net port 5331 device /dev/ttyUSB0 [2400 N81] (
Я так понимаю что это что то не то?
Если задать большую длину считывания то вся строка выглядит так:
Решил тестить код. Упростил его до минимума.
$Ip='192.168.1.117';
$Port='5331';
$Address='10';
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $Ip, $Port);
$str = "A010000000000015"; // Get all data
$t = pack("H*",$str); // Упаковывает данные в бинарную строку 16го формата с верхнего разряда
socket_write($socket, $t, strlen($t)); // отправляем строку
usleep(200 * 1000); //Откладывает выполнение на микросекунды
$line = socket_read($socket,64); // чтение строки длинной 64 бита (8 байтов)
print_r($line);
получаю в браузере следующую строку:
�������� ser2net port 5331 device /dev/ttyUSB0 [2400 N81] (
Я так понимаю что это что то не то?
Если задать большую длину считывания то вся строка выглядит так:
- Вложения
-
- ответ.JPG (18.03 КБ) 9906 просмотров
-
- Сообщения: 136
- Зарегистрирован: Вс июл 14, 2013 2:42 pm
- Благодарил (а): 6 раз
- Поблагодарили: 27 раз
Re: термостат BHT-1000
Хм.. а если работать с портов на прямую? через fopen fread fwrite ? не используя ser2net... попробуйте.. просто надо понять что именно не пашет. У Вас же на малине ser2net куртится помоему.. попробуйте прогнать там скрипт. или можно попробовать тем же модбас полл подключится к порту ser2net только надо протокол выбрать RTU over TCP
-
- Сообщения: 17
- Зарегистрирован: Чт июн 18, 2015 6:20 pm
- Благодарил (а): 2 раза
- Поблагодарили: 0
Re: термостат BHT-1000
Модбас полл дал я так понимаю не то. Следовательно проблема в настройке ser2net или то как он настроил порт. Я правильно понял?Geban писал(а):Хм.. а если работать с портов на прямую? через fopen fread fwrite ? не используя ser2net... попробуйте.. просто надо понять что именно не пашет. У Вас же на малине ser2net куртится помоему.. попробуйте прогнать там скрипт. или можно попробовать тем же модбас полл подключится к порту ser2net только надо протокол выбрать RTU over TCP
И если можно первую часть подробнее раскажите. А то я начинающий юзер в этом вопросе.