scientifichackers / ampy

MicroPython Tool - Utility to interact with a MicroPython board over a serial connection.
MIT License
718 stars 156 forks source link

ampy can't open Windows COM port numbers above 10 #6

Open carterw opened 7 years ago

carterw commented 7 years ago

I have multiple USB hubs on my Windows PC and a fair number of USB devices. For some reason Python needs to see Windows port names with numbers above 10 in a non-obvious format or they will not be opened. For example, COM24 needs to be depicted as \.\COM24 or the open attempt will fail. The ampy utility doesn't take this into account, and it would not open the USB port my esp8266 is attached to.

I did a little looking around and found a function that can return a correctly formatted COM name;

import re import serial

def full_port_name(portname): """ Given a port-name (of the form COM7, COM12, CNCA0, etc.) returns a full name suitable for opening with the Serial class. """ m = re.match('^COM(\d+)$', portname) if m and int(m.group(1)) > 10: portname = '\\.\' + portname return portname

pn = full_port_name('COM24') print pn

So I put that in cli.py and modified the cli() function as follows;

`def cli(port, baud): """ampy - Adafruit MicroPython Tool

Ampy is a tool to control MicroPython boards over a serial connection.  Using
ampy you can manipulate files on the board's internal filesystem and even run
scripts.
"""
global _board
pn = full_port_name(port)
#print(pn)
#_board = pyboard.Pyboard(port, baudrate=baud)
_board = pyboard.Pyboard(pn, baudrate=baud)`
tdicola commented 7 years ago

Ah thanks for digging into it further, yeah that's annoying that Windows seems to treat COM ports above 9 so differently with path names. I just added a similar workaround function to the latest 1.0 version of ampy, and it should be up on PyPi in ~10 minutes too. I haven't fully tested it yet since I don't have a COM10 device handy, can you install the latest ampy and see if it repros? You can force an update with:

pip install adafruit-ampy --upgrade

Thanks again and apologies it took a while to look at this issue!

mightylastingcode commented 5 years ago

Hi tdicola,

I am still having the same trouble with ampy. I have version 1.07. Can you help.

1) Install ampy C:\Users\mikel>pip install adafruit-ampy Collecting adafruit-ampy Downloading https://files.pythonhosted.org/packages/59/99/f8635577c9a11962ec43714b3fc3d4583070e8f292789b4683979c4abfec/adafruit_ampy-1.0.7-py2.py3-none-any.whl Requirement already satisfied: pyserial in c:\users\mikel\anaconda3\lib\site-packages (from adafruit-ampy) (3.4) Requirement already satisfied: click in c:\users\mikel\anaconda3\lib\site-packages (from adafruit-ampy) (6.7) Collecting python-dotenv (from adafruit-ampy) Downloading https://files.pythonhosted.org/packages/8c/14/501508b016e7b1ad0eb91bba581e66ad9bfc7c66fcacbb580eaf9bc38458/python_dotenv-0.10.1-py2.py3-none-any.whl distributed 1.21.8 requires msgpack, which is not installed. Installing collected packages: python-dotenv, adafruit-ampy Successfully installed adafruit-ampy-1.0.7 python-dotenv-0.10.1 You are using pip version 10.0.1, however version 19.0.3 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command.

2) Do the upgrade C:\Users\mikel>pip install adafruit-ampy --upgrade Requirement already up-to-date: adafruit-ampy in c:\users\mikel\anaconda3\lib\site-packages (1.0.7) Requirement not upgraded as not directly required: python-dotenv in c:\users\mikel\anaconda3\lib\site-packages (from adafruit-ampy) (0.10.1) Requirement not upgraded as not directly required: click in c:\users\mikel\anaconda3\lib\site-packages (from adafruit-ampy) (6.7) Requirement not upgraded as not directly required: pyserial in c:\users\mikel\anaconda3\lib\site-packages (from adafruit-ampy) (3.4) You are using pip version 10.0.1, however version 19.0.3 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command.

3) run it

C:\Users\mikel>ampy --port COM16 put main.py Traceback (most recent call last): File "c:\users\mikel\anaconda3\lib\runpy.py", line 193, in _run_module_as_main "main", mod_spec) File "c:\users\mikel\anaconda3\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Users\mikel\Anaconda3\Scripts\ampy.exe__main.py", line 9, in File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 722, in call__ return self.main(args, kwargs) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 697, in main rv = self.invoke(ctx) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 1063, in invoke Command.invoke(self, ctx) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 895, in invoke return ctx.invoke(self.callback, ctx.params) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 535, in invoke return callback(args, **kwargs) File "c:\users\mikel\anaconda3\lib\site-packages\ampy\cli.py", line 99, in cli _board = pyboard.Pyboard(port, baudrate=baud, rawdelay=delay) File "c:\users\mikel\anaconda3\lib\site-packages\ampy\pyboard.py", line 147, in init raise PyboardError('failed to access ' + device) ampy.pyboard.PyboardError: failed to access \.\COM16

