![]() |
Forum Index : Microcontroller and PC projects : A file synchronisation tool for PicoMites
Author | Message | ||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi all, I wrote a file synchronization tool for PicoMites - PicoM. The tools is written in Python and allows to backup and restore a PicoMite, including files and directories, options, and libraries. In addition, the tool can list ports, options, files, and PicoMite properties. Many commands work also under Linux except for the `restore` command (see current issues here). Important: Use at your own risk; I tested it under Windows but until you made sure that it works for you as expected, backup your PicoMites also by other means! For installation instructions, see PicoM on GitHub. To get help, enter `python picom.py -h`. Here are some examples of its functions: Get information about the connected PicoMite: PS F:\Dropbox\__GIT\picom> python picom.py c PicoM v0.1.2 (beta) Retrieving key data from PicoMite ....... done. Firmware : PicoMite @`COM5` Chip : RP2350A MMBasic : V6.00.01 CPU frequency : 252 MHz Current drive : A: Disk space : 2146 of 2306 kB free (93%) List the serial ports: PS F:\Dropbox\__GIT\picom> python picom.py p PicoM v0.1.2 (beta) 2 serial port(s) found : `COM1`, Kommunikationsanschluss (COM1) `COM5`, Serielles USB-Gerät (COM5) Transfer a file from a PicoMite to the PC: PS F:\Dropbox\__GIT\picom> python picom.py -s "COM5" -f "hps_srv.bas" xr PicoM v0.1.2 (beta) Receiving file(s) using XMODEM : Retrieve [==================================================] 100% `hps_srv.bas` - complete (62592 of 62592 bytes). Make a backup: PS F:\Dropbox\__GIT\picom> python picom.py -n "backup" b PicoM v0.1.2 (beta) Save options to "202501121755.opt" file ... Save library, if exists, to `202501121755.lib` ... Retrieving file tree from `A:` : Parsing `A:/` ... Parsing `A:/tests/` ... 15 file(s) and 1 folder(s) found. Create backup of PicoMite @`COM5` : Backup folder : `F:\Dropbox\__GIT\picom\backup_202501121755` Create local folder `F:\Dropbox\__GIT\picom\backup_202501121755\tests` Backup [==================================================] 100% `202501121351.lib` - complete (3072 of 3072 bytes). Backup [==================================================] 100% `202501121351.opt` - complete (896 of 896 bytes). Backup [==================================================] 100% `202501121755.lib` - complete (3072 of 3072 bytes). Backup [==================================================] 100% `202501121755.opt` - complete (896 of 896 bytes). Backup [==================================================] 100% `bootcount` - complete (128 of 128 bytes). Backup [==================================================] 100% `hps_calibrate.bas` - complete (16512 of 16512 bytes). Backup [==================================================] 100% `hps_srv.bas` - complete (62592 of 62592 bytes). Backup [==================================================] 100% `lib_bno055.bas` - complete (3328 of 3328 bytes). Backup [==================================================] 100% `lib_mcp3208.bas` - complete (2816 of 2816 bytes). Backup [==================================================] 100% `lib_tools.bas` - complete (768 of 768 bytes). Backup [==================================================] 100% `tests/test_gamepad.bas` - complete (3840 of 3840 bytes). Backup [==================================================] 100% `tests/test_mcp3208.bas` - complete (384 of 384 bytes). Backup [==================================================] 100% `tests/test_ps4.bas` - complete (4096 of 4096 bytes). Backup [==================================================] 100% `tests/test_tof8x8.bas` - complete (5504 of 5504 bytes). Backup [==================================================] 100% `tests/test_tof8x8_i2c.bas` - complete (4608 of 4608 bytes). Backup `backup_202501121755` successfully created. 15 file(s) and 1 folder(s) saved; 0 failed Restore a backup: PS F:\Dropbox\__GIT\picom> python picom.py -n "backup_202501121351" r PicoM v0.1.2 (beta) Retrieving key data from PicoMite ....... done. Retrieving file tree from `F:\Dropbox\__GIT\picom\backup_202501121351` : Parsing `F:\Dropbox\__GIT\picom\backup_202501121351` ... Parsing `F:\Dropbox\__GIT\picom\backup_202501121351\tests` ... 15 file(s) and 1 folder(s) found. Restoring backup `F:\Dropbox\__GIT\picom\backup_202501121351` to `PicoMite` @`COM5` : Continue (y/n)? y Kill everything on drive `A:` (y/n)? y Really?!? (y/n)? y Formatting drive `A:` ... Restore [==================================================] 100% `202501121351.lib`complete (3072 of 3072 bytes). Restore [==================================================] 100% `202501121351.opt`complete (896 of 896 bytes). Restore [==================================================] 100% `bootcount`complete (128 of 128 bytes). Restore [==================================================] 100% `hps_calibrate.bas`complete (16512 of 16512 bytes). Restore [==================================================] 100% `hps_srv.bas`complete (62592 of 62592 bytes). Restore [==================================================] 100% `lib_bno055.bas`complete (3328 of 3328 bytes). Restore [==================================================] 100% `lib_mcp3208.bas`complete (2816 of 2816 bytes). Restore [==================================================] 100% `lib_tools.bas`complete (768 of 768 bytes). Make folder `tests` ... Restore [==================================================] 100% `tests/test_gamepad.bas`complete (3840 of 3840 bytes). Restore [==================================================] 100% `tests/test_mcp3208.bas`complete (384 of 384 bytes). Restore [==================================================] 100% `tests/test_ps4.bas`complete (4096 of 4096 bytes). Restore [==================================================] 100% `tests/test_tof8x8.bas`complete (5504 of 5504 bytes). Restore [==================================================] 100% `tests/test_tof8x8_i2c.bas`complete (4608 of 4608 bytes). Restore PicoMite options (y/n)? y Reset options ... Re-open serial port ... Restore options from `202501121351.opt` ... Re-open serial port ... done. Restore library from `202501121351.lib` (y/n)? y done. Backup `F:\Dropbox\__GIT\picom\backup_202501121351` successfully restored. 13 file(s) copied, 1 folder(s) created; 0 failed 2 backup management files ignored Please let me know if you find the tool helpful. Of course, I appreciate any bug reports ![]() Cheers Thomas Edited 2025-01-13 03:40 by karlelch |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
... I rarely had so little feedback ![]() If you are not into Python, you can package to tool into an executable. For this, you install pyinstaller pyinstaller and run it with the picom.py file as argument. It generates an executable for the platform you run pyinstaller from. I added to the repository the executable for Windows to the repository. Cheers Thomas |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 75 |
Hello Thomas, don't be disappointed! I saw your thread and think the tool is very interesting and useful! But I haven't gotten around to trying it out yet... ![]() And besides, I'm not an "experienced Python user"! ![]() So thank you very much for the Windows EXE! bfwolf |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
![]() |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
... new version (v0.1.4): Command for displaying the complete file tree added: PS F:\Dropbox\__ROS\__Robots\__code\hexapod2\mmbasic> .\picom ft PicoM v0.1.4 (beta) Retrieving file tree from `A:` : 21 file(s) and 2 folder(s) found. Content of `A:` : ├──tests │ ├──abc │ │ ├──202501121351.opt │ │ ├──202501121755.opt │ │ └──202501132242.opt │ ├──test_gamepad.bas │ ├──test_mcp3208.bas │ ├──test_ps4.bas │ ├──test_tof8x8.bas │ └──test_tof8x8_i2c.bas ├──202501121351.lib ├──202501121351.opt ├──202501121755.lib ├──202501121755.opt ├──202501132242.lib ├──202501132242.opt ├──bootcount ├──hps_calibrate.bas ├──hps_srv.bas ├──lib_bno055.bas ├──lib_mcp3208.bas ├──lib_tools.bas └──test_pio_uart.bas |
||||
ebbandflow Regular Member ![]() Joined: 31/08/2023 Location: United StatesPosts: 42 |
Hi Thomas, thank you for posting this tool. I have been looking for a way to use xmodem now that I don't have windows and terraterm anymore. I have not been able to get your tool working in Linux Mint yet, but I am 100% sure it's user error and I'm going to keep trying! ![]() |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi ebbandflow Thanks. I tested it briefly under Raspberry Pi OS (bookworm). If you post the errors that you see I may be able to help. Best Thomas |
||||
ebbandflow Regular Member ![]() Joined: 31/08/2023 Location: United StatesPosts: 42 |
Thanks Thomas, I got it working today and been playing with it... what a great little program! ![]() ![]() ![]() ├──LCD$edit.054.bas ├──LCD$edit.055.bas ├──LCD$edit.056.bas ├──LCD$edit.057.bas ├──LCD$edit.058.bas ├──LCD$edit.059.bas ├──LCD$edit_test.wg ├──LCDwithoutLib.bas └──testInputprog.bas (venv) ebb_flow@Workstation:~/Projects/picom$ python picom.py -s "/dev/ttyACM0" -f "LCD$edit_test.wg" xr PicoM v0.1.6 (beta) Receiving file(s) using XMODEM : Error: File `LCD.wg` not found ... skipped. Error : 1 of 1 transfer(s) failed. (venv) ebb_flow@Workstation:~/Projects/picom$ python picom.py -n "backup" r PicoM v0.1.6 (beta) Retrieving key data from PicoMite ....... done. Traceback (most recent call last): File "/home/ebb_flow/Projects/picom/picom.py", line 1210, in <module> res = _restore(args, info) ^^^^^^^^^^^^^^^^^^^^ File "/home/ebb_flow/Projects/picom/picom.py", line 1024, in _restore stamp = _args.name.split("_")[1] ~~~~~~~~~~~~~~~~~~~~~^^^ IndexError: list index out of range Edited 2025-02-07 13:56 by ebbandflow |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi ebbandflow, ok, I guess it is the parsing of the `$` sign as well as the fact that there may be a second `.` in the file name. I'll look into it later today. Cheers Thomas |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 5050 |
Hi Thomas, The reconnect issue with linux can easily be fixed if you create a udev rule for your pico. Then it always reconnects to the same /dev/name device. Not sure if you can automate write a separate python script for udev rules. I create it manually. About restoring options: one option is OPTION MODBUFF, that goes on the expense of A:/ drive space. I would personally restore options BEFORE restoring files to the A:/drive. I do think this is a very handy tool in education environment. Kids could corrupt systems unintended. To restore systems to virgin state easy is very handy. I assume this is the application: Education. They have their own SD card for personal storage, and get a training system that has tools and examples pre-installed. Volhout Edited 2025-02-07 18:23 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi ebbandflow, regarding this issue: For restoring a backup, picom expects the backup's folder name with the time stamp separated by "_" (e.g., "test_202902080820"), because it uses the time stamp to identify its own files (e.g., the backup of the options, of the library, a list of the copied file names). In the new version, picom will not crash anymore if the backup name does not contain a time stamp, but it will not restore options or a library because it then does not know what files to use for that. So the command "pair" for backup and restore are, e.g., python picom.py -s "COM5" -n "test" b and python picom.py -s "COM5" -n "test_202502081001" b Best Thomas Edited 2025-02-08 19:10 by karlelch |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Ok, same as for Windows/powershell, `$` indicates variable name in the Linux shell. I have not too much experience with Linux - there may be shells that don't do that. In any case, the problem occurs already before the command parameters are parsed by picoms. In your case, `LCD$edit_test.wg` is handed to picom as `LCD.wg` because the string `$edit_test` is interpreted as a variable, which is empty, because it does not exist. So there is little to do on the picom side. You can remedy the problem by "escaping" the `$` character: python picom.py -s "/dev/ttyACM0" -f "LCD\$edit_test.wg" xr In my hands, this works. A new version (v0.1.7) is on GitHub. Best Thomas |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi Volhout, thanks a lot for this info - I'll look into this next. Best Thomas |
||||
karlelch![]() Senior Member ![]() Joined: 30/10/2014 Location: GermanyPosts: 235 |
Hi Volhout, Thanks for the suggestion. I looked into udev rules but then came up with a potentially simpler solution: I record the GUID of the PicoMite at the very beginning and then, when reconnecting, look for the Pico device with that ID. It sort of works but then I run into a problem that I don't understand: (picom) rbot@rbotai:~/picom $ python picom.py -s "/dev/ttyACM0" -n "test_202502081508" r PicoM v0.1.7 (beta) Retrieving key data from PicoMite ....... done. Retrieving file tree from `/home/rbot/picom/test_202502081508` : Parsing `/home/rbot/picom/test_202502081508` ... 2 file(s) and 0 folder(s) found. Restoring backup `/home/rbot/picom/test_202502081508` to `PicoMite` @`/dev/ttyACM0` : Continue (y/n)? y Kill everything on drive `A:` (y/n)? y Formatting drive `A:` ... Restore [==================================================] 100% `hps_srv$88.test.bas` - complete (62720 of 62720 bytes). Restore [==================================================] 100% `202502081508.opt` - complete (896 of 896 bytes). Restore PicoMite options (y/n)? y Reset options ... Re-open serial port ... Checking for Pico with ID `BA90242DCBF` ... `/dev/ttyACM1`, Pico - Board CDC `/dev/ttyAMA10`, ttyAMA10 Found Pico @ `/dev/ttyACM1` with ID `BA90242DCBF` ... Successfully reconnected. Restore options from `202502081508.opt` ... Traceback (most recent call last): File "/home/rbot/picom/picom.py", line 1184, in <module> res = _restore(args, info) ^^^^^^^^^^^^^^^^^^^^ File "/home/rbot/picom/picom.py", line 1071, in _restore _ = sendCommand(cmd, doWait_ms=1200) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/rbot/picom/picom.py", line 251, in sendCommand res = SerIO.readline() ^^^^^^^^^^^^^^^^ File "/home/rbot/picom/lib/python3.11/site-packages/serial/serialposix.py", line 595, in read raise SerialException( serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?) I can access the newly connected device (e.g., I asked it for its GUID) but then later I get an access problem ... I cannot figure it our right now; need to sleep over it. Good point. I'll change that when I figured out the reconnection issue. Thanks! Best Thomas |
||||
ebbandflow Regular Member ![]() Joined: 31/08/2023 Location: United StatesPosts: 42 |
Thomas, Thank you for explaining how to change things and avoid problems! I took your advice and after renaming files on the A:/ drive to remove the $ symbols I was able to use xmodem for individual files and also the backup utility. It's very nice to be able to upload files without pasting a few lines at a time into the console ![]() |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |