Форум сайта python.su
Здравствуйте, знатоки!
Ну очень заинтересовал урок А.Б.Глазова:
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. Не нашёл, как вставить скрипт в окно, извините, пришлось просто скопировать.
Офлайн
ser.write(out_st.encode())
[code python][/code]
Офлайн
PEHDOM
Офлайн
А не поможете, уважаемый 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. Кажется, можно и не добавлять кнопку, а использовать закрытие окна (“Х” в правом верхнем углу) с запросом подтверждения закрытия. Но до такого ещё не добрёл.
Спасибо.
Офлайн
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)
[code python][/code]
Отредактировано PEHDOM (Март 29, 2019 10:10:33)
Офлайн