mightylastingcode commented 5 years ago

I saw the code you have implemented.

def windows_full_port_name(portname):

Helper function to generate proper Windows COM port paths. Apparently

# Windows requires COM ports above 9 to have a special path, where ports below
# 9 are just referred to by COM1, COM2, etc. (wacky!)  See this post for
# more info and where this code came from:
# http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
m = re.match("^COM(\d+)$", portname)
if m and int(m.group(1)) < 10:
    return portname
else:
    return "\\\\.\\{0}".format(portname)

The format seems to be correct. Maybe this is a problem when my Putty is also connected to the device So, I killed Putty. I tried to run the command again. This time it get a different error that Ampy cannot enter the raw repl.

C:\Users\mikel>ampy --port COM16 put main.py b'NLR jump failed, val=0x3ffb25ec\r\nets Jun 8 2016 00:22:57\r\n\r\nrst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)\r\nconfigsip: 0, SPIWP:0xee\r\nclk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00\r\nmode:DIO, clock div:2\r\nload:0x3fff0018,len:4\r\nload:0x3fff001c,len:5060\r\nload:0x40078000,len:8788\r\nho 0 tail 12 room 4\r\nload:0x40080400,len:6772\r\nentry 0x40081610\r\n\x1b[0;32mI (260) cpu_start: Pro cpu up.\x1b[0m\r\n\x1b[0;32mI (260) cpu_start: Application information:\x1b[0m\r\n\x1b[0;32mI (260) cpu_start: Compile time: 12:41:59\x1b[0m\r\n\x1b[0;32mI (262) cpu_start: Compile date: Mar 1 2019\x1b[0m\r\n\x1b[0;32mI (267) cpu_start: ESP-IDF: v3.3-beta1-268-g5c88c5996\x1b[0m\r\n\x1b[0;32mI (274) cpu_start: Single core mode\x1b[0m\r\n\x1b[0;32mI (278) heap_init: Initializing. RAM available for dynamic allocation:\x1b[0m\r\n\x1b[0;32mI (285) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM\x1b[0m\r\n\x1b[0;32mI (291) heap_init: At 3FFB92B0 len 00026D50 (155 KiB): DRAM\x1b[0m\r\n\x1b[0;32mI (298) heap_init: At 3FFE0440 len 0001FBC0 (126 KiB): D/IRAM\x1b[0m\r\n\x1b[0;32mI (304) heap_init: At 40078000 len 00008000 (32 KiB): IRAM\x1b[0m\r\n\x1b[0;32mI (310) heap_init: At 40092834 len 0000D7CC (53 KiB): IRAM\x1b[0m\r\n\x1b[0;32mI (316) cpu_start: Pro cpu start user code\x1b[0m\r\n\x1b[0;32mI (36) cpu_start: Starting scheduler on PRO CPU.\x1b[0m\r\n' Traceback (most recent call last): File "c:\users\mikel\anaconda3\lib\runpy.py", line 193, in _run_module_as_main "main", mod_spec) File "c:\users\mikel\anaconda3\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Users\mikel\Anaconda3\Scripts\ampy.exe__main.py", line 9, in File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 722, in call__ return self.main(args, kwargs) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 697, in main rv = self.invoke(ctx) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 1066, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 895, in invoke return ctx.invoke(self.callback, ctx.params) File "c:\users\mikel\anaconda3\lib\site-packages\click\core.py", line 535, in invoke return callback(args, **kwargs) File "c:\users\mikel\anaconda3\lib\site-packages\ampy\cli.py", line 263, in put board_files.put(remote, infile.read()) File "c:\users\mikel\anaconda3\lib\site-packages\ampy\files.py", line 208, in put self._pyboard.enter_raw_repl() File "c:\users\mikel\anaconda3\lib\site-packages\ampy\pyboard.py", line 198, in enter_raw_repl raise PyboardError('could not enter raw repl') ampy.pyboard.PyboardError: could not enter raw repl

mightylastingcode commented 5 years ago

Ampy was able to flash the device with my main.py one time today. For that time, it did not generate any error. The main.py program runs good because it prints the message. Since then, I cannot duplicate the same success again.

I am going to reboot my PC and see if it helps.

mightylastingcode commented 5 years ago

Same error "could not enter raw repl.'

mightylastingcode commented 5 years ago

I have found the solution in this recent post. https://github.com/dhylands/rshell/issues/27 The solution works consistently. I was confused with COM1x issue. It turns out to be the reset problem.

--------------------------------------hyper99 commented on Oct 4, 2018------------------------------------- The simplified below code can reset ESP board when connecting, and no need hardware reset when reconnecting to ESP board on ESP8266 and ESP32 board. in init() of class pyboard.py file. self.serial = serial.Serial(device, baudrate=baudrate, interCharTimeout=1)

--------added below--------------------

self.serial.setRTS(1) #EN=LOW time.sleep(0.01) self.serial.setRTS(0) #EN=HIGH

------ added to here--------

break