История изменений
Исправление James_Holden, (текущая версия) :
Постараюсь поподробнее описать.
Сначала о железе, на всякий случай.
Весы в цеху, от них идет кабель RS-232 в лабораторию, втыкается в искрозащитный барьер от весов, далее идет кабель RS-232, втыкается в преобразователь интерфейсов MOXA nPort.
MOXA по ethernet связан с сервером. В моем случае, со стороны монтажа было 100500 ошибок, в распайке кабелей, еще какой-то хрени. После перепроверки всего по документации на весы и MOXA, прозвона кабелей и проверки RS-232 в эхо режиме перемычкой между 3 и 4 ножкой разъема, перепайки кабелей я стал уверен что железная часть работает.
Далее - я проверял настройки весов, которые делаются через их меню. Там задавал скорость обмена, настройки UART протокола. Тоже могут быть сюрпризы.
Теперь о программной части. Поскольку все работает через ethernet - RS-232 преобразователь, то работа идет через TCP сокет. Каждому RS-232 порту на MOXA соответствует свой номер TCP порта, и тут важно не перепутать! А также, в моем случае MOXA преобразователей было несколько и все постоянно путали какому IP адресу соответствует какой преобразователь.
Вот код python, который получает массу нетто с весов.
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(3)
s.connect((weigher_ip, int(weigher_port)))
if self.id == 4:
s.sendall(b'\xFF\x01\xC2\x8A\xFF\xFF')
elif self.id == 5:
s.sendall(b'\xFF\x02\xC2\x8F\xFF\xFF')
time.sleep(0.1)
data = s.recv(1024)
massa_weigher_get = (data[3] & 0x0F) + ((data[3] & 0xF0) / 16) * 10 + (data[4] & 0x0F) * 100 + ((data[4] & 0xF0) / 16) * 1000 + (data[5] & 0x0F) * 10000 + ((data[5] & 0xF0) / 16) * 100000
steady_weigher = data[6] & 0b00010000
commapos = data[6] & 0b00000111
if steady_weigher:
massa_weigher = massa_weigher_get / (10 ** commapos) *1000
Вот этот запрос к весам
if self.id == 4:
s.sendall(b'\xFF\x01\xC2\x8A\xFF\xFF')
elif self.id == 5:
s.sendall(b'\xFF\x02\xC2\x8F\xFF\xFF')
такой, потому что у меня двое весов с адресами 1 и 2. Получается два разных запроса с разной контрольной суммой.
А теперь ВНИМАНИЕ! Вот эта строчка
time.sleep(0.1)
очень важна! Если не сделать паузу после запроса к весам, нифига не работало. Я так и не понял почему, видимо я не настоящий сварщик )) Но вот так.
steady_weigher это бит «устаканивания» веса.
По контрольной сумме сейчас в следующем посте.
Исходная версия James_Holden, :
Постараюсь поподробнее описать.
Сначала о железе, на всякий случай.
Весы в цеху, от них идет кабель RS-232 в лабораторию, втыкается в искрозащитный барьер от весов, далее идет кабель RS-232, втыкается в преобразователь интерфейсов MOXA nPort.
MOXA по ethernet связан с сервером. В моем случае, со стороны монтажа было 100500 ошибок, в распайке кабелей, еще какой-то хрени. После перепроверки всего по документации на весы и MOXA, прозвона кабелей и проверки RS-232 в эхо режиме перемычкой между 3 и 4 ножкой разъема, перепайки кабелей я стал уверен что железная часть работает.
Далее - я проверял настройки весов, которые делаются через их меню. Там задавал скорость обмена, настройки UART протокола. Тоже могут быть сюрпризы.
Теперь о программной части. Поскольку все работает через ethernet - RS-232 преобразователь, то работа идет через TCP сокет. Каждому RS-232 порту на MOXA соответствует свой номер TCP порта, и тут важно не перепутать! А также, в моем случае MOXA преобразователей было несколько и все постоянно путали какому IP адресу соответствует какой преобразователь.
Вот код python, который получает массу нетто с весов.
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(3)
s.connect((weigher_ip, int(weigher_port)))
if self.id == 4:
s.sendall(b'\xFF\x01\xC2\x8A\xFF\xFF')
elif self.id == 5:
s.sendall(b'\xFF\x02\xC2\x8F\xFF\xFF')
time.sleep(0.1)
data = s.recv(1024)
massa_weigher_get = (data[3] & 0x0F) + ((data[3] & 0xF0) / 16) * 10 + (data[4] & 0x0F) * 100 + ((data[4] & 0xF0) / 16) * 1000 + (data[5] & 0x0F) * 10000 + ((data[5] & 0xF0) / 16) * 100000
steady_weigher = data[6] & 0b00010000
commapos = data[6] & 0b00000111
if steady_weigher:
massa_weigher = massa_weigher_get / (10 ** commapos) *1000
Вот этот запрос к весам
if self.id == 4:
s.sendall(b'\xFF\x01\xC2\x8A\xFF\xFF')
elif self.id == 5:
s.sendall(b'\xFF\x02\xC2\x8F\xFF\xFF')
такой, потому что у меня двое весов с адресами 1 и 2. Получается два разных запроса с разной контрольной суммой.
А теперь ВНИМАНИЕ! Вот эта строчка
time.sleep(0.1)
очень важна! Если не сделать паузу после запроса к весам, нифига не работало. Я так и не понял почему, видимо я не настоящий сварщик )) Но вот так.
По контрольной сумме сейчас в следующем посте.