pythoncmdarduinoavrdude

Python read cmd AVRDUDE to update arduino


I have created a GUI in python using Tkinter which connects to an Arduino nano. I can use my GUI to flash the firmware on the Arduino using AVRDUDE with no issue but this pops up a CMD box while programming. What I want is to redirect or pipe that to a text box to my GUI instead. If I use normal windows command like ping, dir etc, this works with no issue (example code and screenshot below) but when I try and flash the Arduino, it does flash but still in its own console and does not redirect. I'm guessing the AVRDUDE printf that's the issue but is there a way to redirect the output?

I have also tried adding "2> e:\\output.txt" to the end like in this link https://learn.sparkfun.com/tutorials/raspberry-pi-stand-alone-programmer/parsing-output-from-avrdude-w-python to save to a file then I can read in the file. If I do that in CMD, it works but not if I try from python, I get

Bad parameter >2

even if I try >> test.txt.

import tkinter as tk
import subprocess, sys

main = tk.Tk()

IP = "ping 192.168.0.1"
date = ["cmd", "/C","date", "/T"]

arduino = ["W:\\Python\\Hopper_Tester\\update\\avrdude", "-CW:\\Python\Hopper_Tester\\update\\avrdude.conf", "-patmega328p", "-carduino", "-PCOM7", "-b115200", "-D", "-Uflash:w:C:\\Users\Frazer Telford\\Documents\\PlatformIO\\Projects\\hopper_test\\.pio\\build\\nanoatmega328\\firmware.hex:i", "2>", "e:\\flash.txt"]


RUN = IP

textbox = tk.Text(main)
textbox.pack()

def command_one():

    #item = subprocess.Popen(RUN,stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
    item = subprocess.Popen(RUN,stdout=subprocess.PIPE)
    #item.communicate()[0]

    # print(f"printing {item}")

    for line in item.stdout:
        output = (line.decode())
        textbox.insert(tk.END,output)
        textbox.see(tk.END)
        main.update_idletasks()

def command_two():
    result = subprocess.run(RUN, stdout=subprocess.PIPE, text = True)

    for line in result.stdout:
        #output = (line.decode())
        textbox.insert(tk.END,line)
        textbox.see(tk.END)
        main.update_idletasks()


tk.Button(main, text = "Function 1", command = command_one).pack(side=tk.LEFT, padx = 10)
tk.Button(main, text = "Function 2", command = command_two).pack(side=tk.LEFT, padx = 10)




main.mainloop()

enter image description here


Solution

  • After spending some hours on it I have found a fix that works if someone has a better way I would appreciate your response.

    def command_one():
    item = subprocess.Popen(RUN,stderr=subprocess.PIPE)
    
    
    for line in item.stderr:
        #output = (line.decode())
        textbox.insert(tk.END,line)
        main.update_idletasks()
    
    textbox.see(tk.END)
    

    My mistake was looking at stdout where I should be looking at stderr, not sure why but I get the output I need.

    enter image description here