I'm trying to make a Python function in the TCLab package to flash firmware to an Arduino Leonardo (32u4). I can compile the TCLab ino (firmware) and deploy with the Arduino IDE or with the Python avryp package. The Python avr_helpers package looks like a possible solution but is only supported with the older Python 2.7. Forum posts such as this one, how can I upload a hex file to an arduino uno?, and others suggest avrdude
to upload a hex file. However, I need a Python solution that can be used on any platform (MacOS, Windows, Linux, etc) without a requirement to install packages (avrdude, Arduino IDE, etc).
I have the hex file from a successful Arduino build. Here is an unsuccessful attempt to load the hex file with serial communication:
import serial
import time
import os
# open and close COM8 to activate bootloader
ser = serial.Serial('COM8',baudrate=1200)
print(ser.isOpen()); ser.close()
time.sleep(2)
# load hex file on COM9
filesize = os.path.getsize('tclab_v2.ino.hex')
fid = open('tclab_v2.ino.hex','rb')
offset = 0; MTU = 20
ser2 = serial.Serial('COM9',115200)
while (offset < filesize):
fid.seek(offset, 0)
ser2.write(fid.read(MTU))
offset = offset + MTU
ser2.close()
The script is able to activate the bootloader on another port and connect. If I transfer all at once with ser2.write(fid.read())
, it semi-bricks the Arduino and I recover it by hitting the reset button just before the Arduino IDE installs the firmware. I use a Maximum Transfer Unit (MTU) of 20 but I couldn't verify if there is one for the Leonardo. I can write a Python function to identify the ports and have used COM8
and COM9
here just to simply the test. Although the TCLab firmware is preloaded for Python, sometimes users change the firmware to use MATLAB, Octave, or Java and then want to switch back to Python. I'd like to make that as easy as possible without adding more steps or more instructions to the troubleshooting FAQ. Can I update the firmware like the MATLAB Arduino Support Package that detects a new device and transfers the firmware automatically with user confirmation?
ser2 = serial.Serial('COM9',9600)
but it has the same result.