[The Maker Pi Pico board is Device:106] [This article breathes life into the amazing Maker Pi Pico (as of 2021FJun16)] [The author is trying to address the current lack of available information about the Maker Pi Pico ] [WARNING: Do NOT connect any of its Grove 3V3 pins to the 3V3 power on the Raspberry Pi.]
Techies should read the brief "For Techies Only (Special Notes)"
Programmers can Copy-n-Paste Python code marked "selectCode #"
Table of Contents (Outline)
(A number following a title refers to its selectable code segment)
The Maker Pi Pico by Cytron
What you will need
IX.py The Pi Library
For Techies Only (special note)
Introduction
Pi & Pi Pico Menus
The "PicoLe-22" Audio Start-Up Menu
The Pi Pico GP pins
Stand-Alone Power SWD DEBUG Connector
Maker Pi Pico Notes
Class, Attribute, Method
RPi digLight Sensor
Debugging the Pi Pico using SWD
Main MakPiADC Adapter Pinouts
MakPiADC (early prototype)
UA741 Op-Amp
Software Uart for a Pi Pico in Python
mpyPico_uart.py (listed as textloop_pico .py)
textloop_pico.py 00
Cytron Support
Select Products [in US$] (Cytron products listed first)
Thonny/Python/MicroPython Software Sources (Mostly Cytron)
Simple Python pyPlot program: testPlot
strToComplex.py Function
A Format for ADC Reading Samples
Adding Redundancy to the Ascii Sample Vectors
The Pico's Low-Res issue: testUtime.py program
wave-samples for pyPlot .py
testPlot.py 01
Function Generator for the Pi Pico
funcGen_pico_wPot_pico.py 02
funcGen_pico_woPot_pico.py (not yet coded)
Meaning of "count_freq=10_000_000" for PWM
USB Microphone for the Pi for the Maker Pi Pico
picoButton _pico.py 03
(see ref to 05)
deviceReset_pico.py 04
maker-pi-pico-rgb-led_pico.py 05
Library of pico Python Routines: IX_pico.py
*PiX.py 06
*ix_pi.py 06
*IX_libr_pico.py 06
.py 10 (first instance)
testUtime.py program in 11
test_piButton.py program 12
test_timer.py program 13
Maker Pi Pico Schematic
Maker Pi Pico gets WiFi via an external ESP01S (using a Pico UART)
ESP01S firmware from Arduino IDE
Maker Pi Pico gets WiFi via an external ESP01S (using a Pico UART)
esp01uart_pico.py program 14
Transfer Serial data from the Pi UART on GPIO pins
serReadWrite_pi.py program 15
Raspberry Pi Audio vs Pico Audio Pin-Outs
Using the Male Audio Jack on the MakPiADC
A Small 741 Amplifier on the MakPiADC board
More about the MakPiADC Board
The MakPiADC Can Become A Theramin
theraminVolume_pi.py
Maker Pi RP2040
End of Article (Sources follow)
External Sources
Video Sources
Web Sources
-end of table of contents-
I inserted a note for the Wio Terminal using "pickle-22". Chrome reported a virus in 164.html. So I backed out my changes. This note did not have the same issue. I re-did similar edits, with no resulting issue. Today, I had uninstalled "Total A/V", perhaps there is a relationship.
This article was intended, in 2021FJun06, to describe in detail both the Maker Pi Pico hardware board and the Raspberry Pi Pico that it can house. But it also describes a future MakPiADC Adapter that can be built to interface them to a Raspberry Pi computer. I apologize for the long length and level of detail in this article, but my goal is to provide detailled information and software for the Maker Pi Pico and its Pi Pico. To use the software provided in this article, no additional hardware is required except when using the version of "functionGenerator with pot" software producing variable audio output. This software specifies a 4K6 (4,600 ohm) potentiometer connected to GP26 (ADC0) [and to 3V3 and GND], but I have used a 6K8 (6,800 ohm) pot instead and connected it to GP27 (ADC1) instead. References to some additional software have been included in the section: "Thonny/Python/MicroPython Software Sources (Most by Cytron)", the Cytron GitHub software references (Web Source 17) and in the Web Sources at the bottom of this article. Herein, I have included the following simple programs written in Python mainly to be used with the Pi Pico:
(code without a # prefix is future code that has not yet been written)
07 readADC_pico.py code snippet to read the value from ADC0
08 syncRTC_pico.py program on Pico to sync its RTC with the host (e.g. the Pi)
09 syncRTC_pi.py program on Pi to sync its RTC with the Pico
mpyPico_uart_pico.py listed as textLoop_pico.py text generator via uart
00 textLoop_pico.py send text, read and print it
PicoLe-22_pi.py start-up menu for Pi (not yet written)
PicoLe-22_pico.py start-up menu for Pi Pico (not yet written)
piButton_PicoLe-22_pi.py GPIO22 button (photo cell on pi)
10 strToComplex.py converts any numbers to Complex numbers
01 testPlot.py to plot a wave form on the Pi monitor
02 funcGen_pico_wPot_pico.py wave form generator (with pot) for pico
funcGen_pico_woPot_pico.py wave form generator (wo pot) for pico
signalGen_pico.py signal generator for pico
03 picoButton_pico.py senses Maker Pi Pico pushButton GP22
04 deviceReset_pico.py resets all or any devices on the Maker Pi Pico board
(WARNING should not set ~RUN (RESET) low)
05 maker-pi-pico-rgb-led_pico.py activates the Neopixel RGB Led (Software from Cytron at GitHub)
11 testUtime.py program comparing reading precision on the Pi with the Pico
06 IX_libr_pico.py library of functions useable on the Pi and/or Pi Pico (in progress)
06 PiX.py
06 ix_pi.py * Note: resolve this naming issue *
06 IX_libr_pico.py
10 .py second instance converts str to complex (integers only)
11 testUtime.py program comparing reading precision on the Pi with the Pico
12 test_piButton.py tests pi Button (usually on GPIO 22)
13 test_timer.py program tests a timer/scheduler to run routines repetitively or when events occur
14 esp01uart_pico.py Maker Pi Pico gets WiFi via an external ESP01S (using a Pico UART)
15 serReadWrite_pi.py Transfer Serial data from the Pi UART on GPIO pins
picoButton(GPnn,waitTime) picoButton(22,10) #returns True if GP22 is pushed within 10 seconds
Note: the 2 ADC functions below use the pico & return values to the pico code.
readADC(nn,cnvrt) readADC(0,2.0) #returns 6.6 if 3.3 volts is at ADC0 (GP26 on Grove 6)
(readADC(26,2.0) reads the same pin). Only 1 sample is read.
readWaveADC(nn,cnvrt,n,fmt,DT) eg readWaveADC(0,2.0,100,"ADC",1.0) #returns a wave vector of 100 values where
DT= sample interval in seconds( often 1.0). If DT=0, samples are ASAP.
(n is the # of samples (range:0,65536), fmt is one of these input formats:
RAW: Raw ADC Readings without Times (most speed efficient if cnvrt=1 or 1.0)
ADC: ADC Readings in the raw U12 or U16 two byte format (unconverted).
The Pico only sends a series of voltage readings. It is the Pi that adds the time.
The resulting vector of complex numbers is the same result as when the
RUasc format is used, except that the times are slightly later. This format is
designed to be used when there is no Real Time Clock (RTC) on the Pico.
RDasc: Reading (Decimal) in ascii. It is difficult for the pico but is human readable
RRasc: Redundant Readings in ascii (to use with noisy serial lines)
RDSasc: Reading (Decimal) plus non-Unix time (in Seconds), good when human testing
stored as (65536+1j).
RUasc: Reading (Integers) plus Unix-time in ascii: each number pair is stored as
a complex number. In Python, the complex number 1+2i is represented as
(1+2j) including the parentheses (unless real=0). The sample "s" e.g. 65536 and the
Time "t" e.g. 4 are stored as the complex number(65536,4000j). Note that the real part
of the complex number is the sample value. Normally the time is the unix time, not
a small number of seconds. A unix time (epoch time in GMT excluding the milliseconds
is 1621625066. So a max sample (of 65535 ) including GMT (UTC) would be stored as
(0x1000+1621625066j). Every non-unix time includes 3 digits of milliseconds. For example:
15 seconds is represented as 15000j. The Pi Pico does not do calculations using complex
numbers but this does not stop it from representing this large number pair in the
complex format. The statements to get this Unix-Time are:
"import time;ts=time.mktime(time.gmtime());print(ts)"
Note that the real-time clock on the Pi Pico must be initialized manually (see code 08).
RUPasc: Reading plus Unix-time with Periods (as decimal Points). This is similar to ADC, except
a) that the ADC reading is U12 or U16 and b) for the RUPasc time, the Pico is the source
of the time. (RUPasc is efficient if cnvrt=1 or 1.0). The RUPasc is stored as
(0x10000.0+1621625066.713j). (This is the recommended Format for now and the future.)
Note that the clock on the Pi Pico must be initialized manually (see code 08)
because the original Pi Pico does not have a Real Time Clock.
picoWaveADC(nn,cnvrt,n,fmt,DT,bps) eg picoWaveADC(0,2.0,0,"ADC",1.0,9600) This only stops if RESET is done on the Pico. It
is the same as readWave, but sends results continuously in fmt at 9600 bps to the Pi.
Results are sent from pico to pi on the Grove GPnn line (on GP00 if nn=0 etc).
The Pi code will function as a UART to receive the continuous samples.
Normally the ADC source (ADCnn in Grove 6) for these samples is a pin on the Pi.
This is used when the Pi Pico is simply functioning as a hardware ADC for the Pi.
piWaveADC(nn,cnvrt,n,fmt,DT,bps) eg piWaveADC(0,2.0,100,"ADC",1.0,9600) This runs on the Pi like readWaveADC()
on the Pico and the results are returned as a vector to the Pi code to be stored
on the Pi as a vector. Note that nn is the GP pin number on the Pico, not the Pi. The Pi
normally uses this routine to read voltage values that the Pi Pico ADC is measuring
from a voltage source on the Pi. The specified ADCnn on the Pi Pico will be continuously
sampling the ADC voltages on pin GP nn. They come from the Pi, but the Pi Pico will be
sending these results in "fmt" at a bitrate of "bps" back to the Pi on the GPnn line
in the Grove 1 connector. This has the effect of adding an Analog to Digital Converter
to the Pi by "dedicating" the Pi Pico to this job. This source of continuous readings
(or samples) notifies the Pi of the current voltage on the ADC source pin in the Pi.
Choosing too fast a bps rate will overload the Pi resulting in errors. The only solution
is to reprogram the Pi Pico to send results at a slower bps rate or by using a more
efficient and less redundant format. The resulting wave (of samples) is a wave vector
listing the samples that have been read. The "fmt" of "SPasc" is similar to RTKasc except
that the Time is derived from the Pi clock, not the Pi Pico clock. The sample value
stored in complex number can be derived using the real() function, which eliminates
the imaginary portion of the complex number (which is the time). The Pi time in the SPasc
format can be a few milliseconds later (because it is appended by the Pi) but it does not
require the setting of the Real Time Clock (RTC) in the Pi Pico. If the fmt is Null, the
SPasc format is used in the vector that is produced.
generateWave(nn,cnvrt,n,vector,DT) eg generateWave(18,1.0,0,vector,1.0) This generates a wave on pin GPnn on the Pi Pico,
using the shape specified by the vector. Each subsequent voltage value is
generated using the conversion factor of cnvrt, after a time interval of DT seconds.
The vector should be an integer number of whole cycles. If the last value is not
approximately equal to the first value, then the Wave generated will not be smooth.
The Wave will be generated n times, after which it must be restarted. If n = 0 then
the wave will be generated continuously until the Pi Pico is RESET.
theraminVolume_pi.py uses SPI to control the IC for theramin volume (not yet coded)
Note: program names are usually device-specific:
for Pi only (end with _pi.py)
for Pi Pico only (end with _pico.py)
not device specific (end without _pi.py nor _pico.py)
What you will need
Of course, the Maker Pi Pico is designed to be used when a Raspberry Pi Pico is plugged into it. To run some of these above programs, you should plug in a male-male jumper from GP4 to GP5. You should also plug a pair of headphones (or an external speaker) into the audio jack. For the buzzer to operate, the buzzer ON-OFF switch (on the Maker Pi Pico) should be switched ON, to the right (towards the GP20 push button). In the future, you should also insert a Micro-SD card into the Maker Pi Pico. To create a theramin, you will need the MCM4131 IC volume control add-on.
IX.py Library
The author has created a small library of useful Python functions for the Pi family including the Pi Pico. More can be read about them in Web Source 21 which is Article 155 (also by the author of this article.) If this library is placed in the same folder with the Python routines, its functions can be included in your program with the "import IX.py" statement. The IX.py library is actually the group of the 3 libraries listed below. Be sure to refer to the correct library. A full up-to-date list of IX Software Functions can be found in Article 215.
Some Python programmers (I was one of them) have difficulty to correctly reference objects, global variables and functions that have been imported. Often the solution is to preface the name of the object, variable or function with the name of the library followed by a ".". For this reason the name of the library is very short.
ix_pkg.py contains functions that work on both the Pi and the Pico
ix_pkg_pi.py contains functions that only work on the Pi
ix_pkg_pico.py contains functions that only work on the Pico
All of the callable functions created by the author will eventually be placed in one of these libraries. The name of the IX library was selected to be very short so that it can be easily referenced in Python code. More information about creating such a library can be found in Web Source 21 (article 155) . It shows how to create your own personal library and how to use it on your computer without uploading it to the web.
A list of the functions currently in the PiIX.py Library follows:
f3() converts any number to a string in format -999999.999 so that it can be easily printed.
inputWto() input text from keyboard with timeout
show(isShow,vName,value,sN) show the value of a variable at statement sN if isShow=True
For Techies Only (special note)
The Maker Pi Pico permits quick and easy access to the following devices (some on the Pi Pico itself): one led/pin, 3 push-buttons, an RGB led, audio for headphones, a buzzer, and a micro SD connector. Software that activates each is (or will be) provided on this web page. Software: MicroPython (Thonny) code making use of following technical capabilities of the Pi Pico (and the Maker Pi Pico) is also provided. Code written in "C" is also supported on the pico, but is not covered in this article. Wifi is only supported via the Raspberry Pi. Note that Thonny cannot support 2 Desktop users simultaneously. (If Thonny won't start using RDC, Thonny might be already running on the main pico Desktop or vice-versa.) In the absence of a MakPiADC Adapter, the simple circuitry can be built on a small breadboard. Most of the pins on the Pi Pico can be assigned an internal pull-up or pull-down resistor using software control. Technicians will find the 30 Test Points (female jumper pins) on the MakPiADC board especially useful.
Pi Pico ADC-Rx Control Protocol
To make the ADCs on the Pico "on demand", the Pico will begin by continuously sending the ADC reading of both ADC converters at the predefined baud rate (bps). This is done continuously unless the pin is switched to be mode IN on the Pico. If the Rxn pins are in mode IN, the Pico will read both the Rx0 and Rx1 lines from time to time. If either line stays HIGH, this means to stop sending the readings on its respective Txn line. While the Rx0 or Rx1 line is not set HIGH by the Raspberry Pi, the Pico will continuously monitor the Rxn lines, read the ADC and send the reading of the respective ADC on the respective Txn line. This will be known as the "Pi Pico ADC-Rx"control protocol. Perhaps, one day, an I2C chip will be created using this protocol and this format.
Note: "Pi Pico ADC-Rx"protocol and its RUPasc serial format are recommended.
Most technicians will appreciate the schematic diagram of the Maker Pi Pico found at the end of this article. Web Source 22 might also be of interest. It describes how to connect the Maker Pi Pico to the web using an ESP01S WiFi module also made by Cytron. The ESP01S WiFi module (shown below) plugs into the small connector in the bottom right corner of the Maker Pi Pico. Some say that the software for the ESP01S wifi module doesn't work.
Necessary Hardware that is not included:
[This article needs headphones (or an external speaker), a male-male jumper, a 6K8 potentiometer, 1 CH 110V/15A relay (future), 2 photo-cells, and 2 6K8 resistors. A microphone would also be
useful. A MakPiADC board includes a microphone and all of the other devices (except the jumper).]
Devices/Functionality
The Pico supports GP IO, PIO, PWM, ADC, SPI, I2C, UART and HC logic,
but buffers should be used when a pico pin drives loads over 10mA
low speed multiple blue led control
low speed bright NeoPixel RGB led control
reading of 3 push Buttons (active low)
uart operation (low speed) software-coded simulated using software and timers
uart operation (medium speed bidirectional text) using a hardware uart in the Pico
uart operation (high speed) using PIO in the state-machines in the Pico
signal generation of various waveforms (using PIO) in the Pico
audio tones output to the audio jack in the Pico (or buzzer on the Make Pi Pro).
manual switch to disable the buzzer on the Make Pi Pro
ADC sampling of
voltages (including VSYS)
temperature of the pico processor
which usually is the ambient temperature
ambient light (using a photo cell [not included in the Maker Pi Pico])
potentiometer [not included in the Maker Pi Pico]
plotting of waveforms (even a single cycle) to the display (usually on the Pi)
creating brief interrupt routines to respond to each interrupt "tick" on Pi or Pico
reading from (and writing to) a micro SD card on the Pico (future)
SWD (SoftWare Debugging) of the Pi Pico
Stand-alone operation of the Pi Pico (without a Raspberry Pi)
Reset (not-RUN) button for the Pi Pico
PicoLe-22 headless audio start-up menu for the Maker Pi Pico
(using headphones instead of a display)
Initialization of the RTC (clock) on the Pi Pico from a Pi
The addition of a small photo cell and resistor (Device:58) permits measurement of the ambient light and serves as a push-button for the Pi.
Introduction
First, I apologize for the length of this article, but all of this Maker Pi Pico information is HERE "in one place". In the future, I plan to chop it into 2 or 3 separate articles.
The Maker Pi Pico by Cytron (Web Source 01), (Cytron part number ESP-01) shown above, at US$9.00 is an important companion product for the Raspberry Pi Pico. The Raspberry Pi is deficient in that it does not have any ADC (Analog to Digital Converter), something that the competing Arduino includes. The Raspberry Pi 400 (built inside a keyboard) is missing an audio jack. None of the Raspberry Pi boards have an audible output device, such as a buzzer; they are all missing a pushbutton and a temperature sensor. The Grove connector (made popular by Seeedstudio) is becoming a standard as an I2C connector; the Raspberry Pi computers all support I2C but do not have any Grove connectors. An external micro SD card connector is missing from the Pi Pico. The Real Time Clock (RTC) on the Pi Pico does not (as of 2021FJun01) get intitalized on start-up. The Pi Pico does arithmetic in low-precision, because it doesn't have floating point hardware. So high precision data readings must be logged on the Pico, then sent to be processed on the Pi. The Pico can maintain the time, but loses track of the time when rebooted. The Maker Pi Pico together with the Pico itself (and related software described herein) address ALL 11 deficiencies just mentioned. As an added bonus, the "Signal Generator with Pot" when used with the CDS1 photo-cell becomes a "theramin" to play music with no hands.
One day, Cytron will hopefully resolve the software issue with its optional ESP-01 WiFi chip for the Maker Pi Pico. Then the software fix for the Unix time issue will no longer be necessary at Pico boot time. Via its PIO assembler language, the Pi Pico supports high speed "bit-banging". This article describes the use of a Raspberry Pi to program and/or control the Pi Pico, but any standard computer (Mac, Microsoft or Linux) can be used. The author has (as of 2021 F Jun 06) completed some experimentation with the Maker Pi Pico. The electronics in the Pi Pico needs 3V3 to run, but its buck converter (on-board power supply) can be driven by any supply voltage from 1.8v to 5.5v DC via the USB cable. Most of the GP pins on the Pi Pico can serve multiple purposes and must be "set-up" by software. A 2x3 pin connector is useful (when the Raspberry Pi is used for SWD [SoftWare Debugging] ) of a Standalone Pi Pico. This 2x3 pin connector can also provide Power to the Standalone Pi Pico, if no USB cable is used. It easily connects to the 2x3 SWD males pins on the Maker Pi Pico board. One notable mistake or deficiency exists on the current Maker Pi Pico board (Revision 1.2.0 or 1.2 as of 2021FJun06). Cytron intended to provide optional WiFi for the Pi Pico by using the ESP8266 IC for which there is an 8-pin connector (labelled ESP-01 with a "wifi" logo) in the bottom right hand corner. Apparently there is a software driver issue (problem) that prevents its use.
The Maker Pi Pico board provides all of the following capabilities:
1 Audio Jack (mono microphone & mono headphone OR dual headphones [left & right])
1 audible Piezo Buzzer (with on/off switch)
1 NeoPixel RGB LED
1 micro SD Card connector
3 Push Buttons (Active Low)
1 ~Run (Reset) Button
2 ADC (Analog to Digital) converters (plus 3 internal ADCs)
6 Grove connectors
40 female jumper pins
27 LEDs (1 per usable GPIO pin)
plus (on the Pi Pico itself)
1 green LED
1 BOOTSEL pushbutton
1 micro-USB B female connector to connect to a host computer
1 temperature sensor (senses the internal processor)
1 2MByte QSPI Flash Memory (internal flash) on the Pi Pico Board
1 264KB on-chip RAM on the RP2040 microprocessor in the Pi Pico.
plus (on the future MakPiADC Adapter, if used)
1 photo cell (there are 2) providing digLight, ambLight, piButton
1 photo cell providing a second pushButton for pot & "push to talk" microphone use
1 6K8 potentiometer (pot) used in many test programs
1 TMP102 I2C temperature sensor
1 PDM MEMS on-board microphone (future)
1 Grove connector to attach more Grove devices to the Raspberry Pi
(Note: it connects the Pi 3V3 pin of the Grove connector to external sensors)
1 2x3 pin connector to facilitate SWD on the Pi Pico using the Maker Pi Pico board
(and provides power to a stand-alone Pi Pico without a USB cable)
3 cables each ending with a male Grove Connector
one to Grove 6 on the Pi Pico (to ADC0 and ADC1)
one to Grove 1 on the Pi Pico (to GP0 and GP1 to read the ADC0 and ADC1 )
one to Grove 3 on the Pi Pico (to GP4 and GP5 to read the MEMS )
(WARNING: do NOT connect the 3V3 pin of any Pico Grove connector to the Pi 3V3)
1 future 8 wire cable to a ST7735 LCD screen (using SPI protocol when driven by the Pi)
1 future 1 CH (110V/15A) relay from Cytron for US$ 0.88 (currently Out Of Stock at Cytron)
1 UART (future use to read serial data from a standalone Pi Pico)
3 terminals to/from the Pi Pico: WAV (GP18), ADC0 and ADC1
4-8 dip-switches or cuttable jumpers (traces to disable the POT, ambLight, MEMS mic and the 3v3 to pico)
NB the Pi Pico supports GP-IO, PIO, PWM, ADC, SPI, I2C, UART and HC logic,
but buffers should be used when the pico drives moderately heavy loads
Drawbacks or Unknowns of the Maker Pi Pico
The drawbacks of (or unknown info about) the Maker Pi Pico are:
-no software for the WiFi connector (ESP8266)
(This is not an issue when driven by a Raspberry Pi with WiFi.)
-the board is very tiny. The lettering is almost unreadable.
-complete support software is not readily available (other than in this article)
-a few GP pins can only be connected by jumpers (no devices nor connectors)
-the 3 SWD (DEBUG) points are not connected
-all pico pins are unbuffered (cannot drive more than 10 mA)
(perhaps a SN74AHC541N should be recommended.)
-the total power output limit is unknown
-the function of SWCLK and SWDIO is not stated
-is SA1 (labelled 3V3) actually VSYS? (see schematic at end of article!)
-is GP19 a second audio out or is it audio in or either?
-what does an "active low" push-button mean?
-which GP # reads the internal voltage of the Pi Pico?
-how to fully reset the Maker Pi Pico (i.e. turning all devices off)?
-ADC2 cannot read ADC by default from pin GP28
because RGB LED is wired to GP28. But ADC2 can read ADC from another
open GPxx pin if redirected to it using software (see Web Source 04 text
example). But note that reading from ADC(29) will read ADC from
ADC VREF (which is the system voltage). Reading from ADC(29) will
also automatically remove all pull resistors when reading the ADC.
Availability:
Maker Pi Pico (board ESP-01) by Cytron (Web Source 01) in Malaysia
(Shipping issues might occur if ordering directly from Cytron)
(See Cytron Software Notes below)
from Seeedstudio (Source 03) in the USA
Pi & Pi Pico Start-Up Menus
Human communication with a bare Pi Pico (or even with a bare "headless" Raspberry Pi) is difficult. Some sort of protocol should be defined. To provide an audio Start-Up Menu the following steps have been defined by David KC COLE;
The "PicoLe-22" Audio Start-Up Menu
The "PicoLe-22" Audio Start-Up Menu ( pronounced "pickle-22" ) applies to the Raspberry Pi and the Pi Pico. In French, the name PicoLe-22 means "Pico: The 22" which suggests using GP22 or GPIO22 for user input. Of course, if a monitor is available, the start-up menu should appear on the monitor on the HDMI port nearest the power connector on the Pi. On a Pi Pico, an I2C LCD monitor should be attached to the I2C Grove 1 connector; or to the first Raspberry I2C channel on pins GPIO2 and GPIO3 . The Wio Terminal can also use the "pickle-22" menu by blinking its tiny blue LED twice two times. The Wio Terminal has built-in Push Buttons, so on a Wio Terminal, the user should press Button 2 once to indicate that he/she is listening. The Wio Terminal should also sound its buzzer twice two times. Instead of pressing button 2 once, the user of a Wio Terminal could also whistle a short single whistle once into the microphone. On a Pi or Pico in the absence of any type of monitor nor keyboard nor mouse (said to be "headless"), the following "PicoLe-22 start up" communication steps are recommended:
the Pi or Pico blinks its main LED two times twice. This should be thought of as "blink-blink" then "blink-blink".
(this means 22 or "ii" in Morse Code) which identifies GPIO22 or GP22 as the default user input pin. When
clicked at the correct baud rate (bits/sec), a robot would recognize the US ASCII code (Web Source 14) for "cc" (2 lower-case Cs).
the user then "presses" push button 22 once which is:
GP22 push button on the Maker Pi Pico (by Cytron)
GP22 pin (physical pin 29) on the Pi Pico
GPIO22 pin (physical pin 15) on the Raspberry Pi
Button 2 (PC27#) on the Wio Terminal
(The previous 2 can be done by shorting GP22 or GPIO22 to ground with a m-m or f-f jumper)
(Note that the 13th "counted" pin on the pin-1 side is ground on both the Pi and the Pico)
the Pi Pico or the Pi should respond by blinking the LED once (meaning "yes" or "acknowledged")
(This signifies that two-way communication has been established.)
the user should have attached a pair of headphones (or an external speaker) to a headless Pi or to the Pico on GP18
(The Pi or Pico should then play the start-up menu audibly by saying "PicoLe-22 Menu".)
(The next sound played on a Raspberry Pi should be its IP address in English (for Remote Desktop Connection [RDC] use.)
(The Pi should then also send an email to the owner of the Pi. This email will specify the current IP address of the Pi.
This email is useful when the Pi is to be run by distant Remote Desktop Connection (when audio cannot be heard).
(My Raspberry Pi is plugged into a special 110v outlet that can be remotely voice-controlled to turn on or off
the Pi using a Google Home device.)
the user should then select subsequent actions from the audio start-up menu.
the user replies to audio questions by pressing on "pin" 22 once for "Yes" and twice for "NoNo" or "Unh-uh".
mnemonic: pin GP22 and physical ground pin 13 define "PicoLe-22"
A simple ambient light (& digital light/dark) sensor (Web Source 06) can be connected to a Raspberry Pi on GPIO22
(This MakPiADC light sensor can be used as both a digital light (digLight) sensor and
on a Pi as a non-mechanical pushbutton: piButton().)
[This same MakPiADC light sensor can be used as an Ambient Light analog sensor via the Pi Pico as picoButton(22).]
The Pi Pico GP pins
The pins on the Pi Pico are named GP pins (not GPIO pins). The physical numbering of the 40 pins on the two devices is also done differently. The Raspberry Pi GPIO pins can be seen by clicking on Web Source 05 at the end of this article.
("Do" means "ditto" i.e. "same as above")
GPIO# Device# USE USE IO Use
(x phys) Type a b Signal Mode
GP 0 Grove 1 SDIO SDA0 TX0 I2C
GP 1 Do CSn0 SCL0 RX0 Do
GP 2 Grove 2 SCK0 SDA1
GP 3 Do SDO0 SCL1
GP 4 Grove 3 SDIO SDA0 TX1 I2C
GP 5 Do CSn0 SCL0 RX1 Do
GP 8 Grove 5 SDI1 SDA0 TX1
GP 9 Do CSn1 SCL0 RX1
GP 6 Grove 4 SCK0 SDA1
GP 7 Do SDO0 SCL1
GP10 SDIO uSD card SCK1 CLK
GP11 Do Do SD01 CMD
GP12 Do Do SD11 DAT0
GP13 Do Do DAT1
GP14 Do Do DAT2
GP15 Do Do CSn1 CD/DAT3
GP16 WiFi (future) TX0
GP17 Do (future) RX0
GP18 Audio Center : Piezo buzzer & Audio Out Left
GP19 Do Middle Audio Out Right & Audio In
Gnd Do External
GP20 PButton Active Low internal
GP21 PButton Active Low middle
GP22 PButton Active Low external (pin used for the PicoLe-22 start-up menu)
GP23x undefined (no physical pin)
GP24? ~RUN Button (RESET) on the Maker Pi Pico
~RUN signal (phys. pin 30 ????)
GND (phys. pin 33)
GP29x ADC VREF nc (phys. pin 35)
3V3 (OUT) (phys. pin 36) and 3v3 male pin
3V3 EN nc (phys. pin 37)
VSYS nc (phys. pin 39)
VBUS nc (phys. pin 40)
GP25x single green LED on the Pico (near phys. pin 2)
GP26 Grove 6 ADC0 SDA1 ADC
GP27 Do ADC1 SCL1 ADC
GP28 NeoPixel RGB LED (not ADC2)
Stand-Alone Power Connector (SWD)
In addition to the above, on the Maker Pi Pico, a 2x3 connector with male pins provides the signals shown below. Like the pins on the Pi Pico, these 6
pins have been numbered counter-clockwise but starting with the pin in the bottom left. The names eg "SA1" have been created by the author of this website.
See the sections named "Debugging the Pi Pico using SWD" and "Stand-Alone Power Connector (SWD)" below for more information about using these
pins for debugging and as a source of power for the Pi Pico (instead of the USB micro B cable).
Pin Signal
1 SA1 3V3
2 SA2 GND
3 SA3 ~RUN
4 SA4 SWDIO (from pico DEBUG pins)
5 SA5 GND (from pico DEBUG pins)
6 SA6 SWCLK (from pico DEBUG pins)
This connector is also used to power and control the
Pi Pico when it is running stand-alone, i.e.
when the USB micro-B cable is not used.
Maker Pi Pico Notes
Note 1: The BootSel Button is on the Pico not on the Maker Pi Pico
Note 2: Wifi requires ESP01-wifi (with ESP8266) US$1.98 (no known operational software)
Note 3: optionally cut the trace on the back of the Pi Pico (not recommended)
to disable all the LEDs (lessens the load on each GPnn pin)
Note 4: A female pinout for each GP pin permits off-board
m-m jumpers to a breadboard for example
Note 5: micro-USB B connector on the Pi Pico provides power & data
Note 6: a manual on/off switch disables the piezo buzzer
Note 7: pico SWD (DEBUG) pins are inaccessible
Note 8: male pins exist for 3V3, Gnd and ~RUN
Note 9: IO: GP-IO, PIO, PWM, ADC, SPI, I2C, UART and HC logic
Note 10: GP25* connects software to the main on-board pico LED (no phys. pin)
Note 11: ADC4 reads an internal ADC (no phys. pin)
Note 12: ADC4 measures the processor temperature
Note 13: See Web Source 01: Article 161 to read ADC4
Note 14: Add Wifi using a ESP8266 board for US$1.98
But CircuitPython no longer supports this module :(
Class, Attribute, Method
To work with a Pi Pico, a programmer must understand and use the concept of "Class" in the Python language. A "Class" is a group of programming entities (or members) where each member can be identified, usually by its name. A good example of a Pi Pico Class is the group of devices in the Pi Pico machine. The members of a Class need not all be of the same type. To work with a Class, some Class code must be imported into the program. To do this for the Pi Pico machine class, the "import machine" statement must appear (usually at the top of the Python program).
One type of member of the machine Class is the group of Analog to Digital Converters (ADC) that are available on the Pi Pico. The first two physical ADCs on the Pico are ADC0 and ADC1. For a program to work with an ADC, it must construct a programming object (which is different from a variable). Each object has some attributes that describe it. One of its attributes is its name. So the programmer must create and name each object that is to be used. This is done by coding "adcFirst = machine.ADC(0)". This creates an object named "adcFirst" which corresponds to the physical ADC number 0 (on pin GP26 which is physical pin 31 on the Pi Pico).
There is at least one more attribute associated with any object, in this case: read_u16 is available for an ADC object. By referencing this attribute, the programmer can read the current value of a specific ADC. The code to do this is "adcValue=adcFirst.read_u16()". This "read_u16()" attribute is similar to a function because it is followed by "()". This indicates that some operation or procedure is probably indicated. With Classes, this type of operation is called a Method. Explaining this latter statement in detail: . . . . the code will do the following actions: It knows that it should be dealing with the ADC object named "adcFirst". It will perform the predefined method called "read_u16()" on this ADC object. This will cause the physical ADC to actually read the value being sensed by ADC0. This value is then assigned to the Python variable named "adcValue". This variable can then be used and/or printed by the programmer. The name "read_u16()" is slightly misleading; only 12 bits are actually read. . . . this name may predict a future improved version of the ADC electronics on a future RP2040. Other actual functions (called methods) are defined within the Class, some of them can operate on more than one object. Their use will not be described here.
In summary, to read and print the value read by ADC0, the only necessary Python code is the readADC_pico.py code shown in lines 1 to 4 below as "selectCode 07":
readADC_pico.py program 07
-- end of readADC_pico.py program in 07
The first two lines of code need only appear once in the code; their definitions do not need to be redone. But to read the value of ADC0 again, simply repeat the execution of the last two lines of code. A second reading of ADC0 will be performed and printed.
The value that is printed is 6225, which might be a surprise. It is not a voltage that appears at the pin for ADC0. Such a voltage should be between 0 and 3.3 volts. To convert the ADC reading to a voltage, the value read from the ADC must be converted to a voltage. This is done by the 5th to 7th statements in the above code. The voltage read was actually 0.3013733.
How to Sync the Pi Pico RTC with a Host Computer (Mac, Windows, Linux [even a Pi])
Because the bare Pi Pico is not connected to the Internet, without any GPS or other such hardware, the Real Time Clock (RTC) in the Pi Pico is not initiated upon start-up. Web Source 18 provides code for the Pico and the Pi that will do this. This code must be executed on the Pi Pico before Thonny is started. This code can also be modified and used to send a data log to the Pi from the Pi Pico. This code must run in the absence of the Thonny software controlling the Pi Pico. Be sure to also install the software named "pyserial" on the Raspberry Pi. The communication occurs along the USB cable joining the Pi and the Pi Pico. No other pins or cables are required. It bears repeating: these programs permit communications between the Pi and the Pi Pico for logging purposes for example, without Thonny. One very good result of using this approach is that the RTC in the Pi Pico will be reset each time the Pi Pico is restarted. But to do this, the corresponding code must still be running in the Pi and the USB cable must remain in place. It should not surprise us that, if the Pi Pico is headless and unconnected to a host computer, it will lose its RTC when it is RESET (or disconnected from power, if no battery backup exists).
syncRTC_pico.py 08
The following code should be stored on the Pi Pico and named main.py.
-- end of syncRTC_pico.py program in 08
syncRTC_pi.py 09
The following code should be invoked on the Raspberry Pi before the Pi Pico is started up.
-- end of syncRTC_pi .py program in 09
How to Sync the Pico RTC from a host PC without any code on the Pi Pico
Web Source 19 (an improvement over Web Source 18) by the same author, in Feb 2021 shows how to do this, but with no logging capability. The negative of this approach is that the RTC will be lost if the Pi Pico is reset. Someone on the Pi must reset the RTC on the Pi Pico each time. Note that the original author of this code was also building a fridge temperature monitor.
RPi digLight Sensor
This describes a simple circuit that will sense a simulated pushbutton on the Raspberry Pi. It is a simple ambient light sensor. When lit it returns a 1, When dark (when covered by a finger) it returns a 0. This is said to be "Active Low". Being "Active" means that it has NOT detected some ambient light.
The circuit uses GPIO22 on a Raspberry Pi. A small CDS photo cell is connected between GPIO22 and 3V3. Two 3K4 resistors are connected (in series) between GPIO22 and GND. The Python program in Web Source 07 named digLight.py is used to sense the ambient light via the photo-cell. The Python program in Web Source 08 named piButton_pi.py is the same program, but it returns a 0 when lit and a 1 when dark. This same circuit can be used to read the ambient light (as an analog value) by an ADC on a Pi Pico. An ADC is an Analog to Digital Converter; the Pi Pico has 3 externally accessible ADC devices: ADC0, ADC1 and ADC2. The ambient light (ambLight) is sensed at the midpoint between the two 3K4 resistors. This ambLight point is connected to ADC0 which is GP26 in the Grove 6 connector.
A program named piButton_pi.py can also be found in Web Source 08. This routine is used in the PicoLe-22_Menu_pi.py which should be used to start-up the Raspberry Pi. In the near future, the initialization of the Real Time Clock will be added to the PicoLe-22 Menu_pico.py program. For this to work, the Pi host must be attached to the Pico by the micro-USB B cable.
Debugging the Pi Pico using SWD
SWD means "SoftWare Debugging". Web Source 07 describes how to do SWD on the Pi Pico. The Maker Pi Pico supports SWD by providing 6 male pins that can be connected to the Raspberry Pi for debugging. Of the 6 SWD pins on the Pi Pico, 3 main signals need to be connected to the Raspberry Pi: SWCLK, SWDIO and RUN. In Web Source 07, on the Raspberry Pi, SWDIO is connected to GPIO24, SWCLK is connected to GPIO25 and RUN is connected to GPIO18. A ground connection between the two devices is also necessary: SWD GND can be connected to GND on physical pin 20 of the Raspberry Pi. The PicoLe-22 adapter provides easy access to GPIO27, GPIO17 and GPIO10 instead. For this purpose, the MakPiADC adapter can be ordered with the optional 3 wires with female ends that can be connected to SWCLK, SWDIO and RUN on the Pi Pico. If the Maker Pi Pico is used to access the Pi Pico SWD pins, appropriate connectors need to be soldered to them both.
One can use SWD to debug a standalone Pi Pico; "standalone" meaning "without using a USB Micro B cable". In this case, 3V3, GND and RUN also need to be connected from the Pi Pico to the Raspberry Pi. The MakPiADC adapter also provides a six-pin (2x3) female connector which can be used to SWD debug a "standalone" Pi Pico. WARNING: do not connect both this 6 pin connector and the Micro B cable between the Pi and the Pi Pico at the same time. The two sources of 3V3 volts (one from each cable) could easily cause problems.
The software tool recommended in Web Source 07 is OpenOCD which is designed to control the 2 ARM Cortex Processors in the Pi Pico. Web Source 08 describes the configuration file for OpenOCD which is "raspberrypi2-native.cfg'. When using the PicoLe-22 adapter, SWCLK, SWDIO and RESET can be redefined to use GPIO27, GPIO17 and GPIO10 (specify 27, 17 and 10 instead of 25, 24 and 18 in the config file below) on the Pi. The relevant lines in the configuration file are:
The MakPiADC adapter must drive the pins on each of its devices (the microphone is shown above) to connect SWD, I2C ADC etc to the Raspberry Pi. An image of the tiny (postage stamp size) PDM MEMS
microphone board from Adafruit Industries is what is shown above. This example shows the pin-outs of a device on the MakPiADC Adapter. The PDM MEMS
is an example of a device whose pins need to be driven for it to operate. Some of its devices are connected to the Pi and others to the Pi Pico, permitting the Pi and Pico to work better together. The MakPiADC Adapter connects its pins to the following external devices:
Device cable and connector
Pi Pico 2 signal lines from the PDM MEMS microphone on the MakPiADC Adapter via Grove 1
on the Pi Pico
Pi Pico ADC0 via a cable to a Grove male connector to Grove 6 on the Pi Pico
the Grove 6 can accept analog signals from the following devices:
ambLight photo cell
potentiometer on the MakPiADC Adapter
Pi Pico SWD via 6 wires to a 2x3 female connector to the 2x3 male connector on the Maker Pi Pico
I2C device Grove female connector on the MakPiADC adapter (to connect to external I2C devices)
MakPiADC Pi GPIO Pico GP
physical Signal Signal
pin Signal pin pin
--- ---------- -------- ------------------------------------------
T1 3V3 3V3 I2C1_3V3
T3 - GPIO02 I2C1_SDA
T4 - GPIO03 I2C1_SCL
T11 ADC1 pin GPIO04 ADC1 on Pico
T26 GND GND GND on Pico and I2C1_GND
na - GPIO17 SWCLK on Pico (for SWD)
na - GPIO27 SWDIO on Pico (for SWD)
T12 ADC0 pin GPIO22 ADC0 on Pico (piButton on Pi)
17 3V3 3V3 3V3 on Pico
na - GPIO10 not-RUN on Pico (for SWD)
T29 MEMS DAT GP01 DAT on Pico (MEMS)
T30 MEMS CLK GP02 CLK on Pico (MEMS)
T8 6K8 Pot GP26 POT on Pico (for Audio Signal Generator)
T1 WAV Pin GP18 WAV on Pico (from Audio Signal Generator)
J0 MEMS DAT cut to disable the PDM MEMS microphone
J1 ADC0-digLight cut to disable ambLight (liberate ADC0)
J2 POT cut to disable the 4K6 Pot (liberate ADC1)
J3 3V3Pi to 3V3Pico cut if Pico is connected via the micro USB B cabe (not running stand-alone)
J4 tiny on-board speaker cut if Pico has headphones or a better speaker.
T2 tiny amplifer In a UA741 simple op-amp circuit (amplifier gain: -20)
T10 tiny amplifer Out a UA741 simple op-amp circuit (amplifier gain: -20)
"MakPiADC Adapter" Physical Layout [top (component) view]
(designed to connect the Pi to the Maker Pi Pico board and add some devices)
***************************************************** (deprecated. . . . . .to be revised)
* 02 06 10 14 18 22 26 30 34 38 * physical pin #s
* 01 05 09 13 17 21 25 29 33 37 * on the Raspberry Pi
* T21---------------T30 *
* TMP102 ************* S0 ---UART IC--- * (this I2C uart will be a future addition)
* 741 * female * S1 4K6-Pot ********* *----- cable to male Grove connector (to Pi Pico Grove 1 connector)
* WAV * Grove * S2 * photo * *----- cable to male Grove connector (to Pi Pico Grove 6 connector)
* ADC0 * Connector * S3 PDM MEMS * cell * *----- cable to Pi Pico 2x3 SWD female connector
* ADC1 ************* S4 microphone ********* *----- cable to 2x3 female connector (to Pi Pico 2x3 male SWD connector)
* *
* 1 CH 110V/15A relay and LM741 (future) * (future optional addition)
*****************************************************
Note: the midpoint of the ambLight photocell sensor resistor is read to avoid voltage overload of the
ADC on the Pi Pico
Note: TMP102 is an I2C ambient temperature sensor
Note: T1 WAV is a terminal that can be a source of a signal wave from the pico's signal generator
Note: T9 the CDS0 (ambLight) is read by the Pi Pico using the Grove 6 connector
Note: T9 The piButton can also be read by the Pi as the binary digLight signal
Note: T11 ADC1 is a terminal that can be used for ADC1 signal source
Note: T12 ADC0 is a terminal that can be used for ADC0 signal source
Note: S1 jumper connects the tiny on-board audio speaker to its amplifier or driver
Note: S2 jumper connects the photo cell ambLight signal to ADC0
Note: S3 jumper connects POT to ADC1
Note: S4 jumper provides 3V3 from Grove 6 (ONLY if PicoLe-22 Adapter is not plugged into the Pi)
Note: S5 jumper connects the (CDS1(Mic-Enable) to Gnd
Note: S6 switch connects the 3v3Pico to the MEMS Select pin
Note: ADC2 is not said to be accessible on the Maker Pi Pico
but it can be used (if it is set up as an input instead of being an output)
(pin GP28 as output is used to drive the Neopixel RGB Led .)
Note: ADC3 is internally connected to measure the temperature of the RP2040 processor
Note: ADC4 can be used to measure the VSYS voltage that powers the Pico
(This is quite similar to the VBUS external supply voltage)
MakPiADC: Suggested GP & GPIO pin Usage
GP Signal GPIO Signal
----- ------------ -------- ------------
GP4 Grove 3 MEMS D GPIO02 I2C1 Data
GP5 Do MEMS C GPIO03 I2C1 Clock
GP8 Grove 5 Rx0 GPIO05 Relay D (future)
GP9 Do Rx1
GP18 Pico Audio Out GPIO07 SPI_CE1
GP19 Pico Audio In GPIO08 SPI_CE0
GP20 pico button:left GPIO09 SPI_MISO
GP21 pico Button:mid GPIO10 SPI_MOSI
GP22 picoButton :right(PicoLe-22Men) GPIO11 SPI_SCLK
GP25 Green Led on pico GPIO12 Rx1
GP26 Grove 6 ADC0 white GPIO13 Rx0
GP27 Do ADC1 yellow GPIO16 CDS1 (micButton)
GP28 NeoPixel RGB GPIO17 SWDIO (on pico)
pin 36 3V3 Pico GPIO18 Capac. to Speaker
pin 33 GND Pico GPIO19 tiny red LED (new)
GPIO22 PiButton (PicoLE-22 Menu)
GPIO23 PiButton (to GPIO22)
GPIO25 ~Run (on pico) [recently moved]
GPIO26 Tiny Red LED (deprecated)
GPIO27 SWCLK (on pico)
pin 01 3V3 Pi
pin 02 5V0 Pi
pin 39 GND Pi
MakPiADC (early prototype)
Shown below (on 2021FJun08) is the first (early) prototype of the MakPiADC adapter. It has one operational CDS photo-cell that can be read using the ADC on the Pi Pico that is plugged into the Maker Pi Pico board. The Raspberry Pi that reports the readings is hidden by the MakPiADC that is plugged into the GPIO pins of the Raspberry Pi.
The UA741 (aka IC-741 shown below) is a simple op-amp (operational amplifier) that amplifies a signal (see Web Source 32 for a Technical Description). It needs a +V and a -V supply, but requires at least 5V to operate. It works fine as long as the +(non-Inverting) input is biased midway between V+ and ground (using 2 R4 resistors (4K7 each) and a capacitor C2=10 uF connected from midpoint to ground). For audio signal amplication, the input signal should pass through a capacitor (C1 = 0.022 uF) then through R1 then into the Inverting input (pin 2). The Gain is (Av)= -(R2/R1) in the circuit below. The circuit below labels R2 as R. If a sine wave is input, the output will be a sine wave centered around +2.5 Volts. Fortunately, 5V is available from the Raspberry Pi (but not from the Pi Pico). I suggest R1=22K and R2=440K for a gain of -20. The speaker should be preceded by a 1000 uF capacitor. A stronger similar two-stage amplifer can be seen in Web Source 20 but it is said to be "noisy". The Pico output pins cannot provide more than 10ma, for this reason the 741 buffers its input signal so that "heavier" loads (such as a speaker) can be driven (using the Pi 5v source instead of a 3V3 source). Other OpAmps such as the LTV6741 should be considered.
Software UART for a Pi Pico in Python: mpyPico_uart.py
The Pi Pico has two types of built-in UARTS: software UARTs and "hardware" UARTs. The main software UARTs (available only on Pico pins GP0 and GP1) are used for low speed serial data transmission. The hardware UARTs are used for high-speed serial data transmission. A third type of UART (called a software-coded UART) is used for very low speed signals such as the blinking of a led. A software-coded UART is achieved in software by turning any Pico GPxx pin on and off using a timer routine as a rough clock. This is not advised as it can monopolize the processor. To check the default settings of the software UART (not the software-coded UART) on a Raspberry Pi Pico, enter the following statements using the MicroPython REPL interpreter:
The mpyPico_uart.py program (coded below as textloop_pico.py 00) is from Web Source 09. It emulates a hardware UART on the Pi Pico with GP4 as Tx and GP5 as Rx. This is the Grove 3 connector on the Maker Pi Pico. Because the MakPiADC adapter uses these pin for its MEMS microphone, it is advised to "deselect" the MEMS by opening switch SW6. This program expects a jumper from GP4 to GP5 on the Maker Pi Pico. This jumper will read whatever has been recently transmitted. This program writes a short text message: "hello", which it then reads and displays, then it exits with "- bye -". For the PicoLe-22.py software, GP5 (Tx) in Grove 6 should be connected to GP27 on the Pico. GP27 is connected to pin GPIOxx on the Raspberry Pi to be read using a simulated UART software routine (a software-coded UART) on the Raspberry Pi. A software-coded UART on the Raspberry Pi can read/write amazingly high bit-rates as shown in Code 13, but high rates put a heavy load on the Pi processor.
First set up the state-machine on the Pi Pico with the following 3 statements:
>>> # set-up the UART state-machine at the terminal prompt as follows:
>>> comm = machine.UART(1,9600)
>>> comm.init(9600, bits=8, parity=None, stop=1, timeout=2000)
Then copy (by clicking on "selectCode 00" button below, then paste it to Thonny to run the following program named "textLoop_pico.py" on the Pi Pico.
textLoop_pico.py 00
-- end of textLoop_pico.py program
Cytron Support
The Cytron Company is located in Malaysia in Southeast Asia. Their first language is not English but their documentation and videos are in English. It appears that the Cytron company first embraced the Arduino, but recently is turning some of its attention to the Raspberry products. This is probably because the Raspberry Pi supports the stronger (Linux) operating system. The Raspberry Pi Pico is a layered device. Development and experimentation are best done using a host computer such as the Raspberry 4 or 400 (or even a Mac, Windows or other Linux OS). The main layers of hardware and software are:
RP2040
the microprocessor chip with 256K RAM on the Pi Pico
Pi Pico board
contains the microprocessor with 2MB flash, connectors, devices eg ADC, pins etc
Maker Pi Pico
Grove connectors, interfaces to external sensors and devices (eg optional LCD)
including a connector for an external micro-SD card.
MakPiADC
connects ADC (and other Pico devices) to the Pi
Python Interpreter
provides MicroPython v1.14 on the Pi Pico with the machine Class
Raspberry Pi
the interactive workstation (eg RPi 400) with an optional disk drive, monitor, keyboard and mouse
Thonny v3.3.3
the first level of programmable software for the Pi Pico
Maker Pi Pico Software
Cytron software routines (Web Source 02) and the IX_libr_pico.py function library
RPi OS
Raspberry OS (Linux) which works well with a spinning disk drive
Router
Web access via Ethernet or WiFi
Note that upon startup the Pi Pico will try to run a local program called main.py .
It is recommended to install PicoLe-22_pico.py on the pico and rename it as main.py.
Serious programmers will want to sync the date/time in the Pico to the current time.
ESP-01 MPP $ 9.90 Maker Pi Pico Board with Pico soldered onboard
Rasp Pi Zero W $11.50 OOS Raspb Pi Zero W (HDMI, USB, Camera I/F)s
Rasp Pi Pico $ 4.98 Bare Pico no legs
Pico Kit $ 3.98 Pico Basic Kit (without Pico) (1)
PIC18F2520 $ 3.13 non-Pi microprocessor with 32 KB Flash memory and 10 ADC etc
74HCT9046AN $ 5.00 PLL with Band Gap Controlled VCO
nRF24L01 $ 1.25 RF Transceiver 2.4G
LiDAR (small) $44.75 TFMini-Micro LiDAR Module (12m)
Pi400 $82.25 Pi 400 in Keyboard
1000uF cap $ 0.18 16V Electrolytic Capacitor (5)
100uF cap $ 0.02 63V Electrolytic Capacitor (50)
1uF cap $ 0.05 50V Electrolytic Capacitor (20)
.01uF cap $ 0.04 multi-layer Capacitor (25)
82pF cap $ 0.02 multi-layer Capacitor (50)
10K 1/4W res $ 0.01 Resistor 0.25W 5% 10K (50)
1K 1/4W $ 0.01 resistor (50)
220R 1/4W $ 0.01 resistor (50)
330R 1/4W $ 0.01 resistor (50)
3K3 1/4W $ 0.01 resistor (50)
2N2222 $ 0.10 NPN transistor (10)
2N3904 $ 0.15 NPN transistor (10)
2N3905 $ 0.15 PNP transistor (10)
Diodes $ 0.05 (Silicon) Diodes (10)
Germ Diodes $ 0.30 Germanium Diodes (4)
LED Kit $ 2.50 5mm/3mm LED Kit Box 5 colors (125 pcs)
10K pot $ 0.45 Finger adjust potentiometer Blue (2)
16 pin socket $ 0.09 IC socket (10)
18 pin socket $ 0.10 IC socket (10)
20 pin socket $ 0.11 IC socket (10)
LM555 $ 0.25 IC (4)
LM741 $ 0.25 IC op amp (4)
74HC173N $ 0.83 IC (1)
74HC238N $ 0.58 IC (1)
SN74AHC541N 20 pin IC 8-line buffer for Pi Pico
+5V Regulator $ 0.25 Voltage Regulator (4)
+3V3 Regulator $ 0.50 Voltage Regulator (4)
2WD Car $ 4.48 Smart Robot Car Chassis
Croc Clip $ 1.63 Package of 10
120G SATA III $31.00 MakerDisk 2.5 inch with RPi OS (only)
128G uSD RPi $11.00 128GB with RPi OS (only)
120G uSD RPi $24.00 120GB with RPi OS (only)
32G uSD RPi $11.00 120GB with RPi OS (only)
?G NOOBS SD $ 9.00 with Preloaded NOOBS for RPi
5MP Camera $10.00 5MP Camera Board for Raspberry Pi
camera cable $ 1.98 RPi Zero/W/WH Camera cable 15cm
5MP Night Cam $14.63 OOS 5MP Night Vision Camera w IR lamp
Flex Bend 2.2" $14.38 Flexible Bend Sensor 2.2 inches long
LDR (small) $ 0.10 Photo Cell (20)
1 CH relay $ 0.88 1CH Active H/L 5V 110V/15A Optocoupler Relay (5)
3v3 Serial LCD $ 3.25 I2C and SPI Serial Chaaaaracter 3v3 1602 LCD
H49S $ 0.03 Crystal H49S (Low Profile) 11.0592MHz (5)
ESP8266 $ 1.98 WiFi Serial Transceiver Module
ESP01S $ WiFi Module for the Maker Pi Pico (2)
Sold-Iron Stand $ 2.00 Soldering Iron Stand wo Sponge
M-M jumpers $ 1.13 65 pcs Male-Male colored jumpers 110mm-240mm
10 Terminal Blk $ 0.75 10 terminal Block (covered)
TB1512 $ 0.90 12 terminal block (covered)
Grove male $ 0.33 Grove 4 pin Buckled 20cm Cable
Grove to female $ 0.38 Grove 4 pin Buckled 20cm to female jumper
Grove on board $ 0.10 Grove 4 pin right angle through hole socket (20)
830Breadboard $ 0.98 830 hole Breadboard (5)
ADS1115 $ 3.70 OOS ADS1115-KY-053 16 bit I2C mic (4 channels) w Gain
Mini USB mic $ 3.73 Mini USB microphone (1)
40p GPIO cable $ 1.13 for RPi GPIO (f-f ?) (1)
40p GPIO ext $ 2.38 extension cable m-f (1)
Keyboard $11.25 Wireless Keyboard with Touch Pad
4 way DIP $ 0.30 DIP Switch (4 way) red (3)
6 way DIP $ 0.45 DIP Switch (6 way) red (3)
non-Cytron products
ESPprogrammer $ supplier unknown
SN74AHC541N $ not available directly from Cytron ($ 0.69 from Mouser)
KY-038 $ microphone in "37 sensor kit"
KY-053 $ 4 channel ADC Analog to Digital Converter using I2C
ADS1115 CAD$ 9.99 ADS1115-KY-053 16 bit I2C mic (4 channels) w Gain from dealextreme (Web Source 16)
ID 3492 $ 4.95 OBS Digital PDM MEMS Microphone from Adafruit https://www.adafruit.com/product/3492
SPH0645 CAD$ 9.99 Super tiny dual MEMS I2S mic board from Adafruit
SPW2430 CAD$ 6.99 Super tiny single MEMS I2S mic board from Adafruit
MAX4466 CAD$ 9.99 Electret mic (non-I2S) with adjustable gain from Elmwood
MCP4131 $1.03 Variable Potentiometer IC ($1.00) from Microchip Technology
MCP4131-103E/P $0.74 Variable 10K ohm Potentiometer IC DIP from Mouser
MCP4131-104E/P $0.74 Variable 100K ohm Potentiometer IC DIP from Mouser
UA741CP $0.69 TI Op Amp (from Mouser)
TLV6741DCKT $1.32 TI Op Amp (5 pin) (from Mouser) VCC:2.25v-5.5v (not available in DIP format)
OBS: Obsolete
OOS: Out Of Stock
Thonny/Python/MicroPython Software Sources (Most by Cytron)
A very simple video reviews the Pi Pico at Video Source 01 by "#garyexplains" below. It shows how to set up the Pi Pico and how to run a few simple MicroPython software routines on the Pi Pico.
The value of the optional internal pull-up or pull-down resistors on each Pi GPIO pin is approximately 50K ohms for the Raspberry Pi. Each of these resistors is approximately 10K on the Pi Pico GP pins.
For more serious sensor and control programs, Cytron provides the following Tutorials in Sources 02 to 06. Web Source 01 is another article by the webmaster (D@CC). The article in Web Source 01 provides some very simple software for the Pi Pico. The routines in Web Source 01 have been tested by the webmaster of this article, David at ColeCanada.com .
Source 01 Article 161 by David Cole
http://ephotocaption.com/a/161/161.html
Source 02: Cytron Play MP3 file on MPP (It plays an mp3 when GP20 is pressed)
https://tutorial.cytron.io/2021/04/13/play-mp3-file-on-maker-pi-pico-using-circuitpython/
Source 03: Cytron write & read data to SD card
https://tutorial.cytron.io/2021/02/02/write-read-data-to-sd-card-using-maker-pi-pico-and-circuitpython/
Source 04: Cytron REPL in MicroPython (eg1: Blink the pico LED Eg2: read phys. pin 39 )
https://tutorial.cytron.io/2021/01/19/learn-microcontroller-code-easier-with-micropython-repl/
Source 05: Cytron Adding ESP32 as WiFi co-processor for Raspberry Pi Pico
https://tutorial.cytron.io/2021/05/18/esp32-as-wifi-co-processor-for-raspberry-pi-pico/
Source 06: Cytron Write Text to LCD (Serial 3v3 1602 LCD) via I2C from a Pi Pico
https://tutorial.cytron.io/2021/04/03/3-3v-serial-lcd-with-raspberry-pi-pico-via-spi-or-i2c/
Source 07: Cytron Sensor Readers eg Flex Sensor
https://tutorial.cytron.io/2012/08/10/method-to-interface-and-use-flexibend-sensor/
Other sensors with software provided by Cytron are: RID, Infra-red, ultrasonic and LiDAR.
/MakerPiPico_Pins.txt D4CC C~
Simple Python pyPlot program: testPlot
The simple program, written in Python, shown below provides a very simple plot of 60 samples.
It runs well on the Raspberry Pi. It has not yet been tested on the Pi Pico which usually has no monitor.
This program can be adjusted as needed. It can be used to display the readings taken by the
Analog To Digital Converter (ADC) provided by the Pi Pico. Its input is a simple list of wave
samples called a "vector" as defined in Python. This program is NOT directly connected to
any pins, neither on the Pi nor on the Pico. A simple square wave vector is shown below:
vector=[
10,10,10,10,10,
1 , 1 , 1 , 1 , 1,
]
A few rules apply to the wave vector used by testPlot .py:
wave-samples for pyPlot .py
The samples are stored in a Python list named "vector".
Each of the samples must be a number between 1 and 24.
The number of samples must be 60
The maximum number of samples can be modified to be 6000.
The time (in seconds) of the first and last sample must be provided.
The sample frequency is presumed to be 1 sample/sec
testPlot.py 01
(not yet complete)
-- end of testPlot.py program 01
A sample plot (of one cycle of a square wave) generated by the pyPlot .py program [but yet uncoded] is shown below. Version 0.1 of the pyPlot .py program
expects 60 samples (or less) with a sample value range of [1:24], a sampleFreq of 1 and a sampleRate of 1/sec defined by tBeg and tEnd measured in seconds: 1, 60.
Note that the background is composed of dots and the samples are plotted as asterisks. Also 100 has been
added to the values plotted; so that the length of each value written along the vertical axis is always 3 digits wide. The timescale is shown;
presuming that the sample readings are taken once per second. If further sampling (e.g. 600 samples) is added to the program; you should display 1 in every
10 samples. When reducing the precision, the timeScale must be adjusted accordingly.
Function Generator for the Pi Pico
The following MicroPython program generates a sine wave (shown in the photo after the code) using the Pi Pico. It reads a potentiometer on GP26 (to adjust the frequency).
It outputs the wave form on GP22. Outputting to GP18 (with a m-m jumper from GP22 to GP18) results in a continuous audio signal to the audio jack on the Maker Pi Pico board. This signal can be sent to the Buzzer by turning the buzzer switch ON The wave format is generated using a list of sample values (in a vector as described above for pyPlot .py). The range of the sample values is (-1,256). What could be simpler? See Web Source 11 for more info.
The recurring wave form (or cycle) shown above is a sine wave. It can be displayed on an oscilloscope if one is available. It is important to specify which part of the wave form is used to trigger the "display" and also to specify the time interval shown in the photo. In the photo above, the trigger is being done at the top of the wave and the time interval shown is approximately 6.2 msec. The time interval of one complete cycle of the wave form is called the "cycle time" or "period" of the wave form. The cycle time of the sine wave shown is 1.99 msec (listed as the "period"). The number of cycles per second of a recurring wave form is called the frequency. The frequency illustrated is 502 Hz; 1 Hz being 1 cycle/sec. The trigger value is the value of the waveform that is equal to the point on the wave where the value is the sin. The value of sin(0) = 0.000. The value of sin("near the top") = sin(89 degrees) = 0.9999. The value of sin("near the bottom") = sin( -269 degrees) = minus 0.9999. So, in the display shown above, the trigger value used is approximately 0.9999. A trigger value of minus 0.9999 would reposition the sine wave further to the left, starting at the bottom of the wave. When plotting or displaying a waveform, the trigger value and the time interval to be displayed must be specified and/or adjusted. A future plan is to add an LCD screen such as the ST7735 or any I2C screen to the MakPiADC adapter, perhaps on the end of a cable. This type of small screen could add a display to the Pico (to be used as a small oscilloscope).
Meaning of "count_freq=10_000_000" for PWM
In Web Source 12, ShawnHymel writes the following code snippet (including Pi Pico PIO code) with the comments.
# Create PIOPWM object used to fade LED
# (state machine 0, pin 25, max PWM count of 65535, PWM freq of 10 MHz)
pwm = PIOPWM(0, 25, max_count=(256 ** 2) - 1, count_freq=10_000_000)
Here, we import the PIOPWM class that we made in the piopwm module. We can use it to start a PIO instance that handles pulse width modulation (PWM) for us!
Elsewhere, about his LED fader program, he also writes:
If we set the clock divider so the state machine operates at 2 kHz, that means we will flash the LED at a 2 kHz / 200 = 10 Hz rate.
In the main part of the program, we create a StateMachine object from the rp2 module. The first parameter is the state machine we wish to use. State machines 0 through 3 are in PIO 0, and state machines 4 through 7 are in PIO 1. So, you must choose a number between 0 and 7 for this parameter. Next, we set the desired frequency (between 2000 and 125_000_000 for the Pico) followed by the pin we wish to use.
Nice words, but I still don't know the exact meaning of "10_000_000". Does it set the state machine's clock frequency to 10 MegaHz?
USB Microphone for the Pi Pico
Web Source 13 shows how to make a USB microphone for the Pi Pico. (Web Source 15 shows how to do it on the Pi.) It requires a digital microphone such as the PDM MEMS from
Adafruit (listed above). The article in Web Source 13 uses the I2S (not I2C) peripheral interface protocol. It requires no special software code, but only the download of existing software
modules. Only two signal pins need to be connected from the PDM MEMS to the Pi Pico. The output from this USB microphone can be recorded on the Pi using any software such
as Audacity. Audacity will be running on a laptop or a Raspberry Pi. Adafruit sells a new mono board and a new dual left/right board. Adafruit no longer supports this
PDM MEMS board.
PDM Raspberry MEMS Pi Pico
3V 3V3
GND GND
SEL GND
DAT GP22 data
CLK GP03 clock
The source of the audio signal is, of course, the tiny microphone on the PDM MEMS board, by Adafruit illustrated earlier.
GitHub Software for the Maker Pi Pico by Cytron
The following routtines can be found (as of 2021EMay24) at GitHub; full access requires a free membership at and experience
with GitHub. The author of this web-page has not experimented with most of the routines listed below.
I2C OLED Edit comments 2 months ago
LCD I2C Update LCD_I2C.py last month
LCD SPI Update LCD_SPI.py last month
Line Follow Update motor_driver.py last month
Melody Mario Added product and product page 4 months ago
MelodyDoraemon Play Doraemon melody on Maker Pi Pico 4 months ago
Motor Driver Added product and product page 4 months ago
maker-pi-pico-analogread.py Added comments 4 months ago
maker-pi-pico-blinking.py Update maker-pi-pico-blinking.py 4 months ago
maker-pi-pico-button-controlled-LED.py Update maker-pi-pico-button-controlled-LED.py 4 months ago
maker-pi-pico-led-fade.py Update maker-pi-pico-led-fade.py 4 months ago
maker-pi-pico-read-ultrasonic.py Update maker-pi-pico-read-ultrasonic.py last month
maker-pi-pico-rgb-led.py 03 Edited comment 4 months ago
maker-pi-pico-running-light.py Update maker-pi-pico-running-light.py 4 months ago
maker-pi-pico-ultrasound-hcsr04.py Update maker-pi-pico-ultrasound-hcsr04.py 2 months ago
pico-servo-control.py Update pico-servo-control.py last month
None of the above programs have yet been reviewed by this webmaster.
picoButton_pico.py
The MicroPython pico program shown below continuously reads push-button GP22 on the Maker Pi Pico.
It prints out the state of the button: 1 is up [high voltage], 0 is down [low voltage].
This is called an "Active Low" button. The GP22 button is normally high.
When it is pressed down, it is activated. To active GP22 on the pico (without the Maker Pi Pico's GP22 push
button), use a male-male jumper to connect GP22 to GND.
picoButton_pico.py 03
-- end of picoButton_pico.py
deviceReset_pico.py 04
This program will reset any or all devices on the Maker Pi Pico. Code can also be added
to reset other devices that are connected via the Grove connectors.
-- end of deviceReset_pico.py
maker-pi-pico-rgb-led_pico.py 05
This MicroPython program for the pico activates the RGB led on the Maker Pi Pico.
-- end of maker-pi-pico-rgb-led_pico.py program 05
Library of pico Python Routines: IX_libr_pico.py
as of 2021FJun06 (work in progress)
The webmaster plans to create a comprehensive software library of routines for the Pi Pico and the Maker Pi Pico. From time to time the author will add callable functions to this library. It is
the intention of the author to write a separate article describing each of the routines in this library. See Article 215 for a list of all routines.
IX_libr_pico.py 06
-- end of PiIX.py program in 06
strToComplex.py Function
Why do we need to use Complex numbers? When samples are recorded, they should be recorded at regular time
intervals. When this is not possible, the time should be noted for each sample that is recorded. Ideally both the
sample and the time should be recorded as a couple or pair of numbers. To facilitate this, the author chooses
to record the sample and the time as a complex number with the time being the imaginary part of the complex
number. If the sample times are not needed, the list (i.e. the vector) of samples can be derived from the real
number portion of each complex number. The function permits the Pi Pico to create each
complex number from a string which is in the format of sample+timej. The time preceding the "j" will be
put in the imaginary part of the complex number. For example, a sample of 63507 taken at unix time
1622428309 can be put in a text string "63507+1622428309j" which is converted by the Raspberry Pi into
the equivalent complex number. Note that the lowest non-zero value returned from the Pico ADC is
16000. Raw ADC samples and UnixTime (both multiplied by 1000), are stored as a complex string. The lowest
ADC value will appear as 16000000 (after being multipled by 1000). To get the actual value read from the
ADC in u12 format x1000), merely divide by 16000000 (which is 16 million). Python ver 3 for the Pi and
MicroPython for the Pico can both handle complex numbers, but MicroPython uses less precision. I call
this the "k-Complex" format when it contains sample and UnixTime (both multiplied by 1000). Usually it is
displayed in base 10. To Python, a simple complex number appears as follows: "23+4j". Technicians might
prefer complex numbers that have an "i" instead of a "j", but for some reason Python always uses a "j".
While being currently limited to integers, the values of each reading and each time should be
multiplied by 1000. Internally, this format is called "k-Complex" meaning multiplied by 1000.
Doing this will permit the final values to be expressed in millivolts and milliseconds
when retrieved from the vector lists. This also provides a simple standard for data storage and transfers.
Hopefully, Python can continue to handle such large integers on the Raspberry Pi..
It is the author's goal to provide high-resolution (9-digit) samples and Unix times to be used in the basic recording
of data. MicroPython does not provide a sufficient number of digits to store 9-digit numbers
in the samples. Furthermore, storing the actual times as unix dates with milliseconds necessitates
very large numbers. Consider using a pico epoch, where a
timestamp might be (uTime-1609536870 [Jan 1 2021] = 0). One year later the (pico-epoch) time
would be a very large number: 31476330 (in seconds). It grows very rapidly. The recording of time-stamps for readings
is difficult unless the start time is made relative to a known time close to the actual time when the
readings were taken. I suggest that the sample&time (as complex integers) vector be assigned a filename
similar to "vrci2021AJan13-23:05:02" where the date/time of the first sample is contained in the name
of the vector. In fact the whole unix time-stamp (as a long integer) could be stored in the name e.g. "vrci1609536870".
The "ci" in the name would indicate that both the sample and the time values are stored as a single "complex integer".
The whole vector could be stored as a CSV (Comma Separated Values) file or as a JSON file.
Using this convention, the sample vector name could be "vrci1609536870.csv". When non-integer samples are used
this would be named the "VRC" sample data storage convention, pronounced "vrick". The "VRC" means the
"Vector Readings Complex" format. This convention could be the VRC format meaning
"Vector Readings as Complex numbers" pronounced "vrick". Both the real and the imaginary part of the
complex number can contain a period followed by the fractionary part of the reading. These would not
be integer numbers so the prefix should be "vrc" instead of "vrci".
It is possible to facilitate the creation of the VRC numbers by the Pico. In Python either the real or imaginary part of each
VRC sample should be permitted to be expressed in hexadecimal format. An acceptable number in the VRC
format would be (0x4000.200+1609536870.300j) which would express a voltage reading in mVolts and the
time in seconds and msec since the Unix epoch. A valid vector of 3 of the most simple numbers (in VRC format)
would be [2, 2, 2, 2, 0, 0, 0, 0]. This is a square wave with a peak-peak voltage of 2 that does not include any
sample times. This vector could be assigned the name "vrc1609536870" indicating that the first sample was
taken at Unix Time of 1609536870. It could be presumed that the sample rate is 1 msec, when unstated. Alternatively
the sample rate can be included as a suffix in the name preceded by a "_". This suffix should be the reciprocal of
the sample rate. A sample rate of once every 1 microsecond would require a suffix of "_1000000". A sample rate of
once every millisecond would require a suffix of "_1000". The VRC name previously cited also designating a sample rate
of once every 1 microsecond would be "vrc1609536870_1000000.csv" if the samples were in Comma Separated Values.
The VRC is "My Recommended Format" for ADC Reading Samples. Furthermore, the Pi Pico (with 8 bit precision
today) could easily record each sample in a VRC format where the real part of the reading is represented
in hexadecimal and the optional imaginary (time) stored in either unix epoch time (including msec) or
simple elapsed seconds in either decimal or hexadecimal.
CUP3: An IXcomplex variant of the RUPasc Vector (with 3 "header readings")
As of 2023EMay02, a slight variant of the RUPasc format is described in Article 193 (Source 38 ). This new variant is
called the IXcomplex CUP3 format of a Python list of readings. In a IXcomplex Vector named CUP3, 3 complex numbers are placed as 3 header entries in each list. They are marked as header entries by having a "" (a null string) value as the real portion of the third and last header entry in the list. Using a null reading as the last "header reading" permits additional header "readings" to be added (more than 3) in the future. This null header entry should trigger an error when arithmetic is performed on the readings. This error (and perhaps errors in the first 2 readings) permit these two entries to be recognized as header entries. The imaginary part of the first and second "header readings" is not defined. The real part of the first "header reading" defines "dt", the time between readings, or is 0. If non-zero, it is "dt", the time between readings. The numerical value of the imaginary part of any actual defines the interval between readings as a decimal fraction which has a period in it. If the value of the first "header reading" is "0.001+0j" or "0.001", the time interval between readings is 0.001 seconds. This indicates a 1 millisecond interval between samples. In a similar fashion, the second "header reading" is the Unix time stamp of the
first reading of the subsequent readings. The most complex format of the CUP3 readings vector is where the first two readings are defined as described in the prior sentences, but each subsequent reading is a complex number where the imaginary portion of each reading is the Unix time of the reading. If the time intervals between readings is known to be not constant then (dt=0) and the non-heading readings must be complex numbers.
On a Raspberry Pico, it is often difficult (or impossible) to set the correct Unix time or any time in the pico clock. If this is the case, the correct Unix time will not be in the second "header reading". The second "header reading" might be zero or it might just be the current value of the pico clock. If the first "header reading" is non-zero, it will indicate the time between readings and therefor the imaginary part of each reading can be zero or omitted. If both of the two "header records" and there are no imaginary portions in each reading, then the time interval between readings cannot be deduced from the data in the CUP3 vector. If each reading has a non-zero imaginary part, then these "time of reading" should be considered valid and any "dt" in the first "header reading" should be ignored. These imaginary readings might be unix times or "time of reading" of a clock started one interval before the first reading was recorded. Similarly, if each reading has a Unix time, then the value of the second "header reading" should be considered to be the unix time one interval before the time of the first actual reading. If a null real number appears in the vector, then all readings that precede the first null are "header readings" and all reading following it are "normal actual readings". It is possible that one or more of the subsequent readings might also be null. If no null reading exists in the vector, all readings in the vector are "normal actual readings" and there are no "header readings". If a vector of readings has no "header readings" and no imaginary portions, then the time interval between readings is either unknown or must be determined some other way, perhaps by asking the operator who measured the readings. If one of the first three actual readings is null, then (""+0j) should be the first record and it should be considered the null record that marks the end of the "header readings". Of course, this is an invalid complex number because its real part is a string, not a number.
The simplest (quickest and most efficient) valid CUP3 vector format has "3 header readings", no "dt" defined and the unix time of the beginning of the vector readings in the second "header reading" followed by a null reading of "". Each subsequent actual reading will have the pico clock reading as the imaginary part. The easiest way for the pico to record a measured reading (say of an ADC) is to record the actual U12 or U16 bits without doing any arithmetic conversions. The easiest way to record a U12 or U16 reading is to store it in octal (eg 0o177) or hexadecimal (eg 0x3ff). The quickest vector that can be created is if all the readings are taken at constant intervals. In this case, the fastest vector should be recorded with every reading at equal intervals and the hexadecimal value of each reading stored in memory. After all the readings are complete, the vector can be created containing the time interval , the unix time, the null reading and followed by all of the readings.
If the IXcomplex CUPasc first header record has a non-zero imaginary part, it is the regular time interval between recorded samples. The second header record will still hold the Unix time of the first valid complex number in the list (as in the previous IXcomplex list with headers). In this case, the subsequent complex numbers can each have a numerical imaginary part equal to "0j" because the exact Unix time can be easily calculated by the Raspberry Pi computer receiving this list of IXcomplex CUPasc samples. See Source 38 for more information and for other special header definitions for IXcomplex sample lists.
Recommended VRC Vector Name for ADC Samples in CSV format
An example of a recommended vector name for ADC samples taken at regular intervals in CSV (Comma Separated Values) format would be:
"vrc1609536870_1000000.csv"
This vector contains only data, the Unix time and the frequency (1/period) of the readings is stored as part
of the vector name. The frequency is stored instead of the time interval to avoid periods and abbreviations in the name.
Citing an integer as the reciprocal of the sample rate precludes sample rates lower than once per second. Such slow
sample rates do not produce voluminous data files. Therefore the UNIX time stamp can be included for each reading
as the absolute value of the imaginary part of the reading. Such files would not have a suffix beginning with "_" as
part of the name.
This type of vector can be easily produced by a Raspberry Pi Pico using the MMBasic software. On the Raspberry Pi Pico,
MMBasic is probably slightly superior to Python because it can do arithmetic on longer integers with higher
resolution. [This is presumed, but has not yet been proven by the author.] MMBasic is suggested because the author
knows how to write files to a uSD drive using MMBASIC. Doing this with MicroPython or CircuitPython might be more problematic.
It is interesting to note that a Raspberry Pi Pico running MMBasic can
record such vectors to a micro SDcard plugged into a Maker Pi Pico board. Such micro SDcards can hold 32 GB of
data (and perhaps more). For more information about MMBasic see Article 166 in Web Source 37.
the IX f3() format function
Most programmers will appreciate using the f3() function to print columns of numbers with 12 characters in each
column. This allows for 11 characters for the number and 1 separator character. There is a tidier version of f3()
called f3_9() that does the same processing but produces only 9 characters in each column with no characters between
columns. The author prefers to use f3_9(). The "3" means 3 significant digits to the right of the decimal point.
The function "f3()" is used when formatting numbers for printout. It formats all real parts of
numerical readings as -999999.999 so that the decimal points will always "line up" in a report.
In the cases of bigger or smaller (very tiny) numbers, the scientific format will be used eg. -1.2347531 x 10^-7", which
is expressed in Pyton using f3() as "-1.23465E-7 ". This is the same width as -999999.999 but the inclusion of the
"E-7 " was done by removing the lower 3 significant digits and allowing the decimal point to be
moved "out of alignment". Higher numbers than E+7 can be printed by using the extra space on the right
for double digit powers of 10 in the scientific notation. Big complex numbers cannot be formatted into
12 characters eg (-12345.6-1.23465E-78j), so they are formatted "as is". Furthermore programming is simplified
for these readings by obviating the
need for special formatting code, which can be cumbersome in today's Python (as of 2021FJun11). If the time is
included as the complex part of the reading, it also will be be included in format f3(). When unix times
are used, the f3() expects a second parameter which is usually the numerical time of the first reading followed by
a "j". Using CUP3 format, this second parameter (relative time) can be subtracted from the beginning Unix time value,
converting unix times into elapsed time since the first reading. Then this number is placed as the imaginary part
of each reading. The following (over-simplified) Python sample code easily uses the f3() function:
print("-999999.999 +999999.999j")
print("------------ ------------")
len=sr.count()-3
uGMT=sr[1]
print(" "+dateTime(uGMT))
for k in range(3,len):
print(f3(real(sr.index(k)), f3(imaginary(sr.index(k))) ))
#end for
Using vector sr=[1, .02, -12998000, 5.9,8000,16] with unix time as a "header reading", the CUP3 vector format with a sample interval
of 2 seconds, would print [including the "strange" second "header reading]:
-999999.999 +999999.999j
------------ -----------
2006FJun09 @ 14:00:00.000
1.000 +0.000j
.020 +2.000j
-1.2998E+7 +4.000j
5.900 +6.000j
8000.000 +8.000j
16.000 +10.000j
Using the same CUP3 vector sr=[1, .2, -12998000, 5.9, 8000, 16 ] with non-unix times as imaginary portions with a sample interval
of 2 seconds, the simpler Python code would print a very similar (but less readable) report (without mention of unix info):
print("-999999.999 +999999.999j")
print("------------ -----------")
len=sr.count()-3
for k in range(3,len):
print(real(sr.index(k), imaginary(sr.index(k))) )
#end for
-999999.999 +999999.999j
------------ -----------
1 +0j
.02 +2j
-12998000 +4j
5.9 +6j
8000 +8j
16 +10j
If no time information were included (no imaginary component) in the vector, only the first column would be printed
(without any "+" signs) presuming that the same second code segment (above) is used. If unix times are in the samples
and no second parameter is used, the times will appear as large useless time numbers because they will be printed
in Python scientific notation. If non-unix (imaginary) times are in the data, but two parameters are given to f3(),
as in the above code, the time of the first sample will be subtracted from each time showing elapsed time (since
the first reading) for each subsequent reading.
strToComplex.py function
The software routine shown below converts any string or number (which is a complex or other number) into
a special internal format. In this internal format, the types of the data and the data in the readings (integer,
floating, boolean, complex) are in a vector which contains the data and the times of the samples.
The first letter of the result simply indicates the type of digits or characters (string, boolean, integer,
float, complex, error) that originally was used to identify the real part of the number that was derived.
In most cases, the first character can be ignored. However, the letter can be "e" which indicates
that no number could be identified and a result = e3.141 = Pi (meaning Python) was returned after
the first letter was removed. Any value that is "Pi" should be suspect, perhaps the processing
routine returned the number pi (without flagging it as an error).
strToComplex.py 10 (second instance)
-- end of strToComplex_pico.py program in 10
A Format for ADC Reading Samples
Every version of the ADC read function that is written for the Pico should be able to produce every format shown below.
The MakPiADC board sends the voltages to the Pico where the ADC hardware takes samples of the voltages. The Pico takes readings of the samples, converts them into 7-bit Ascii character strings and sends them back to the Raspberry Pi via the MakPiADC board. On the Raspberry Pi, the readings are converted into a list called a Vector. Various formats can be used to transmit the Ascii character strings into the final numbers that are stored in the Vector. In the RAW format each byte (8 bits) contains 1 bit of parity plus 0b10 plus 5 bits of data. This eliminates every ascii control character, and also eliminates the "DEL" = 0x7F. In every format, a comma is sent after every sample (even after the last sample). In the recommended format (RUPasc), the sample is in raw hex format and the unix time is in raw decimal format and allows for extra non-significant digits to the right of the Period (the decimal point). The maximum reading from the RP2040 pico's ADC (today as of 2021FJun07) is 4096 quantization levels which is 0x1000 in hex. But Raspberry developers recommend that current software be designed to work with a quantization level of u16 = 65536 (in decimal) which is 0x10000 . The maximum reading today is 0x1000 (in u12) which is 0x10000 in U16 (which is 65536 in decimal). This same reading (the maximum reading on today's RP2040) is shown in every example below. (This is equal to 4096*16 =65536.) The different formats with an example (of the exact same sample reading in each) are:
RAW: U16 in 4 bytes [0b10+the lower 5 of 8 bits/byte are actual data] (to prevent sending neither ascii control characters nor DEL)
Note that parity bits are optional, presuming that the parity is on the left (not that it matters much here.)
In the data below, the parity bits are shown as being always 0.
eg "B@@@," (which is 0x42 0x40 0x40 0x40 0x2c) because 0x10000 = 0b10,00000,00000,00000 (commas inserted for clarity)
ADC: ADC Samples in the raw U12 (converted to U16 for the RP2040) as printed by Python in hex in an ascii character string followed by a comma
eg "0x10000,"
RDasc: Reading (Decimal) in ascii
eg "65536.000,"
RRasc: Redundant Reading(s) s(octal), s(hex) s*2(hex) separated by semicolons in ascii
eg "(0o200000; 0x10000; 0x20000),"
RDSasc: Reading (in Decimal) plus a Non-Unix Time (s in actual Decimal with t in Seconds) in ascii.
eg "(65536.000+0.000j),"
RUasc: Reading plus Unix Time (all in Integers) in ascii.
eg "(0x10000+1621625066j),"
RUPasc: Reading plus Unix Time (with Periods) in ascii.
eg "(0x10000.000+1621625066.713j),"
CUPasc: Reading plus Unix Time (with Periods) in ascii.
(preceded by 3 header control records)
eg "(0x10000.000+1621625066.713j),"
Comparison of the Various Formats
Recommended: RUPasc (~30 bytes/sample)
RUPasc includes the actual (Unix) time of each sample (not just "presumed" to be at regular intervals)
It requires Periods (showing where the decimal point is meant to be).
Only at very very high sampling rates, the following Most Efficient (RAW) format should be used
Most efficient: RAW (5 bytes/sample) with a comma between each sample.
The most efficient is the RAW format which requires 4 bytes/sample plus a comma.
In the RAW format 4 characters are sent per sample (5 of 8 bits/byte are actual data which allows for 20
bits to hold 16 bits of actual data today and to allow four more bits of higher order data in the future)
By sending only 5 bits/byte (in the lower order 5 bits), it prevents sending control characters (and prevents sending
DEL) in non-noisy (clear) transmissions.
Noisy Environments: RRasc (40 bytes/sample but time info is not sent)
This format is a redundant format that sends each reading three times (but using different bases or variants). The intention is to eliminate the need to request retransmission of erroneous data in a very noisy environment. The ascii characters appearing in each of the three numbers are often different. The first two numbers are the same number first in octal, then in hexadecimal. The third number is two times the value of the first two but in hexadecimal format. Most readings, when appearing in this third number will be quite different from the second number. For example, if the second number in hexadecimal is 0x04025, then the third number will be 0x0824A. This third number can be generated very simply by a simple single bit shift to the left. By using redundancy instead of using parity, the number is sent three times, hopefully, two of these three numbers will indicate a reading of the same numerical value. An example of a reading in this RRasc format is shown below:
eg "(0o0040445; 0x04025; 0x0824A),"
Human Readable (testing) Format: RDSasc (20 bytes/sample converted to decimal in the Pico, with Non-Unix time in Seconds).
Three digits to the right of the decimal point, provide acceptable resolution in most cases:
eg "(65536.000+0.000j),"
The only question is whether any information is lost when a u16 reading is converted to decimal by the Pico
Adding Redundancy to the Ascii Sample Vectors
When the Pico reads the ADC samples and sends the resulting readings to the Pi, the occasional error might occur due to noise in the serial data line.
The normal solution to this type of issue is to use "Ack" and "Nack" to request retransmission, as is done on the Internet. Another solution is to add
some redundancy to each record containing a sample. One way of providng redundancy is to send each value three times (in octal, and 2 hexadecimal
formats, the second one being twice the value of its predecessor). Decimal is avoided to not tax the Pico's shabby arithmetic processor. The same
number is presented in each format. If one is wrong, the other two should be identical. Such redundancy permits error-correcting by the
receiving program. That is the mechanism that will be used by the software for the MakPiADC adapter.
The Pico's Low-Res issue: testUtime.py program
The data resolution of the Pi Pico processor and MicroPython language is only 7 significant decimal digits which doesn't permit fast arithmetic on the Unix time. It can also cause loss of data for the readings taken by the Pico. The testUtime_pico.py program demonstrates this issue. To manipulate hi-res data
on the Pi Pico, it must be kept in strings. The strToComplex program manipulates the readings and the unix time as strings, with no loss of accuracy. They are stored in a "hi-res" string format (such as the RUPasc format) that can be transferred to the Raspberry Pi. The Raspberry Pi has no difficulty reading them as hi-res integers within complex numbers. Without these routines, the precision of the numbers in the pico can be reduced.
testUtime.py program in 11
-- end of testUtime_pi.py program in 11
test_piButton_pi.py program in 12
This program tests the piButton (usually on GPIO22). A piButton could have
been designed into all models of the Raspberry Pi. This is a non-mechanical push button.
It senses the ambient light. Because the Raspberry Pi can only sense on and off,
it senses whether or not light is being detected by the photocell which is the
piButton. To "push" the piButton, simply touch the CDS photo-cell with your finger.
The piButton routine should constantly be sensing the photocell, to be able to detect
the "push of the piButton". An improved version of the piButton routine would use
interrupts to liberate the processor.