Уведомления

Группа в Telegram: @pythonsu

#1 Март 13, 2019 20:16:13

Peotr
Зарегистрирован: 2019-02-25
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Python. Как передавать по COM-порту числа?

Здравствуйте, знатоки!
Ну очень заинтересовал урок А.Б.Глазова:
https://www.youtube.com/watch?v=9-6NkEK72pM
Но я вместо связи двух ПК связал ПК с Ардуиной. От Ардуины всё принимается как положено. А вот от ПК (с питоновским скриптом) возникла следующая проблема. в строке:
ser.write(out_st)
(out_st - переменная, полный скрипт приведен ниже)
при передаче указывается ошибка, требуется преобразование передаваемого в байтовый тип:
"TypeError: unicode strings are not supported, please encode to bytes: ‘86’
('86' - это заданное число для передачи)
Нужно, наверное, так:
ser.write(b'out_st')
Но тогда передаётся не значение переменной out_st, а код самой переменной! Полный тупик.
Помогите.
Полный скрипт:
# coding: utf-8
import threading # – подключение модуля потоков
import time
import serial
from tkinter import *

# – Глобальные переменные
in_list = # – массив полученных строк
out_flag = 0 # – признаки занятости вывода и ввода

ser = serial.Serial('COM7', 9600, timeout=1)

# – функция приёма строки
def fn_in():
global in_list
while 1:
# – ждём прихода к нам строки
in_len = 0;
while in_len < 1:
in_st = ser.readline()
in_len = len(in_st)
# – ждём освобождения входного буфера и записываем в него
in_list.append(in_st)
time.sleep(1)

# == запустить поток приёма
tr_in = threading.Thread(target = fn_in)
tr_in.daemon = True
tr_in.start()

# ==запустить основной поток
def fn_out(): # – функция запроса на отправку
global out_flag
out_flag = 1

def fn_send(): # – функция отправки
out_st = ed.get()
#k = b'int(ed.get())'
k = b'int(out_st)'
#out_st = bytes(ed.get())
if len(out_st) > 0:
ser.write(out_st) #Первоначальный вариант! Выдаёт ошибку
#ser.write(b'out_st') выдаёт КОД переменной (НЕ ЗНАЧЕНИЕ!)
lb.insert(END, “>>>>> ”+out_st) #на рисунке верное значение!
ed.delete(0, END)

# == вывести строки в листбокс
def fn_disp():
global out_flag
#if out_flag: # – флаг запроса на передачу
#fn_send()
#out_flag = 0

if len(in_list) > 0:
st = in_list.pop(0) # – метод .pop удаляет эл-т после внесения в список
lb.insert(END, st) # – запись с конца уже записанного списка
if out_flag: # – флаг запроса на передачу
fn_send()
out_flag = 0
root.after(500,fn_disp) # – перезапуск ф-и fn_disp ч-з 100 мс

root = Tk()
lb = Listbox(root, width = 20, height = 25, font = ('Calibri', 16))
lb.pack()
ed = Entry(root, width = 12, font = ('Calibri', 16))
ed.pack()
bt = Button(root, text = “send”, width = 12, command = fn_out, font = ('Calibry', 16))
bt.pack()
root.after(10,fn_disp) # – через 10мс после запуска root будет запущена fn_disp
root.mainloop()

Спасибо за помощь.

P.S. Не нашёл, как вставить скрипт в окно, извините, пришлось просто скопировать.

Офлайн

#2 Март 13, 2019 20:40:38

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python. Как передавать по COM-порту числа?

 ser.write(out_st.encode())



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#3 Март 14, 2019 06:32:31

Peotr
Зарегистрирован: 2019-02-25
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Python. Как передавать по COM-порту числа?

PEHDOM

Как сказал незабвенный кот Матроскин: “Уррра, ЗАРАБОТАЛО!!!”
Огромное спасибо!

Офлайн

#4 Март 28, 2019 21:15:25

Peotr
Зарегистрирован: 2019-02-25
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Python. Как передавать по COM-порту числа?

А не поможете, уважаемый PEHDOM, ещё с одним моментом в этом же скрипте?
Для закрытия окна и одновременно порта Ардуины ввёл кнопку:

bt2 = Button(root, text = “quit”, width = 12, command = qquit, font = ('Calibry', 16))
bt2.pack()

def qquit(): #пытаюсь закрыть порт Arduino при выходе из программы
#global ser
if (ser):
ser.close()
root.destroy()

Работает, как нужно, но при этом выдаётся сообщение:

AttributeError: ‘NoneType’ object has no attribute ‘hEvent’

Похоже, “не правильно я этот бутерброд” состряпал. А проблема, видимо, связана с библиотекой, не могу справиться.

P.S. Кажется, можно и не добавлять кнопку, а использовать закрытие окна (“Х” в правом верхнем углу) с запросом подтверждения закрытия. Но до такого ещё не добрёл.

Спасибо.

Офлайн

#5 Март 29, 2019 10:09:27

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python. Как передавать по COM-порту числа?

Peotrя конечно не вижу всего кода и места где у вас вылазит ексепшин, но учитывая то что у вас функция приема запущена в отдельном потоке, то вполне вероятно что ругаеться у вас поток.

 def fn_in():
    global in_list
    while 1:
        in_len = 0;
        while in_len < 1:
            in_st = ser.readline()
            in_len = len(in_st)
           in_list.append(in_st)
        time.sleep(1)
не уверен что правильно поставил отступы, но смотрите, у вас в потоке бесконечный цикл, вы закрываете соединение ser.close() но при этом поток не останавливаете и поток продолжает опрашивать уже закрытый последовательный порт. С высокой долей вероятности можно предположить именно он и выдает ексепшин при обращении к несуществующему порту.
А возможно чтото еще, у вас там много чего нагорожено с отсрочкой… например root.after(500,fn_disp) который вызывает fn_send() которой пишет в порт, вы сначала закрываете порт, а потом уничтожаете root. Но за это время может сработать отложенный fn_send() который попытается чтото записать в уже закрытый порт.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Март 29, 2019 10:10:33)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version