Найти - Пользователи
Полная версия: PySerial работа с COM портом, непонятки с типами
Начало » Python для экспертов » PySerial работа с COM портом, непонятки с типами
1
Emmk
Добрый всем день!

Разрабатываю программу для работы с фискальным принтером общающемуся по RS232 (COM-порт). Для разработки выбрал Python с библиотекой pyserial. Так как язык знаю поверхностно, возникла накладка которую никак не могу победить.

В сеансе связи между компьютером и принтером возможна передача как одного байта, так и массива байт (строки). Судя по документации pyserial, функция write() пишет в порт byte или bytearray. Оформляю функцию следующим образом:
 def w_(*byte_arr):
    for byte in byte_arr:
        ser.write(bytes([byte]))
    r_()
 
def r_():
    time.sleep(0.05)
    while ser.inWaiting() > 0:
        ser.read(1)
 
w_(5)
w_(2,0,0,63,3,60)

Где ser - экземпляр класса Serial, инстанс com-порта; Функция r_() читает данные (я их обязан читать после каждого акта передачи). Когда так - все работает отлично, сниффер COM-порта фиксирует передачу и, что самое главное, ответ от устройства.

По техническому заданию необходимо передавать строку на печать. И здесь возникает затык. Формируя, согласно документации к принтеру строку, и передавая ее в функцию w_() я получаю ошибку на print(bytes()). Ниже привожу отрывок кода эмулирующий ошибку, готовый для исполнения:

 #!/usr/bin/env python3
import sys
import numpy as np
# function write data to port
def w_(*byte_arr):
    for byte in byte_arr:
        print(bytes([byte]))
def consctuctString(textIn):
    # create list with password (0x00, 0x00) and Start Print String byte (0x4C)
    textArray = [0x00, 0x00, 0x4C]
    # convert symbols to CP866 and insert into list
    for i in range(len(textIn)):
        textArray.append(ord(textIn[i].encode('cp866')))
    # add End Of Text (ETX) byte to end of list
    textArray.append(0x03)
    # calculate CRC (XOR all bytes of the string starts from password to ETX included)
    CRC = textArray[0]
    i = 1
    while i < len(textArray):
        CRC ^= textArray[i]
        i += 1
    # insert into start of list Start Of Text (STX) byte
    textArray.insert(0, 0x02)
    # insert into end of list calculated CRC
    textArray.append(CRC)
    print(textArray)
    w_(textArray)
consctuctString("test string")
Заранее извиняюсь за быдлокод. Тут происходит вот что: строку сначала переводим в кодировку CP866, создаем список и добавляем байт начала текста, пароль доступа к фискальной памяти, далее побайтово саму строку в CP866, в конце байт конца текста и CRC всего этого добра начиная с пароля и заканчивая байтом конца текста включительно.

На выходе получаю список вида
Функция печати (w_) его ест, но давится на print(bytes()): TypeError: ‘list’ object cannot be interpreted as an integer

Уважаемые знатоки, подскажите пожалуйста, как правильно передать (или сформировать список/массив) и что я собственно, делаю не так? Буду благодарен если ткнете в мануал по этой проблеме. Ибо сколько я не мучал SO вместе с гуглом, и сколько не менял эту функцию, результат один и тот же. Заранее спасибо!
izekia
убери звездочку в
 def w_(*byte_arr):

просто если дословно, то вместо переданного аргумента у тебя в byte_arr формируется кортеж с позиционными аргументами,
по сути получается что byte_arr == (textArray,)
соответственно далее byte == textArray, и на него и ругается конструктор bytes, когда обнаруживает вместо целого список
PooH
посмотри на модуль struct сильно поможет
Emmk
Проблема оказалась в использовании python 3. Во второй версии код работает адекатно. Всем спасибо за советы.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB