Контролиране на Adruino чрез Python чрез pySerial

Здравейте и благодаря предварително за отделеното време,

Опитвам се да контролирам поредица от релета, свързани с моя Arduino чрез скрипт на python, използвайки pySerial и Tkinter. Проблемът е, че въпреки че знам, че кодът ми се свързва с моето Arduino (чувам същото трептене на релета, което получавам, когато качвам код с помощта на софтуера Arduino), не мога да накарам релетата да отговорят на команди, изпратени от моя Tkinter GUI. Ето моят код на python:

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
Определих кой сериен порт да се използва в първия ред на горния код. Определянето му като сервизен ли е тази информация? Ако е така, трябва ли да въвеждам целия ред всеки път? Освен това къде трябва да включа 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“ И „data“.   -  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