I have a Pimoroni Pico base explorer board with a Pi Pico WH installed.
Then with Thonny I installed Micro Python (UF2).
Thonny showed (after plugging in the Pico explorer base while holding the Bootsel-button):
In the Variant section above I could also have chosen for:
Raspberry Pi.Pico W /Pico WH
What is the difference between those two variants?
Do the Pimoroni libraries replace the standard libraries or are the Pimoroni libraries an addition?
There are no errors when I type: “import math” or “import random”.
But when I like to use for example “import datetime” then I get:
Import Error: no module named ‘daytime’
I like to avoid these type of error.
I suppose that after Micro Python is installed that I can use most of what is published at The Python Standard Library — Python 3.13.2 documentation and Micro Python is focussed on what is usefull for programming a Pi Pico with reduced memory.
I found a lot of Beginners/Starters sites with Micro Python examples.
I found a lot at https://micropython.org/ but that is especially focussed on the type Pyboard.
I am looking for how can I know or find exactly what modules etc. are available for general programming this Pi Pico WH (or Pi Pico) or the Pico Explorer Base in particular?
You basically have MicroPython core libraries available, and if you load the Pimoroni flavor of MP you also have all the libs and modules they provide in addition. Anything else has to be added manually. Usually by adding a py-file to the lib-directory.
The Python Standard Library is not a good reference, since this is about CPython and MicroPython is stripped down. For example datetime is a very fat library so you usually don’t find it on MicroPython.
MicroPython libraries — MicroPython latest documentation has a list of core modules. Just open the top-most item (MicroPython Libraries) and then you have three subsections with Python standard libraries, MicroPython specific libraries and port-specific libraries.
For Pimoroni libs, you have to dig into the source-code at their Github-repo. AFAIK, they don’t have a central documentation system.
Thank you for your explanation. With the link you specified I’ve dived now into reading all about the list of core modules. There I can draw useful information from that documentation firstly and then secondly the info found at the Github-repo which I had discovered already. But there I missed the info about the basic MP. I’m going to work on it.
…doesn’t this just go on root or else you need to call it explicitly from the lib folder inside your code (e.g. from libraryfoldername.libaryfilename import class)…
This is especially true when you make use of Adafruit or Waveshare or any other code out there from various OEMs, where example files expect other libraries or source code in dedicated folders (check import section on top of the example code to identify the folders). You then need to find the relevant library and put it in the exact folder on root or else the example code wouldn’t run. Alternatively you remove all the (library) folder references in the source code and put the expected files on root.
But I guess it’s easier to identify the folder and place everything there rather than to change all references in the code (and again recursively in the libraries, as well)…
Also, I think the folders are case sensitive…
MircoPython will happily import from tjhe root folder or the /lib folder. It is just a convention: put your own code into root, and external libs into /lib.
a) import foo.bar => imports “bar.py” from the folder “foo”
b) from foo import bar => imports class bar from the file foo.py from root (or ROM system folders in path - see example below)
proof & example:
In the Pimoroni example code inky_frame.py it reads in the first line
…which means it imports (reads) the class “ShiftRegister” from the file “pimoroni.py” (which in this case in already backed into the Flash ROM, but could also be placed on root) and does not read the file “ShiftRegister.py” from the folder “pimoroni” - as you said above…
The below is the contents of the file pimoroni.py:
I could be mistaken, of course…
I really would need to bias my code to find out explicitly, but this is my understanding and how it (my code) works ever since…
In addition, @Tonygo2’s modules listing from the Pico’s ROM Image shows a couple of folders, such as “aioble/” which includes files, like “core” or “device”. Everything else are plain text source code libraries as “pimoroni”, which contains classes like “ShiftRegister”…
On top of this, if you want want to import a class from a library in a folder, it should be importet as:
from folder.library import class
…folder of course then needs to be placed on root.
Have I overseen something or am I mistaken?
Please anybody, correct me if I am wrong…
[quote=“Kees, post:1, topic:27392”]In the Variant section above I could also have chosen for:
Raspberry Pi.Pico W /Pico WH
What is the difference between those two variants?
[/quote]
Pico W => PCB only Pico WH => PCB with already soldered headers
In the moment you copy any ROM image by any manufacturer (Raspberry, Pimoroni, Waveshare, etc.) to the PICO everything which comes with it is going to replace the existing information on the device’s system partition (e.g. “baked in” libraries inside the ROM image). This may not necessarily delete your user space with your source code, but there are also images, which overwrites and clears out everything, e.g. in the case of a “nuke ROM” or when the filesystem has been changed. Then, the whole PICO will be erased and overwritten with the new Flash ROM information. That’s why it is a good device to not keep your source code exclusively on the PICO, but on the host computer…
It always a good advice to backup your source code from the PICO prior to flashing a new ROM to it…
Those are system libraries and baked into the micropython ROMs for PICO. Thus, they are always there and can be imported by any program any time…
My guess is that importing the library “datetime” works fine as the error thrown is with regard to a module called “daytime”. Thus, the library “datetime” calls another library named “daytime” and the latter one cannot be found, either because it is not part of the ROM file or it has not been placed properly on the PICO’s file system to be found.
You need to lookup the first library “datetime” and check how it calls the library “daytime”. My conclusion is that “daytime” is no system library or should have been found automatically.
In either case you need to get (find) the source code of the library “daytime” and simply place it on root of the PICO (copy by Thonny from your host computer to the PICO on “/”).
Which example code do you want to run? Can you share the link to the code so we can look into it?
Man, no way…!
Having realized this earlier could have saved us time for coding some real stuff…!
so, you are saying the error message then should read like this:
Anyways, then I correct myself from above and propose to get the library datetime.py (python source code) and place it on root of the PICO…it then should work…
Maybe this version of datetime.py solves your problem, while importing a non-existing file. Download it to your host computer and save it as datetime.py. Then transfer it via Thonny to the PICO’s root…should work - or you need another version of datetime.py…
Again, can you share the example code you want to run, so we can look into this…?
All the references of any time commands in this file should match with the class’ and/or functions in my above shared datetime.py. If not, you need (to find) another version…
Yes, you are mistaken. What you write about classes is correct, but try this example:
> mkdir foo
> echo 'print("hello from bar")' > foo/bar.py
> python3
Python 3.9.18 (main, Sep 06 2023, 07:49:32) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo import bar
hello from bar
The main thing to keep in mind: an import will do two things: execute top-level code in the imported file and secondly expose names in the current namespace. So from foo import bar will expose bar in the toplevel namespace. If bar is a variable, method, class and so on from within foo.py, this variable method, class will be in the current namespace (your ShiftRegister example from above). If bar is a submodule (on filesystem-level a subdirectory), it will expose the module bar in the namespace, i.e. you can refer to variables, methods, classes and so on with bar.whatever.
Things get more complicated once you add foo/__init__.py into the mix. This file is read while importing the module foo. Some code will use __init__.py to import itself some stuff into the foo-namespace from submodules within foo. So if __init__.py contains from bar import baz then you will have baz in your foo-namespace, i.e. you can use foo.baz instead of foo.bar.baz.
You will find many tutorials on the Python module-system and they are definitely worth a read, especially if you think my explanation sounds complicated.
That is true, but that is why stripped down versions exist (like the one @m1cr0py7h0n linked to above). You will have to check what you really need. If your concern isn’t compatibility and if you only need a small subset of functionality, you could even just extract what you need. But this extra work is again only necessary if you run out of RAM or flash.