Carglglz / upydev

Command line tool for MicroPython devices
https://pypi.org/project/upydev/
MIT License
57 stars 9 forks source link

upydev is stuck in serial transport with ESP32S3 #37

Closed ser closed 1 year ago

ser commented 1 year ago

upydev is getting stuck, how can i debug what's going wrong with it? I read all docs but there is no hint how to turn on a more verbose mode.

Carglglz commented 1 year ago

upydev is getting stuck, how can i debug what's going wrong with it?

which command and which device type? this https://upydev.readthedocs.io/en/latest/howto.html#debug may be of help.

If it is a serial device it may be related to this https://github.com/pyserial/pyserial/issues/124

ser commented 1 year ago

Hello it's a serial device indeed.

What I'm trying to do is to establish encrypted connection via websockets, but it I'm unable to prepare it.

upydev update_upyutils

gets stuck during copying - but I overcame it using mpremote -r and required files got copied into the device.

Question is: why mpremote works correctly and upydev not? :-)

Carglglz commented 1 year ago

@ser

Question is: why mpremote works correctly and upydev not? :-)

There was a fix at mpremote this year, the one mentioned at https://github.com/pyserial/pyserial/issues/124, I've updated https://github.com/Carglglz/upydevice (the backend library) with the fix 👍🏼 .

After some testing it looks it's device/board/USB-UART chip dependant and it is related to DTR, RTS signals while opening the serial port. The device in which I had experienced such behaviour, works now with this fix, BUT it will reset after connecting. I've tested the upydev update_upyutils command and it worked, so install the latest upydevice with

 pip install https://github.com/Carglglz/upydevice/archive/develop.zip

And let me know if that fixes it 👍🏼

ser commented 1 year ago
$ pipx install https://github.com/Carglglz/upydevice/archive/develop.zip --include-deps
⚠️  Note: pyserial-miniterm was already on your PATH at /usr/bin/pyserial-miniterm
⚠️  Note: pyserial-ports was already on your PATH at /usr/bin/pyserial-ports
⚠️  Note: get_objgraph was already on your PATH at /usr/bin/get_objgraph
⚠️  Note: undill was already on your PATH at /usr/bin/undill
  installed package upydevice 0.3.9, installed using Python 3.11.4
  These apps are now globally available
    - get_gprof
    - get_objgraph
    - pyserial-miniterm
    - pyserial-ports
    - undill
done! ✨ 🌟 ✨
$ upydev update_upyutils
Uploading files to ./lib ...
/home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py -> upydevice:/lib/wss_helper.py

/home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py  [2.06 kB]
▏████████████████████████████████████████████████████████████████▉

and stuck

ser commented 1 year ago

BTW, if we are here, docs seem to be outdated:

$ upydev kg ssl CA -tfkey
usage:  kg [-h] -t T -p P [-wss] [-zt] [-rst] [-key_size KEY_SIZE] [-show_key] [-tfkey] [-rkey] [-g] [-to TO] [-f [F ...]] [-a] [mode] [dest] [subcmd]
 kg: error: the following arguments are required: -p/--p

it works:

$ upydev kg -p upydevice ssl CA -tfkey
Generating CA SSL ECDSA key, cert
Generating ROOT CA key/cert chain...
ID HOST: 736572
Passphrase: 
ROOT CA ECDSA key & certificate generated.

https://upydev.readthedocs.io/en/latest/sslwebshellrepl.html

ser commented 1 year ago

And if we are here, IMHO the current location of keys is unfortunate, why do not utilise usual ~/.config/upydev/ directory instead of?

Carglglz commented 1 year ago
$ pipx install https://github.com/Carglglz/upydevice/archive/develop.zip --include-deps
⚠️  Note: pyserial-miniterm was already on your PATH at /usr/bin/pyserial-miniterm
⚠️  Note: pyserial-ports was already on your PATH at /usr/bin/pyserial-ports
⚠️  Note: get_objgraph was already on your PATH at /usr/bin/get_objgraph
⚠️  Note: undill was already on your PATH at /usr/bin/undill
  installed package upydevice 0.3.9, installed using Python 3.11.4
  These apps are now globally available
    - get_gprof
    - get_objgraph
    - pyserial-miniterm
    - pyserial-ports
    - undill
done! ✨ 🌟 ✨
$ upydev update_upyutils
Uploading files to ./lib ...
/home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py -> upydevice:/lib/wss_helper.py

/home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py  [2.06 kB]
▏████████████████████████████████████████████████████████████████▉

and stuck

Weird, is it an esp32 ?, what is in main.py and can you test put command instead?

$ upydev put /home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/*.py -dir lib

BTW, if we are here, docs seem to be outdated: $ upydev kg ssl CA -tfkey usage: kg [-h] -t T -p P [-wss] [-zt] [-rst] [-key_size KEY_SIZE] [-show_key] [-tfkey] [-rkey] [-g] [-to TO] [-f [F ...]] [-a] [mode] [dest] [subcmd] kg: error: the following arguments are required: -p/--p

I'm aware of this, unfortunately I've developed upydev with python3.7 and python3.8+ introduced a bug/breaking change in argparse with allow_abrev=False, that makes having .e.g. -t and -tfkey in the same command impossible, (it will be parsed as args.t = "fkey". I've been slowly fixing these errors in the develop branch, but there are quite a lot command line options...😪so thanks for the report. BTW upydev kg ssl CA should work as expected, and it will ask if you want to upload the certificate to the device (at least in develop branch, I do not remember now when exactly added this)

And if we are here, IMHO the current location of keys is unfortunate, why do not utilise usual ~/.config/upydev/ directory instead of?

I agree and it is in my TODO list for the next version, (which I don't know when it will be released, since I'm being sidetracked by this project asyncmd at the moment).

ser commented 1 year ago

it is Seeed Studio XIAO ESP32S3: https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html

I find this board flawless apart of upydev.

upydev put /home/ser/.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/*.py -dir lib
Uploading files @ upydevice:/lib 

- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py [0.43 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py [3.66 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/shasum.py [5.83 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/sync_tool.py [3.96 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/time_it.py [0.52 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/uping.py [8.38 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/uptime.py [1.48 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/upylog.py [6.41 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/upynotify.py [2.83 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/upysecrets.py [3.81 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/upysh.py [10.00 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/upysh2.py [7.40 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py [2.06 kB]
- ./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py [4.37 kB]
./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py -> upydevice:lib/cycles.py

./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py [0.43 kB]
▏████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ \  100 % | 0.43/0.43 kB |  4.85 kB/s | 00:00/00:00 s

./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py -> upydevice:lib/nanoglob.py

./.local/pipx/venvs/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py [3.66 kB]
▏█████████

... and stuck.

asyncmd

awesome project, thanks - i was not aware of it - i will be using it :)

Carglglz commented 1 year ago

I think I've just figured it out and it is probably stuck in the RAW REPL mode, waiting to read until some specific bytes. I've updated it with the same method that mpremote is using, so let's see if that works. (install from develop branch)

it is Seeed Studio XIAO ESP32S3

Sadly I do not have any ESP32S3 to test and debug it myself :(.

If the fix does not work you may be want to try to change device cpu frequency with machine.freq(240000000) and see if that helps.

Also as a fallback I may add again the previous method that used the normal REPL and I guess it would be more reliable and easy to debug (although a bit slower...).

awesome project, thanks - i was not aware of it - i will be using it :)

Thanks! :) , just be aware that the asyncio + SSL stuff is still pending review in a micropython PR, and you will need this branch to make it work : https://github.com/Carglglz/micropython/tree/asyncio-tls

ser commented 1 year ago

Nothing helped, the same stuck, unfortunately :( I can't help more as I do not fully understand how does serial connection work :(

I checked again mpreremote and it still works well:

$ mpremote a1 fs -r cp lib :
cp lib/wss_repl.py :lib/
cp lib/wss_helper.py :lib/              
cp lib/upysh2.py :lib/                  
cp lib/upysh.py :lib/                   
cp lib/upysecrets.py :lib/              
cp lib/upynotify.py :lib/               
cp lib/upylog.py :lib/                  
cp lib/uptime.py :lib/                  
cp lib/uping.py :lib/
cp lib/time_it.py :lib/                 
cp lib/sync_tool.py :lib/
cp lib/shasum.py :lib/                  
cp lib/nanoglob.py :lib/                
cp lib/cycles.py :lib/
ser commented 1 year ago
  1. another thing, upydev hangs on upydev scan -sr

  2. IMHO global config should also be stored in ~/.config/upydev/ dir.

  3. I forgot to answer your previous question: main.py and boot.py are empty.

Carglglz commented 1 year ago
  1. another thing, upydev hangs on upydev scan -sr

Yes I'm aware of it, and it's fixed by 2260028a84381d156fd8dd4806e0c62c89c4d494 in the develop branch.

IMHO global config should also be stored in ~/.config/upydev/ dir.

I agree, I've already put some config/cache files in ~/ and I will move config and key/certs there 👍🏼.

Nothing helped, the same stuck, unfortunately :( I can't help more as I do not fully understand how does serial connection work :(

https://github.com/Carglglz/upydev/blob/cd9941aa5d4238d61b550b80f73e33ed6239610c/upydev/shell/common.py#L650

    def enter_raw_repl(self):
        self.dev.serial.write(b"\r\x01")
        data = self.dev.serial.read_until(b"raw REPL; CTRL-B to exit\r\n")
        assert data.endswith(b"raw REPL; CTRL-B to exit\r\n"), f"wrong data: {data}"

    def exit_raw_repl(self):
        self.dev.serial.write(b"\r\x02")  # ctrl-B: enter friendly REPL
        self.dev.serial.read_until(b"\r\n>>> ")

    # adapted from micropython serial transport.
    def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None):
        # if data_consumer is used then data is not accumulated and the ending must be 1 byte long
        assert data_consumer is None or len(ending) == 1

        data = self.dev.serial.read(min_num_bytes)
        if data_consumer:
            data_consumer(data)
        timeout_count = 0
        while True:
            if data.endswith(ending):
                break
            elif self.dev.serial.inWaiting() > 0:
                new_data = self.dev.serial.read(1)
                if data_consumer:
                    data_consumer(new_data)
                    data = new_data
                else:
                    data = data + new_data
                timeout_count = 0
            else:
                timeout_count += 1
                if timeout is not None and timeout_count >= 100 * timeout:
                    break
                time.sleep(0.01)
        return data

    def exec_raw_cmd(self, command):
        # check we have a prompt
        if not isinstance(command, bytes):
            command = command.encode("utf-8")
        command += b"\r"
        data = self.read_until(1, b">")
        assert data.endswith(b">"), f"wrong data: {data}"
        for i in range(0, len(command), 256):
            self.dev.serial.write(command[i : min(i + 256, len(command))])
            time.sleep(0.01)
        self.dev.serial.write(b"\x04")
        # check if we could exec command
        data = self.read_until(2, b"OK")
        assert b"OK" in data, f"Command failed: {command}: data: {data}"
        data = self.read_until(2, b"\x04\x04")
        assert data == b"\x04\x04", f"Command failed: {command}: data: {data}"

    def init_put(self, filename, filesize, cnt=0):
        self.file_buff = b""
        self.filesize = filesize
        self.filename = filename
        self.cnt = cnt
        self.get_pb()
        self.t_start = time.time()

    def sraw_put_file(self, src, dest, chunk_size=256):
        try:
            self.enter_raw_repl()
            # time.sleep(0.1)
            # print(f"source: {src}")
            # print(f"dest: {dest}")
            self.exec_raw_cmd(f"f=open('{dest}','wb')\nw=f.write")
            if self.filesize == 0:
                self.exec_raw_cmd("f.close()")
                self.exit_raw_repl()
                print("\n")
                return
            # time.sleep(0.1)
            with open(src, "rb") as f:
                while True:
                    data = f.read(chunk_size)
                    if not data:
                        break

                    self.exec_raw_cmd("w(" + repr(data) + ")")
                    self.cnt += len(data)
                    self.file_buff += data
                    loop_index_f = (self.cnt / self.filesize) * self.bar_size
                    loop_index = int(loop_index_f)
                    loop_index_l = int(round(loop_index_f - loop_index, 1) * 6)
                    nb_of_total = f"{self.cnt/(1000):.2f}/{self.filesize/(1000):.2f} kB"
                    percentage = self.cnt / self.filesize
                    self.percentage = int((percentage) * 100)
                    t_elapsed = time.time() - self.t_start
                    t_speed = f"{(self.cnt/(1000))/t_elapsed:^2.2f}"
                    ett = self.filesize / (self.cnt / t_elapsed)
                    if self.pb:
                        self.do_pg_bar(
                            loop_index,
                            self.wheel,
                            nb_of_total,
                            t_speed,
                            t_elapsed,
                            loop_index_l,
                            percentage,
                            ett,
                        )

            self.exec_raw_cmd("f.close()")
            self.exit_raw_repl()
            print("\n")
        except (Exception, KeyboardInterrupt):
            print("flushing serial")
            self.exit_raw_repl()
            self.dev.flush_conn()
            time.sleep(0.5)
            self.dev.serial.write(self.dev._banner)
            self.dev.serial.read_until(b"\r\n>>> ")
            raise Exception

It just enters the raw REPL and writes the file in chunks (256 bytes) with self.exec_raw_cmd("w(" + repr(data) + ")")

You can compare it with https://github.com/micropython/micropython/blob/master/tools/mpremote/mpremote/transport_serial.py methods.

If you see any significant difference, maybe I'm missing some time.sleep or bytes?

Also with the latest develop branch it should fail instead of getting stuck in the middle of the file transfer (see read_until method).

Did you install the latest develop version with pip install --force-reinstall https://github.com/Carglglz/upydev/archive/develop.zip? You also may want to clone the repo, checkout develop branch and install it, i.e.

$ git clone https://github.com/Carglglz/upydev.git && cd upydev && git checkout develop && pip install .

ser commented 1 year ago

to be absolutely sure i have installed a new venv and then:

$ source /home/ser/upydev/upydev/bin/activate
pip install https://github.com/Carglglz/upydevice/archive/develop.zip
pip install https://github.com/Carglglz/upydev/archive/develop.zip

and...

$ /home/ser/upydev/upydev/bin/upydev update_upyutils
Uploading files to ./lib ...
/home/ser/upydev/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py -> upydevice:/lib/wss_repl.py

/home/ser/upydev/upydev/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py  [4.37 kB]
▏███████████████████████▏                                                                                                            ▏ \   17 % | 0.77/4.37 kB |  0.95 kB/s | 00:00/00:04 s

...stuck.

Carglglz commented 1 year ago

OK, my bad I've just realised I was not using the same method for put and update_upyutils commands, now they use the same method, and also I think I was missing the serial timeout, now I think it's fixed. Install again from develop branch and let me know.

It should look like this now:

upydev update_upyutils -@ gkble
Making ./lib directory ...
Done!
Uploading files to ./lib ...
Uploading files @ gkble:/lib

- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh.py [10.07 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upylog.py [6.41 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py [4.37 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uping.py [8.38 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/shasum.py [5.83 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py [2.06 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py [0.43 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh2.py [7.40 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py [3.66 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysecrets.py [3.81 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upynotify.py [2.83 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uptime.py [1.48 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/time_it.py [0.52 kB]
- /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/sync_tool.py [3.96 kB]
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh.py -> gkble:lib/upysh.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh.py [10.07 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 10.07/10.07 kB |  6.47 kB/s | 00:01/00:01 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upylog.py -> gkble:lib/upylog.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upylog.py [6.41 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 6.41/6.41 kB |  6.54 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py -> gkble:lib/wss_repl.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_repl.py [4.37 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 4.37/4.37 kB |  6.09 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uping.py -> gkble:lib/uping.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uping.py [8.38 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 8.38/8.38 kB |  6.59 kB/s | 00:01/00:01 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/shasum.py -> gkble:lib/shasum.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/shasum.py [5.83 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 5.83/5.83 kB |  6.65 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py -> gkble:lib/wss_helper.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/wss_helper.py [2.06 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 2.06/2.06 kB |  5.76 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py -> gkble:lib/cycles.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/cycles.py [0.43 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 0.43/0.43 kB |  3.32 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh2.py -> gkble:lib/upysh2.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysh2.py [7.40 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 7.40/7.40 kB |  6.61 kB/s | 00:01/00:01 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py -> gkble:lib/nanoglob.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/nanoglob.py [3.66 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 3.66/3.66 kB |  6.66 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysecrets.py -> gkble:lib/upysecrets.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upysecrets.py [3.81 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 3.81/3.81 kB |  6.51 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upynotify.py -> gkble:lib/upynotify.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/upynotify.py [2.83 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 2.83/2.83 kB |  6.19 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uptime.py -> gkble:lib/uptime.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/uptime.py [1.48 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 1.48/1.48 kB |  5.76 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/time_it.py -> gkble:lib/time_it.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/time_it.py [0.52 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 0.52/0.52 kB |  3.29 kB/s | 00:00/00:00 s

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/sync_tool.py -> gkble:lib/sync_tool.py

/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/upydev/upyutils_dir/sync_tool.py [3.96 kB]
▏███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ -  100 % | 3.96/3.96 kB |  6.62 kB/s | 00:00/00:00 s

Thanks for taking the time, too bad I don't have an esp32s3 yet so I could debug this myself...I may be able to get one soon 🤔

ser commented 1 year ago

YES! It works now! Thank you very much!

I definitely recommend these boards, they are super-tiny, useful when size matters. STL files are available to print a case. I've just ordered another pack of 5 on Aliexpress as Seeed has them out of stock. Aliexpress price is $6.93.