Управление Adruino через Python через pySerial

Здравствуйте и заранее спасибо за ваше время,

Я пытаюсь управлять серией реле, подключенных к моему Arduino, через скрипт Python, используя pySerial и Tkinter. Проблема в том, что, хотя я знаю, что мой код подключается к моему Arduino (я слышу то же трепетание реле, что и при загрузке кода с помощью программного обеспечения Arduino), я не могу заставить реле реагировать на команды, отправленные с моего устройства. Графический интерфейс Ткинтера. Вот мой код на питоне:

ser = Serial(port=3, timeout=1, writeTimeout=1, baudrate=9600)  # ensure non-blocking

class Application(Frame):

    print("Arduino Dish Control Ready")

    def __init__(self, parent):  # create constructor
        Frame.__init__(self, parent)  # define parent
        self.parent = parent  # save reference of parent widget
        self.initUI()  # delegate creation of the initUI() method

    def initUI(self):
        self.parent.title("Dish Control")  # title of window

        Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')

        self.columnconfigure(0, pad=4)
        self.columnconfigure(1, pad=4)
        self.columnconfigure(2, pad=4)
        self.columnconfigure(3, pad=4)
        self.columnconfigure(4, pad=4)

        self.rowconfigure(0, pad=3)
        self.rowconfigure(1, pad=3)
        self.rowconfigure(2, pad=3)
        self.rowconfigure(3, pad=3)

        def UP():  # define the UP command.
            ser.write(str(32))  # convert "32" to ASCII and send it via serial port (USB) to arduino.
            print ser.write(str(64))
            # sleep(0.1)
        up = Button(self, text="Up", command=UP)  # create button UP and set the command.
        up.grid(row=0, column=1)  # define position of UP button.


        self.pack()

А вот соответствующий код Arduino:

void loop(){
  if(Serial.available() > 0){
    Serial.begin(9600);
    int inByte = Serial.read(); //read the incoming data
    Serial.print("I received: ");
    Serial.println(inByte, DEC);

    if(Serial.read() == 32){//If the serial reads 32...
      digitalWrite(8, LOW); //Motor Select Low
      digitalWrite(9, LOW);
      digitalWrite(10, LOW); //Motor 1 Low
      digitalWrite(11, LOW);
      digitalWrite(12, LOW); // Motor 2 Low
      digitalWrite(13, LOW);
      digitalWrite(6, HIGH); //Motor Power High
      digitalWrite(7, HIGH);
    }
  }
}

Извините, что включил так много, но я не уверен, где моя ошибка.

РЕДАКТИРОВАТЬ: было запрошено, чтобы я включил трассировку для ошибки, указанной, когда я просто включаю ser.write(32) вместо ser.write(str(32)) в код Python:

Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__
    return self.func(*args)
  File "C:/Users/Radio Astro 4/PycharmProjects/untitled/DishControl.py", line 46, in UP
    ser.write(32)  # convert "1" to ASCII and send it via serial port (USB) to arduino.
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 283, in write
    data = to_bytes(data)
  File "C:\Python27\lib\site-packages\serial\serialutil.py", line 75, in to_bytes
    for item in seq:
TypeError: 'int' object is not iterable

person Matt    schedule 09.07.2015    source источник
comment
Разве вы не должны использовать ser, экземпляр класса вместо Serial в void_loop() Совсем не разбираетесь в последовательных портах, но Serial не знает, какой порт читать/записывать и т. д.   -  person    schedule 11.07.2015
comment
И если у вас есть ser.begin() в коде Python.   -  person    schedule 11.07.2015
comment
Я определил, какой порт Serial использовать, в первой строке приведенного выше кода. Отменяет ли определение его как ser эту информацию? Если да, то должен ли я каждый раз вводить полную строку? Кроме того, где я должен включить ser.begin()? При поиске похожих примеров, таких как этот: instructables.com/id/Interface-Python-and-Arduino-with-pySerial/ я не вижу, чтобы он использовался.   -  person Matt    schedule 13.07.2015
comment
Хорошо, я изучил ваше первое предложение, но мне все равно придется использовать что-то вроде этого: Serial.write(ser, 32), который работает так же, как ser.write(32), пока ser определен. Я не могу опустить ser из Serial.write(ser, 32), потому что здесь требуется ввод «IronSerial» И «данные».   -  person Matt    schedule 13.07.2015


Ответы (1)


В документации Arduino говорится о команде Serial.read():

Возвращает

первый байт доступных последовательных данных (или -1, если данных нет) - int

Вы отправляете микроконтроллеру строку 32, на самом деле это два отправляемых байта [51, 50]. При проверке if(Serial.read() == 32) вы проверяете значение байта 32, но значение байта 32 (пробел ASCII) никогда не отправляется.

Измените команду отправки, чтобы передать значение байта напрямую:

ser.write(32)  # without str()

Редактировать:

Serial.write() принимает (байтовую) строку в качестве аргумента, поэтому придется сделать следующее:

ser.write(bytes([32]))  # convert the list `[32]` to a bytestring
person Finwood    schedule 09.07.2015
comment
Извините, я должен был упомянуть, что это дает мне ошибку: TypeError: 'int' object is not iterable Есть ли другой обходной путь для этого, который мог бы работать? - person Matt; 09.07.2015
comment
В чем именно ваша ошибка и ваша трассировка? Включите это в свой основной вопрос, пожалуйста, трассировка неизбежна для решения вашей проблемы. - person Finwood; 09.07.2015
comment
Извините за задержку - меня не было в городе на выходные. Я обновил вопрос, чтобы включить трассировку. - person Matt; 13.07.2015
comment
@Matt: если это решило вашу проблему, отметьте ответ как принятый - person Finwood; 14.07.2015
comment
Это определенно помогло, но не совсем решило проблему. Как только я соберу все вместе, я опубликую сводку для всех, кто столкнется с этим вопросом, и приму ваш ответ! - person Matt; 16.07.2015