-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Behaviour when no ESP device connected using esptool as a module (ESPTOOL-980) #1044
Comments
Hi @mbastida123, the esptool as python package can be used with context manager. We recently added the section into the documentation, so you can take a look here. It should ensure that port is properly closed afterwards. Hope it helps. |
I'm closing this for inactivity |
Hi, @dobairoland didn't respond until today because I was on holiday :) @Dzarda7 thanks for the resource. However, it still doesn't work for me. The first time the script will correctly timeout on "Connecting......" trying to find a device. However, on the next loop it will be unable to connect to the ESP-PROG via serial. I suspect because the port is left open. |
Can you please share a complete example we can try? We will reopen this if we can reproduce an issue. |
Here I go: I have attached the This is what you should see:
|
Hi @mbastida123, this is intentional. esptool raises exception if it cannot connected to the device. Your port is still present as you use ESP-PROG, but no device is connected, so the esptool opens the port and tries to connect. If this is not successful, it raises the exception with error. You need to handle the exception by yourself and decide what to do with it. The exception you get is following if I am not mistaken:
The simplest solution for that behavior is this: from esptool.cmds import detect_chip
import time
# The port of the connected ESP
PORT = "/dev/ttyACM0"
# The binary file
BIN_FILE = "./firmware.bin"
# Flash offset to flash the binary to
FLASH_ADDRESS = 0x10000
def progress_callback(percent):
print(f"Wrote: {int(percent)}%")
while True:
try:
print("Detecting ESP...")
with detect_chip(PORT) as esp:
description = esp.get_chip_description()
features = esp.get_chip_features()
print(f"Detected ESP on port {PORT}: {description}")
print(f"Features: {", ".join(features)}")
esp = esp.run_stub()
with open(BIN_FILE, 'rb') as binary:
# Load the binary
binary_data = binary.read()
total_size = len(binary_data)
print(f"Binary size: {total_size} bytes")
# Write binary blocks
esp.flash_begin(total_size, FLASH_ADDRESS)
for i in range(0, total_size, esp.FLASH_WRITE_SIZE):
block = binary_data[i:i + esp.FLASH_WRITE_SIZE]
# Pad the last block
block = block + bytes([0xFF]) * (esp.FLASH_WRITE_SIZE - len(block))
esp.flash_block(block, i + FLASH_ADDRESS)
progress_callback(float(i + len(block)) / total_size * 100)
esp.flash_finish()
# Reset the chip out of bootloader mode
esp.hard_reset()
except Exception as e:
print(f"Error: {e}")
time.sleep(1) Sorry for inconvenience, esptool was not meant to be used as a module in the first place so some things are not as easy as it should be, but we plan to change it esptool 5.0. |
I supose you wrote the response before I uploaded my example. Anyway, you are correct. And I do catch the exception. The problem is that even after catching the exception it is impossible to connect to the ESP-PROG via serial. See the log output in my previous message. The first time it works as expected, raising an excepction that I capture as |
Yes, sorry, I missed that. You are right, this does not work correctly, I will try to look at it as soon as possible. |
@mbastida123 the issue was fixed in this commit, you can try it. You just need to use master branch as a release will be done later. Thanks for reporting this. |
Thanks for the quick fix! It it working. However, is it possible that the function |
You cannot use it like this unfortunately. You cannot use |
@Dzarda7 just a heads up since I used your example from here: I think you have an error here: It should be To prevent the padding of the last block to produce a progress percentage above 100% You could even replace |
Thanks for noticing this. This serves just as a demonstration, so it is not a big issue. If you are willing to, you can open pull request, it can be fixed here. |
Operating System
Debian GNU/Linux 12 (bookworm)
Esptool Version
esptool==4.8.1
Python Version
Python 3.11.2
Full Esptool Command Line that Was Run
No response
Esptool Output
I'm making a script on python to program some ESP devices via a GUI.
The line:
Correctly returns an instance if the ESP device is connected.
However, if there is no ESP device attached to the ESP-PROG the function timeouts and raises
FatalError
.This is totally expected behaviour.
The problem is that when this happens the serial port is not correctly closed and so if
get_default_connected_device()
is placed inside a loop the following calls to said function will never work. Even if you connect an ESP device./dev/ttyUSB1 failed to connect: Could not open /dev/ttyUSB1, the port is busy or doesn't exist.
I have tried numerous ways to manually close the port. But the serial instance is not available to me.
Is this an issue or am I doing something wrong?
The text was updated successfully, but these errors were encountered: