208 IX: IX_menu_i and Improvised Programs (208.html)
Keywords
ICH180RR Python ICH180 Raspberry "Pi Zero W" Python MicroPython "Raspberry Pi 5" "Python 3.11" IX IX_menu_i IX_menu_i.py "improvised program" Menu SubMenu "Raspberry Pico" "Wio Terminal" "RPi 5" "RPi 4B" "RPi 4" Pi-400 "IX software family" requires "IX requires" MD5 "IX hash totals" WioClock prepIX prepIX.py main_i.py improvised IX_list_i.py "_i" RUPasc "complex vectors" logging "process control" requests "requests is deprecated" GPIO photocell pull-up pull-down "Enter key" IX_init_i.py
double-photocell "double photocell" flash IP IPv4 "IP address" "IX_boot" "Light Sensor" "GPIO 20"
"GPIO 21" Test_readCD2.py readCD2 initCD2 pir2 CLI MehInCharge.xom MIC "CD2 dongle©" "CD2 dongle"
/KeywordsEnd
(To enlarge .....Click it)
IX or (IX by DC) or "|><"
This article is a part of the IX family of software.
Introduction
Python programs are used throughout the Raspberry Pi world. In some cases, it is preferable to group a small number of programs in a menu that permits the user to select
which program to run. On small processors, such as the Raspberry Pico and the Wio Terminal, only one program can be invoked on the device. In this case, the only way
to select one of many programs is by using a menu-program that invokes each one of the group of programs as a submodule. Regardless of the reason, when a Python programmer
wishes to use a menu that calls or invokes subprograms, the IX_menu_i.py program will be useful. The IX_menu_i.py program is a self-contained Python program that is simple to
understand and use. It does not need to import any other modules to function fully. At its minimum, it requires only 5 modules. A complete working example can be found in Source 01. This article fully describes how to make use of the IX_menu_i.py program. The result is a tiny menu like the one shown below:
IX_menu_i
---------
1 test1_i:
2 test2_i:
3 exit_i:
Another alternative menu can be used in the absence of a keyboard by using a novel double photocell. This simple double photocell lets a Raspberry Pi user select a submenu item from an invisible menu. For more information, see the note named "double photocells" near the end of this webpage.
An example using IX_menu_i.py
This example is comprised of two subprograms called test1_i.py and test2_i.py. These two tasks will appear in a small menu followed by IX_exit_i.py. The latter appears at the bottom
of the menu and is primarily used to exit from the menu. The short test1_i and test2_i example programs merely print out "This runs test1_i" or "This runs test2_i" respectively. This full example only needs the following small modules:
IX_init_i
test1_i
test2_i
IX_exit_i
IX_list_i
IX_menu_i
All 6 modules are contained in one source code module in Source 01.
The resulting program is called IX_menu_i.py and is invoked on a Raspberry Pi with the command:
> $ python3 IX_menu_i.py
When invoked, it prints some introductory information followed by each row (or submenu) of the short menu. If the user simply hits the Enter (CR or Carriage Return) key after each row, the next submenu row is displayed. This continues until all submenu rows have been displayed. The last submenu row is "exit_i:". All of this is shown below:
$python3 IX_menu_i.py
This program is part of the IX group of programs
Source: https://www.ePhotoCaption.com/a/208/208.html
hit CR to NOT select the menu item
IX_menu_i
---------
1 test1_i:
2 test2_i:
3 exit_i:
IX_menu_i
---------
1 test1_i:
2 test2_i:
3 exit_i:Y
Do you really want to exit?Y
Normal Exit
Exit Code 1
As seen above, if CR is hit repeatedly, the menu simply loops around and around. When the user wishes to exit from the menu, he/she simply enters "Y" after the ". . . exit_i:" line. The program then asks "Do you really want to exit?". If the user replies "Y" (for "Yes" or "O" for "Okay"), the program prints "Normal Exit" then "Exit Code 1" and then exits.
However, if the user wishes to run one of the programs on the menu, he/she simply replies "Y" after the ":" following the "program" name. Then the program runs as shown below:
IX_menu_i
---------
1 test1_i:Y
This runs test1_i
2 test2_i:
3 exit_i:
In this manner, program "test1_i" or "test2_i" runs. After running, each submenu item will normally return to the menu, permitting the user to select another program or to rerun the program again. (If the subprogram returns False, then the whole menu system will immediately exit normally.) This menu system is designed to be ultra-simple yet powerful. Any
Python programs can be invoked using this menu system. As with most standalone programs, no parameters are passed to the subprograms.
What Python programming is needed?
In fact, very little Python programming is needed to fully use this menu system. There is no need to modify the IX_init_i.py, IX_exit_i.py or the IX_menu_i.py code. The user only needs to add his own code to the test1_i.py and/or the test2_i.py programs. There is only one module that the user must tailor to his/her needs. It is the very short IX_list_i.py module. As can be seen, this is merely a list of the names of the submodules (without the ".py" extension.) In our example, the IX_list_i.py contains only one statement shown below:
moduleList=[ test1_i , test2_i, IX_exit_i ]
The source code spreads this list placing 1 module name per line, each followed by a comma and a backslash.
If these modules are all coded together (as in Source 01), they can be run by Python or Thonny. If they
are coded separately, they must be concatenated together (in the correct order) before they can be used.
The IX_menu_i program is not more complicated than this. Good Luck using this simple Python menu system.
Example Use of IX_menu_i.py
requires("IX_init_i()")
requires("test1_i(v)")
requires("test2_i(v)")
requires("IX_exit_i(v)")
moduleList=[ test1_i , test2_i, IX_exit_i ]
requires("IX_menu_i()")
#/main_i.py #then convert to main.py before using python3 to run it.
Simply create the Python source code shown above and save it as "main_i.py". Then prepare it (expand it) using "prepIX.py" (formerly named "buildMain_WioT_v01o01_2023EMay15_i.py" in Source 06) and save the result as "main.py". Then copy it onto the device where it will be used (such as the Wio Terminal) and then cause it to run.
Note that the string in parameter "v" appears to be "passed" to the required modules. Note also that these "v" parameters only appear in the strings passed to the modules, not as actual passed parameters. This is because all improvised modules expect to receive an additional parameter that will (in future versions of prepIX) be used to verify the version of each improvised module. This future version verification is not yet being done, but the "extra" parameter is being included here to agree with the syntax of future versions of prepIX. Do not worry if this is still unclear, it should become much more clear in the future.
Note also that the list of module names ( test1_i , test2_i, IX_exit_i ) is not invalid. When a module name is passed to a Python routine, it does NOT need to be followed by a pair of parentheses.
Another example of the use of "prepIX" appears in Source 06. The example in Source 06 merely "requests" the modules "request" and "show". When Source 06 is next updated, the use of "requests" will be converted to "requires". The actual verification of the version numbers of the required modules will be done in a future version of prepIX. Note that the parameter "v" is also included in Source 06 although the deprecated "requests" module does not yet use it. The author apologises for the fact that the IX family of software is not yet complete (as of 2023JOct28).
Future Functionality of IX_menu_i
-
Because some devices do not have a keyboard, it is impossible to type the "Enter" key or any other key on the keyboard. This is true of the bare Wio Terminal when not accompanied by any peripherals. To permit a minimum of functionality in these cases, a future version of the IX_menu_i program will wait for keyboard input for 5 to 30 seconds. If a null answer (just the Enter key) is received before 5 seconds, then it will presume that the user wishes that the program act as if the user had hit the Enter key. If it takes 30 seconds or if any character is received, the answer will be presumed to be "Y". Therefore the first submenu item will be run to completion. Control will then return to the menu and the next menu item will wait for keyboard input. Using the same logic, this next submenu item will be run to completion or not run etc. In this manner each of the submenu tasks can be run in turn. If the last submenu item receives a "Y", it will ask "Do you really wish to exit". Eventually it should receive a "Y" (or its equivalent) and then exit. To prematurely stop this cycle, the user can simply turn the power off.
-
When using the Wio Terminal, it is possible to "talk" to it using the 3 buttons on top
or by using the tiny joystick in the bottom right corner. Simply depressing the "joystick" button can be interpreted as the equivalent of an Enter key. Most other small devices have absolutely no means of communicating with them unless some sort of peripheral is attached. In these cases, the author suggests that a pair of tiny photocells be carried by the user when using his Raspberry Pi computers. The double photocells can function as an input peripheral as described in the paragraph after the photos (below).
double photocells (CD2 dongle©)
Because they have no active components, the two photocells in series are quite safe to plug into the GPIO on a Raspberry Pi. Furthermore because they are powered by a GPIO data output pin, their current draw should not adversely affect the Raspberry Pi. The double photocells are more useful on other Raspberry Pi board computers than on a Pi400 (that always has a keyboard). However, a Pi400 can be used to test this "CD2 dongle©". The author and ICH180RR retain copyright to the name "CD2 dongle©".
When using a Raspberry Pi, if 2 photocells are connected in series to 2 specific adjacent GPIO pins: physical pin 40 (as GPIO 21 input) and physical pin 38 (as GPIO 20 output), the RPi can detect whether or not the photocells are covered by your finger. Physical pin 40 is always located diagonally across from physical Pin 1 (which is marked by a small square). [Take care identifying the physical pins, one of the early GPIO diagrams labelled 2 different pins as pin 37.] First, connect the photocells in series between the 2 specific pins previously mentioned. Polarity is unimportant when connecting photocells. Then the Python program must connect an internal pull-down resistor between GPIO 21 and ground. The Python program should set GPIO 20 high (making it approximately 3v3). Then the Python program should read the input on GPIO 21. When the user covers both photocells (even with a finger), the program should be able to detect it on GPIO 21. To facilitate their connection, the photocells can be soldered in series to two female Dupont connectors which can be easily slid onto the 2 GPIO male connectors on the Raspberry Pi GPIO. The double photocells (right above) are even better, having been soldered onto a 2-pin female GPIO connector. The Python program named Test_readCD2.py can be found in Source 12. It uses the function named readCD2(). Prior to using this function, the GPIO pins must be initialized using the function initCD2(). These functions must be told the number of the higher physical RPi input pin (not the GPIO pin). Often a single CD photocell might work, but sometimes it takes 2 photocells (recommended) in series to be sure.
-
The double photo-cell mentioned above would be especially useful when booting up a tiny Raspberry Pi board (or most other computers that don't have any peripherals attached). They should finish the boot up process by starting a program called main.py. To indicate that it is running, this main.py program will flash an onboard led to "display" the value of the first 3 digits of pi which is of course, 3.14. This flash pattern is 3 flashes on, 1 long flash for the dot, then 1 flash then 4 flashes. Most Raspberry Pi users will recognise this as meaning 'pi'. This pattern also demonstrates to the user the nature (syntax) of the flash pattern. The author has NOT yet written the IX_boot.py program mentioned herein.
A user can control a headless Raspberry Pi using the Remote Desktop Connection (RDC) in Microsoft Windows on a laptop. However, to do this, the user must know the exact IP (IPv4) address of the Raspberry Pi. The author plans to use a double photocell to communicate with a recently booted headless Raspberry Pi. The menu that boots up will start up a special main.py program. This program will monitor the double photocell connected between physical pins 38 and 40 for communication from the user. It will watch to see if the double photocell gets covered. While it is covered, the little main program will start flashing the onboard LED once per second. The user will count the number of LED flashes and will uncover the double photocell after 1, 2, 3 or 4 flashes. The number of flashes selected will have the following meaning:
IX_boot up: LED flashes
----------------------
1 a request to "see" the IPv4 address of the Raspberry Pi
2 a reply of "No" ("No" is 2 letters long)
3 a reply of "Yes" ("Yes" is 3 letters long)
4 a request to start up a specific predefined program (eg the pir2 control system).
The replies of "No" and "Yes" will serve in the future when the "IX_boot" program becomes more complex.
Many other existing boot-up procedures simply flash the full lengthy IP address. The full IPv4 address contains as many as 12 digits separated by 3 dots. However, the leftmost 3 numbers are usually the same for most devices on a single wifi router. Therefore, often, only the rightmost number(s) need to be known to identify the IP address of the specific Raspberry Pi being booted up. The IX_boot up sequence will therefore provide the IPv4 address starting from the right, not the left. To convey an IPv4 address of 0.0.11.28, the IX_boot up main program will flash the on-board led 8 times, then 2 times, then one long flash (for the dot) then once, then once again, after which it will pause. Then it will resend the series of flashes that signify the 3 digits of pi. This means that it is again waiting for input from the user. [After all, the usual name of the Pi user is "Pi"! LOL]. If the user asks for the IP address a second time, IX_boot will send the full IP address via the on-board flashing led in the normal order from left to right. To send a zero, the onboard led will be flashed 10 times. . . Ugh!
The author has developed a Raspberry Pi program (named pir2) to monitor and control the environment in an area of a building. It runs from the Terminal command line (CLI) and can be started by the IX_boot program once the Raspberry Pi has been booted up. When starting up, the pir2 system asks a number of questions that can be answered by a "Yes" or "No". Often, the pir2 system will be running in a situation devoid of both keyboard and mouse. The existing pir2 system can make use of a hdmi monitor and/or BlueTooth audio speaker. The IX_boot program with the double photocell seems to be a great complement to the pir2. Perhaps the IX_menu_i system will also become part of the pir2 system along with the IX_boot program. Another program that must be occasionally initiated by the user upon boot up is a program that will upload log files from the pir2 system to the http://www.MehInCharge.com (MIC) database in Source 13. Note that the MIC database system was also written by this same author.
-
Most Raspberry Pi users have either headphones to plug into an audio jack, or they have a BlueTooth speaker or a monitor. Most Raspberry Pi computers can communicate verbally using either headphones or a BlueTooth speaker. When this is possible, an improved IX_boot program should make use of them to audibly communicate to the user. If a monitor or TV set is connected to the Raspberry Pi, the double photocell can be used to reply to the commands displayed by the IX_boot program. An On-Board keyboard on a GUI screen is sometimes useful when no keyboard is available. But this situation is a CLI interface, not a GUI user interface. Some users have a wireless keyboard that can be connected by wifi. The author has one that also incorporates a mouse. Operating a Raspberry Pi without a physical mouse is always very problematic. Fortunately wireless mice exist, but they still need a dongle plugged into a USB port on the Raspberry Pi. The Wio Terminal addresses this need for a mouse by providing a tiny joystick. No such thing is yet available on the bare Raspberry Pi. The double photocell only addresses (albeit very poorly) the absence of a keyboard.
-
The Wio Terminal already has an internal photocell. It is described in Source 09. Note: WIO_LIGHT is the pin for the built-in Light Sensor. The Light Sensor is connected internally to A13. FreeRTOS is distributed by Amazon (Source 10). FreeRTOS also supports Circuit Python. Many FreeRTOS examples are in C++. FreeRTOS is explained by Seeed Studio in Source 14. Unfortunately, the author of this website has not yet begun to use FreeRTOS nor C++. With FreeRTOS, the internal photocell on the Wio Terminal can be read using the following (C++?) program:
#include
void setup() {
pinMode(WIO_LIGHT, INPUT);
Serial.begin(115200);
}
void loop() {
int light = analogRead(WIO_LIGHT);
Serial.print("Light value: ");
Serial.println(light);
delay(200);
}
Note: The Light Sensor is at the back of the Wio Terminal, just above the microSD card slot but it is impossible to see it. To make it dark cover the whole back of the Wio Terminal with your hand.
WioClock
The first application that will use the IX_menu_i system is the WioClock application (shown below) written by the author in MicroPython for the Wio Terminal. It is described in detail in Source 08.
(To enlarge .....Click it)
The tiny Wio Terminal
|
(To enlarge .....Click it)
WioTerminal with WioClock.py v2o11
|
As of 2023JOct27, the WioClock is functional but does NOT yet make use of the IX_menu_i.py software. As of 2023JOct27, the WioClock has one issue: it cannot yet be adjusted to the exact time. In the near future, the 3 buttons on the top will be used for slight time adjustments.
The IX Family of Python Software For the Raspberry Pi
This IX_menu_i.py program can be used stand-alone without any other part of the IX Family of Python Programs for the Raspberry Pi. But the author is developing the whole IX software family to fully support Python programming for the Raspberry Pi. The IX family will bring all of the following facilities to the Raspberry Python world:
A. the IX macro preprocessor (Source 04).
B. "requires" (operates along with the Python import) modules See Source 16.
("requests" is an alternative verb to "requires") See Source 06.
C. optional embedded MD5 hash totals in IX software modules (Source 05).
D. improvised program menu system (the IX_menu_i system in this article).
E. programs stored in Packages e.g. IX_textpack_pkg.py (Source 15).
The IXp preprocessor is the co-ordinating component of the IX family. For example, a simple mention of
the IX_list_i.py module is sufficient to define all the submenu items for the whole IX_menu_i program. All of the inferred modules needed can be deduced by the IXp preprocessor. IXp
will recognize the IX_list_i.py" as the critical defining item for any individual IX_menu_i system. Using the information in the IX_list_i.py module is sufficient to cause IXp to automatically "require" all of the submenu modules and the IX_menu_i.py module to be concatenated together into the final IX_menu_i.py program which will be called "main.py" by default. The specific name: "main.py" is the name needed for the resulting program to be installed on the Wio Terminal. See Source 07 for information about using the Wio Terminal
Any subroutines (external Python modules) that are used (or that a module says it "requires") during the preprocessing will automatically have their embedded MD5 hash totals evaluated and verified before the modules are built into the final programs. Another important feature provided by the "requires" facility is the automatic verification that the version of a submodule is at least as high as needed by the module that "requires" it.
The IX "requires" facility is very similar to the "import" statement normally used by Python. However, it seems that every version (or release) of Python has its own complex rules about the use of the "import" statement. The "requires" is an ultra simple adjunct to the existing import statements. The IX "requires" statement applies to modules that are present (and can be found) within the current computer's folder structure. Usually the modules mentioned by the IX "requires" statement have all been coded by a single programmer or by a small contained group of Python programmers.
The IX_textpack_pkg.py system (Source 15) packs and unpacks modules into an IX package whose format is defined by the author. It is composed of the following 7 modules:
IX_textpack.py packs a list of files into a package
IX_textunpack.py unpacks ALL the files from an existing package
IX_textselect.py selects (unpacks) a SINGLE file from an existing package
IX_textpack.txt explains HOW to use IX_textpackPkg_py.txt
IX_textnames.py lists the filenamess in a package (deprecated . . . use n.py]
IX_textadd.py adds a file to the package (deprecated. . . use IX_textpack.py with ">>" instead)
n.py lists the various contents of the package
The module IX_textselect.py unpacks one selected module from an IX package.
Complex Vectored Readings: RUPasc
Another (not integral) component of the IX Software family is a novel way of storing process control readings. This novel format applies especially to time-stamped readings that are gathered at irregular time intervals. For such readings, it is especially important to keep each reading and its respective time-stamp firmly tied together. Often a set of readings is stored in one vector while the time-stamps are stored in another vector. But it is very easy for these 2 vectors to be separated, permitting them to possibly become "uncoupled". The author suggests that a complex Python vector be used, storing the numerical reading in the real part; and the Unix time-stamp in the imaginary part of each complex number in the vector. The author suggests the name RUPasc be used for this vector format. The acronym-like name, RUPasc, means "Reading plus Unix-time with Periods (ascii)". The word "Periods" refers to the decimal points that are included. The inclusion of these decimal points offer additional precision such as millivolts and milliseconds. More about this can be found in Source 02 and Source 03. An example of a single RUPasc reading logged by a Raspberry Pico is shown below:
eg "(0x10000.000+1621625066.713j),"
This RUPasc format does not conserve storage space, but it does securely retain ALL the necessary information together. It is worth noting that a Pico is capable ( but barely capable) of creating and transferring such complex vectors. This is because the Pico has a clock but no Real Time Clock nor any complex arithmetic processing capability. More Pico information (using Thonny) is available at Video Source 02 below.
Hopefully, the author will soon find time to complete the development of the IX family of Python software and the routines needed for the RUPasc logging format.
Sources
Video Sources
Video Source V208:01: Introducing Raspberry Pi 5 (0:55m) by Raspberry Pi on 2023 I Sep 28
Video Source V208:02: www
Pi Pico - Review etc (18m 31s)
by #garyexplains as of 2021B Feb 08
Web Sources
Web Source S208:01:www
IX_menu_i_py.txt by D@CC on 2023JOct26
Web Source S208:02:www
RUPasc: A Format for ADC Reading Samples by D@CC on 2023EMay04
Web Source S208:03:www
ReadingsVectorTimeInterval.txt by D@CC on 2023FJun29
Web Source S208:04:www
IT: IX/IXc - A General Purpose Macro Processor (183.html) by D@CC on 2023EMay17
Web Source S208:05:www
IT: Hash Totals using md5_IX (206.html) by D@CC on 2023EMay17
Web Source S208:06:www
IT: prepIX (196.html) by D@CC on 2023EMay16
Web Source S208:07:www
Wio: Readying A Wio Terminal for IX systems (198.html) by D@CC on 2023EMay18
Web Source S208:08:www
Wio: WioClock (189.html) by D@CC on 2023DApr02
Web Source S208:09:www
Getting Started with Light Sensor by jianjing Huang of Seeed Studio on 2023AJan17
Web Source S208:10:www
Using FreeRTOS with the Raspberry Pi Pico by Daniel Gross of Amazon Web Services on 2022JOct22
Web Source S208:11:www
Test_isTrueIfDark_py.txt by D@CC on 2023JOct29
Web Source S208:12:www
Test_readCD2_py.txt by D@CC on 2023JOct30
Web Source S208:13:www
A&C: MIC-Meh In Charge .com (128.html) by D@CC on 2021DApr16
Web Source S208:14:www
How to use FreeRTOS . . . by jianjing Huang of Seeed Studio on 2023AJan17
Web Source S208:15:www
IX: Creating Python Packages of Functions (174.html) by D@CC on 2022BFeb26
Web Source S209:16:www
IX Family of Software: requires( function. . .) (209.html) by D@CC on 2023KNov02
/SourcesEnd
There is a way to "google" any of the part-numbers, words or phrases in all my articles. This "google-like" search limits itself ONLY to my articles. Just go to the top of "Articles by Old King Cole" and look for the "search" input box named "freefind".
Date Written :2023 J Oct 26
Last Updated:2023 K Nov 23
All rights reserved 2023 by © ICH180RR
saved in E:\E\2022\DevE\MyPagesE\Globat\ePhotoCaption.com\a\208\208.html
backed up to ePhotoCaption.com\a\208\208_2023JOct26.html
Font: Courier New 10 (monospaced)
/208.html