Read a pin correctly before trusting a sensor demo

A block menu can make every pin look interchangeable. They are not. If you are moving a working experiment onto a different board or carrier, the first task is to match the program's signal to the actual connection.

We ran the GPIO, ADC and PWM blocks of the BIPES editor on a Raspberry Pi Pico mounted on a GraftPort carrier, and kept both the blocks and the generated MicroPython. That pairing exposed several details a friendly label hides. The selected pin, its electrical mode and the connected module all need to describe the same circuit.

Separate a signal from the load it controls

The first check set GPIO25 high to light the Pico's onboard indicator. High and low describe voltage states. They do not universally mean on and off: some interfaces are active-low. A GPIO supplies a control signal with limited current capability; motors and other loads need a separate driver.

The digital-read check deserves a closer look. Setting "pull-up" to false in the block generated PULL_DOWN, rather than leaving the input floating. The generated code then set the same pin as an output and read it. The printed 1 was therefore not evidence from an independently wired button; it was the program reading back its own output.

For an external switch, choose the input mode from the circuit and establish the inactive and active readings on the real hardware. Do not reuse the LED pin from a menu example as a general sensor input.

A raw ADC value needs a source and a scale

An ADC converts an input voltage to a number. Our check printed 32856 from ADC(29).read_u16(). The block labeled this an internal temperature input. On a standard Pico, though, GP29 is connected to VSYS through board circuitry, and the internal temperature sensor is a different ADC channel. That number is a supply-related reading and must not be presented as a temperature.

from machine import ADC

raw = ADC(29).read_u16()   # 0-65535 scale; on a standard Pico this is VSYS via a divider
print(raw)

The MicroPython RP2 quick reference distinguishes the 12-bit converter from the 0 to 65535 scale returned by read_u16. More printed digits do not mean a 16-bit physical measurement. For a slider or analog module, identify the voltage range and the intended conversion before assigning a physical unit.

PWM specifies a waveform

The PWM comparison held frequency at 1000 Hz and changed the duty value from 2000 to 60000. On the 16-bit duty scale, those are about 3.1% and 91.6% high time. The LED looked dimmer at the low value and brighter at the high value. That is a qualitative difference seen by eye and camera, not a calibrated luminance measurement.

Frequency and duty serve different purposes, and their effect depends on the driver and the load. Some RP2040 outputs share PWM hardware, so two pins may not be independently configurable. Deinitializing PWM also needs an intentional inactive state for whatever is attached. And a PWM reference number in a program should not be mistaken for a physical pin or a hardware slice number.

Interrupts have limits too

An interrupt responds to a selected input edge. It helps when polling is unsuitable, but the handler still uses processing time and has restrictions. Keep handlers short, and do not assume every pulse will be captured just because the block is called "interrupt." Test with the fastest real input you expect.

Before moving to a new board

When a working module example moves to a new carrier or a custom PCB, check these points against the schematic rather than the menu:

Record those answers with the program. They are the information a board designer needs, and they prevent a demo that only worked because of one carrier's wiring.