Как использовать последовательную запись python в ПЛК?

У меня есть 2 ПЛК с последовательным портом. один протокол mitsubishi Q00Jcpu mc, другой протокол omron hostlink.

Я попытался использовать python pyserial lib для записи в ПЛК и чтения ответа. Но потерпел неудачу, я попытался использовать последовательный инструмент для тестирования и получил хороший ответ, последовательный инструмент успешно связывается с ПЛК, прочитал адрес CIO начальный 100 и размер 2, получилось 12345678, это верный результат.

мой код:

import serial

omr = serial.Serial(port='COM4', baudrate=9600, timeout=0.5)
omr.parity=serial.PARITY_EVEN
omr.bytesize = 7
omr.stopbits =2

resp = omr.write(b'\x40\x30\x30\x46\x41\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31\x30\x31\x42\x30\x30\x30\x36\x34\x30\x30\x30\x30\x30\x32\x30\x35\x2a\x0d')
print(resp) # print 34
resp = omr.write(b'@00FA0000000000101B0006400000205*\CR')
print(resp) # print 36 

Кажется, вернуть len данных записи, я пробовал и шестнадцатеричный, и ascii, все потерпело неудачу.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял как, возврат serial.write не результат. Если нужен ответ от устройства, следует использовать read_until(), не уверен, что это хороший способ, дайте мне знать, если у вас есть какие-либо предложения. В любом случае, класс, который я делаю, может читать ПЛК omron, задавая разные параметры, надеюсь, это может кому-то помочь.

ДЕМО:

import serial

# cmd = '0101B00064000001'

class OMR_SERIAL_TOOL:
    def __init__(self,port,baudrate):
        self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
        self.omr.parity=serial.PARITY_EVEN
        self.omr.bytesize = 7
        self.omr.stopbits =2
        self.head ='@00FA000000000'
    
    @staticmethod
    def get_xor(frame):
        res = ord(frame[0])
        for i in frame[1:]:
            res ^= ord(i)
        res = str(res)
        if len(res) == 1:
            res = '0'+res
        return res


    def omr_read(self,head,cmd):
        xor = OMR_SERIAL_TOOL.get_xor(head+cmd)
        self.omr.write('{}{}{}*\r'.format(head,cmd,xor).encode())
        resp = self.omr.read_until("\r".encode())

        return str(resp[23:-4],encoding='utf-8')


test = OMR_SERIAL_TOOL('COM4',9600)
res = test.omr_read(test.head,cmd='0101B00064000002')
print(res) # 12345678 , which is the correct response

БУМ! ВЕРСИЯ 1.0

import serial

class OMR_SERIAL_TOOL:
    def __init__(self,port,baudrate,mode):
        self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
        self.omr.parity=serial.PARITY_EVEN
        self.omr.bytesize = 7
        self.omr.stopbits =2
        # fins mdoe
        if mode == 'fins':
            self.head ='@00FA000000000'
        self.cmd_map = {
            "MEMORY_AREA_READ":"0101",
            "MEMORY_AREA_WRITE":"0102",
            "MEMORY_AREA_FILL":"0103",
            "MULTI_MEMORY_AREA_READ":"0104",
            "MEMORY_AREA_TRANSFER":"0105"
        }
        # cs/cj mode
        self.io_memory_area_code_map = {
            "CIO_bit":"30",
            "WR_bit":"31",
            "HR_bit":"32",
            "AR_bit":"33",
            "CIO_word":"B0",
            "WR_word":"B1",
            "HR_word":"B2",
            "AR_word":"B3"
        }
    
    @staticmethod
    def get_xor(frame):
        res = ord(frame[0])
        for i in frame[1:]:
            res ^= ord(i)
        res = str(res)
        if len(res) == 1:
            res = '0'+res
        res = str(hex(int(res)))[2:]
        upcase_res = ''
        for i in res:
            if i.isdigit():
                upcase_res += i
            elif i.isalpha():
                upcase_res += i.upper()
        if len(upcase_res) == 1:
            upcase_res = '0'+upcase_res
        return upcase_res


    def omr_read(self,cmd,code,address,size):
        address = str(hex(address))[2:]
        size = str(hex(size))[2:]

        while len(address) < 4:
            address = '0' + address
        while len(size) < 4:
            size = '0' + size

        frame = self.head+cmd+code+address+'00'+size
        xor = OMR_SERIAL_TOOL.get_xor(frame)
        #print(frame+xor)
        self.omr.write('{}{}*\r'.format(frame,xor).encode())
        resp = self.omr.read_until("\r".encode())

        return str(resp[23:-4],encoding='utf-8')


omr_client = OMR_SERIAL_TOOL('COM4',9600,'fins')
cmd = omr_client.cmd_map['MEMORY_AREA_READ']
code = omr_client.io_memory_area_code_map['CIO_word']

res = omr_client.omr_read(cmd,code,address=500,size=1)

Я хорошо протестировал его на CIO read, пожалуйста, дайте мне знать, если вы обнаружите какие-либо ошибки.

Другие вопросы по теме

Похожие вопросы

Панды, получить первый и последний индекс столбца для значения строки
PlotWidget Pyqtgraph отображается неправильно
Python3 вызывает csv.DictReader — объект не вызывается
Django - реализация трекера последних изменений в файле HTML
Увеличивайте дату до тех пор, пока в python больше не будет дубликатов
Ошибка Flask-SQLAlchemy - AttributeError: объект «NoneType» не имеет атрибута «добавить»
Как рассчитать поддержку при наличии истинно положительных, истинно отрицательных, ложноположительных и ложноотрицательных результатов?
Использование Pandas для поиска раздела/окна с наименьшей дисперсией во временном ряду
Matplotlib: есть ли способ, чтобы мы могли видеть результат графика и работать с ним, пока процедуры после `.show()` обрабатываются Python?
LightFM как делать прогнозы для новых пользователей (холодный старт) - идентификатор пользователя 8 не в сопоставлении идентификаторов пользователей