Raspberry-Pi-Pico (RP2040)
Raspberry-Pi-Pico-W (RP2040)
Raspberry-Pi-Pico2 (RP2350)
Raspberry-Pi-Pico2-W (RP2350)
Processor | RAM | Flash | Cores | Clock speed |
---|---|---|---|---|
RP2040 | 264KB | 2MB | 2x ARM Cortex-M0+ | 133MHz |
RP2350 | 520KB | 4MB | 2x ARM Cortex-M33 | 150MHz |
MicroPython (MPy) and CircuitPython (CPy) are closely related.
The Adafruit company is sponsoring CPy, which is a derivative of MPy.
“NeoPixel” is a term created by Adafruit for “smart” RGB-LEDs.
They are usually based on WS2812B chips.
See the “NeoPixel ÜberGuide” for a detailed explanation.
All resources can be be downloaded from the assets
directory, as well.
… from Adafruit’s CircuitPython “store” at https://circuitpython.org/down…
… or from the assets
directory.
Read the installation notes in the Adafruit learn guide.
Solder a 3-wire cable to pins 34, 38, and 40 of your “Pico” board.
The other end of this cable has a plug, which fits to the NeoPixel matrix.
Detailed view of “Pico-W” boards with NeoPixel cables.
What | Price |
---|---|
Pico board | 5-10 € |
USB cable | 5 € |
16x16 NeoPixel matrix | 25-30 € |
3 pin Data cable | included with matrix |
Sub total | approx. 40 € |
IKEA frame | 10 € |
acrylic diffusor | 10 € |
Grand total | < 60€ |
If you are new to programming with Python then you might have a look at the “Welcome To CircuitPython” guide by Adafruit. The chapter “How do I learn Python?” has links to guides for every level of experience.
Another guide “Getting Started with Raspberry Pi Pico and CircuitPython” is dedicated to programming “Pico” boards with CPy. The chapter “NeoPixel LEDs” is very helpful for this workshop.
These guides can also be downloaded from the assets
directory.
Python does not use any explicit syntactic brackets ( like begin
and end
, or {
and }
) to delimit compound statements.
That’s why indentation (usually by 4 spaces) is used to group statements.
Python does have most of the usual control structures.
But you need to terminate the ’test’ with a colon :
.
1# IF statement
2if (a == b):
3 x = y
4elif (b == c):
5 x = z
6else:
7 z = x +y
8
9# WHILE statement
10i = 0
11while (i < 10):
12 i += 1
13
14# FOR statement
15for j in range(10):
16 print(j)
The same is true for function definitions.
Put the name and all parameters onto the first line and terminate the line with a colon :
.
Then you need to indent all statements of the function body.
The function definitions ends, when you outdent to the level of the def
keyword.
1# Function defintion
2def fname(x, y, z):
3 return x * y * z
4
5print( fname(2, 3, 5) )
Python does have all the usual data types, like integers, floats and strings.
Some conversions are done implicitly. Others need to be carried out explicitly by calling a function.
1a, b = 5, 7
2x, y = 9.7, 6.5
3z = float( a + b )
4c = int( x / y )
5s = "my "
6t = " know"
7r = "ledge"
8print(z, c, s+t+r)
The basic data structures of Python are lists, dictionaries, and tuples:
1# LISTS have indices that are integers and can be used as ARRAYS
2# delimiters are [ and ]
3a = [ 1, 2, 3, ]
4rgb = [ 0xff, 0xcc, 0xd8 ]
5b = [ 'a', 12, 3.14, [], rgb ]
6print( a[1], b[4] )
1# DICTIONARIES are similar to LISTS,
2# except the indices are strings (or any other type)
3# delimiters are { and }
4word = {}
5word['en'] = 'book'
6word['de'] = 'buch'
7word['fr'] = 'livre'
8words = { 'one': 'eins', 'two': 'due', 'three': 'trois', }
1# TUPLES are an immutable sequence of values
2# delimiters are ( and )
3t = ( 1, 2, 3, 4, 5 )
4print( t[2] )
All Examples can also be downloaded from the assets
directory.
1# SPDX-FileCopyrightText: 2025 Pagong
2# SPDX-License-Identifier: MIT
3
4import time
5import board
6import neopixel
7
8#######################
9
10# for Rpi-Pico with 16x16 NeoPixel-Matrix
11NUM_COLS = 16
12NUM_CELLS = 16
13NUM_PIXELS = (NUM_COLS * NUM_CELLS) # Update this to match the number of LEDs.
14
15SPEED = 0.1 # Increase to slow down the effect. Decrease to speed it up.
16BRIGHTNESS = 0.1 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
17
18PIN = board.GP28 # This is the default pin on my RPi-Pico with 16x16 NeoPixel matrix
19pixels = neopixel.NeoPixel(PIN, NUM_PIXELS, brightness=BRIGHTNESS, auto_write=False)
20
21#####################
22
23black = 0
24color = ( 0xff, 0xcc, 0xd8 )
25
26while True:
27 pixels.fill(black)
28 pixels.show()
29 time.sleep(5*SPEED)
30
31 pixels.fill(color)
32 pixels.show()
33 time.sleep(SPEED)
1# SPDX-FileCopyrightText: 2025 Pagong
2# SPDX-License-Identifier: MIT
3
4import time
5import board
6import neopixel
7import rainbowio
8
9#######################
10
11# for Rpi-Pico with 16x16 NeoPixel-Matrix
12NUM_COLS = 16
13NUM_CELLS = 16
14NUM_PIXELS = (NUM_COLS * NUM_CELLS) # Update this to match the number of LEDs.
15
16SPEED = 0.01 # Increase to slow down the effect. Decrease to speed it up.
17BRIGHTNESS = 0.1 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
18
19PIN = board.GP28 # This is the default pin on my RPi-Pico with 16x16 NeoPixel matrix
20pixels = neopixel.NeoPixel(PIN, NUM_PIXELS, brightness=BRIGHTNESS, auto_write=False)
21
22#####################
23
24black = 0
25
26while True:
27 pixels.fill(black)
28 pixels.show()
29 time.sleep(50*SPEED)
30
31 for i in range(NUM_PIXELS):
32 for j in range(NUM_PIXELS):
33 color = rainbowio.colorwheel(i+j)
34 pixels[j] = color
35 pixels.show()
36 time.sleep(SPEED)
1# SPDX-FileCopyrightText: 2025 Pagong
2# SPDX-License-Identifier: MIT
3
4import time
5import board
6import neopixel
7import math
8
9#######################
10
11# for Rpi-Pico with 16x16 NeoPixel-Matrix
12NUM_COLS = 16
13NUM_CELLS = 16
14NUM_PIXELS = (NUM_COLS * NUM_CELLS) # Update this to match the number of LEDs.
15
16SPEED = 0.2 # Increase to slow down the effect. Decrease to speed it up.
17BRIGHTNESS = 0.1 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
18
19PIN = board.GP28 # This is the default pin on my RPi-Pico with 16x16 NeoPixel matrix
20pixels = neopixel.NeoPixel(PIN, NUM_PIXELS, brightness=BRIGHTNESS, auto_write=False)
21
22#####################
23
24def lerp(begin, end, t):
25 return begin + t*(end-begin)
26
27def hsv2rgb(h, s, v):
28 g = h*6.0
29 i = math.floor(g)
30 f = g - i
31
32 p = v * (1.0 - s)
33 q = v * (1.0 - s*f)
34 t = v * (1.0 - s*(1.0-f))
35
36 r, g, b = [
37 (v, t, p),
38 (q, v, p),
39 (p, v, t),
40 (p, q, v),
41 (t, p, v),
42 (v, p, q),
43 ][int(i)%6]
44
45 return int(r*255), int(g*255), int(b*255)
46
47#####################
48
49hue_A = 15
50sat_A = 230
51val_min = 120.0
52
53hue_B = 95
54sat_B = 255
55val_max = 255.0
56
57palette = []
58def breathe():
59 step = 1.0 # 0.5
60 delta = (val_max - val_min) / 2.35040238
61 max_range = 128
62
63 for i in range(2*max_range):
64 dV = (math.exp(math.sin(step * i/max_range * math.pi)) - 0.36787944) * delta
65 val = val_min + dV
66 t = (val - val_min) / (val_max - val_min)
67 hue = lerp(hue_A, hue_B, t)
68 sat = lerp(sat_A, sat_B, t)
69
70 rgb = hsv2rgb(hue/255.0, sat/255.0, val/255.0)
71 #print(i, dV, val, rgb)
72 palette.append(rgb)
73
74#####################
75
76pulse = 2.5
77breathe()
78
79while True:
80 for i in range(256):
81 color = palette[int(pulse*i)&255]
82 pixels.fill(color)
83 pixels.show()
84 time.sleep(SPEED)
1# move through Sinus and Cosinus terrain
2#
3# 21 Mar 2025 - @pagong
4# Uses Raspberry-Pi Pico with a 16x16 NeoPixel LED matrix
5
6import time
7import board
8import random
9import neopixel
10import rainbowio
11
12import neomatrix
13
14#####################
15
16# for RPi-Pico with 16x16 NeoPixel-Matrix
17NUM_COLS = 16
18NUM_CELLS = 16
19
20NUM_PIXELS = (NUM_COLS * NUM_CELLS) # Update this to match the number of LEDs.
21SPEED = 0.01 # Increase to slow down the animation. Decrease to speed it up.
22BRIGHTNESS = 0.1 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
23PIN = board.GP28 # This is the default pin on RPi-Pico with 16x16 NeoPixel matrix
24
25leds = neopixel.NeoPixel(PIN, NUM_PIXELS, brightness=BRIGHTNESS,
26 pixel_order=neopixel.GRB, auto_write=False)
27
28matrixType = ( neomatrix.NEO_MATRIX_BOTTOM + neomatrix.NEO_MATRIX_LEFT +
29 neomatrix.NEO_MATRIX_ROWS + neomatrix.NEO_MATRIX_ZIGZAG )
30
31matrix = neomatrix.NeoMatrix(
32 leds,
33 NUM_COLS, NUM_CELLS,
34 1, 1,
35 matrixType,
36)
37
38grid = matrix._grid
39
40#####################
41
42# prepare rainbow palette
43palette = []
44for k in range(256):
45 palette.append(rainbowio.colorwheel(k))
46
47# change direction of movement
48def change_direction():
49 xs, ys = 0, 0
50 while (abs(xs) + abs(ys) == 0):
51 xs = random.randint(-1, 1)
52 ys = random.randint(-1, 1)
53 return float(xs), float(ys)
54
55def do_frame():
56 for i in range(NUM_COLS): # for each pixel row
57 sinx = math.sin(start_x + step*i)
58 pxl = grid[i]
59 for j in range(NUM_CELLS): # for each pixel column
60 cosy = math.cos(start_y + step*j)
61 val = 1.0 + (sinx * cosy)
62 col = int(val * 127.5) # scale it from -1 - +1 -> 0 - 255
63 pxl[j] = palette[col] # convert hue to rainbow color
64
65#####################
66
67import math
68step = (1.1 * math.pi) / float(NUM_COLS)
69start_x = 0.0
70start_y = 0.0
71
72incr = 0.1
73xsign = 0.0
74ysign = 1.0
75
76Debug = True
77
78while True:
79 t1 = time.monotonic_ns()
80 do_frame()
81 t2 = time.monotonic_ns()
82
83 grid.show()
84 t3 = time.monotonic_ns()
85
86 if Debug:
87 d1 = (t2 - t1) / 1000000.0
88 print(f"Compute {d1} ms", end=" +\t")
89 d2 = (t3 - t2) / 1000000.0
90 print(f"Display {d2} ms", end=" =\t")
91 print(f"Total {d1+d2} ms", end=" -->\t")
92 print(f"{1000.0/(d1+d2)} fps")
93
94 # move around in noise space
95 start_x += incr * xsign
96 start_y += incr * ysign
97 if (random.randint(0, 99) == 8):
98 xsign, ysign = change_direction()
99
100 time.sleep(SPEED)
1# noise_square_code.py -- playing with simplex noise in CircuitPython
2# 9 Feb 2023 - @todbot / Tod Kurt
3# https://github.com/todbot/CircuitPython_Noise
4#
5# 21 Mar 2025 - @pagong
6# Uses Raspberry-Pi Pico with a 16x16 NeoPixel matrix
7
8import time
9import board
10import random
11import neopixel
12import rainbowio
13
14import matrix16
15
16#####################
17
18# for RPi-Pico with 16x16 NeoPixel-Matrix
19BRIGHTNESS = 0.1 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
20PIN = board.GP28 # This is the default pin on RPi-Pico with 16x16 NeoPixel matrix
21matrix = matrix16.MatrixSetup(PIN, "hsquare", 1.0)
22grid = matrix._grid
23
24NUM_COLS = matrix._width
25NUM_CELLS = matrix._height
26
27NUM_PIXELS = (NUM_COLS * NUM_CELLS) # Update this to match the number of LEDs.
28SPEED = 0.01 # Increase to slow down the animation. Decrease to speed it up.
29
30#####################
31
32# use Todbot's noise module from community bundle
33import noise
34noise_scale = 0.07 # noise_scale * max(width, height) should be smaller than 1.0
35noise_incr = 0.01
36noise_x = 0.0
37noise_y = 0.0
38xsign = -1.0
39ysign = -1.0
40
41#####################
42
43# prepare rainbow palette
44def make_palette(palette, bright):
45 for hue in range(256):
46 color = rainbowio.colorwheel(hue)
47 r = int(bright * float((color >> 16) & 255))
48 g = int(bright * float((color >> 8) & 255))
49 b = int(bright * float(color & 255))
50 col = (r, g, b)
51 palette.append(col)
52
53# change direction of movement
54def change_direction():
55 xs, ys = 0, 0
56 while (abs(xs) + abs(ys) == 0):
57 xs = random.randint(-1, 1)
58 ys = random.randint(-1, 1)
59 return float(xs), float(ys)
60
61def do_frame():
62 for i in range(NUM_COLS): # for each pixel column
63 nsx = noise_x + noise_scale*i
64 pxl = grid[i]
65 for j in range(NUM_CELLS): # for each pixel row
66 # get a noise value in 2D noise space
67 n = noise.noise(nsx, noise_y + noise_scale*j)
68 c = int((n+1.0) * 127.5) # scale it from -1 - +1 -> 0 - 255
69 pxl[j] = palette[c] # convert hue to rainbow color
70
71#####################
72
73palette = []
74make_palette(palette, BRIGHTNESS)
75
76Debug = True
77
78while True:
79 t1 = time.monotonic_ns()
80 do_frame()
81 t2 = time.monotonic_ns()
82
83 grid.show()
84 t3 = time.monotonic_ns()
85
86 if Debug:
87 d1 = (t2 - t1) / 1000000.0
88 print(f"Compute {d1} ms", end=" +\t")
89 d2 = (t3 - t2) / 1000000.0
90 print(f"Display {d2} ms", end=" =\t")
91 print(f"Total {d1+d2} ms", end=" -->\t")
92 print(f"{1000.0/(d1+d2)} fps")
93
94 # move around in noise space
95 noise_x += noise_incr * xsign
96 noise_y += noise_incr * ysign
97 if (random.randint(0, 99) == 8):
98 xsign, ysign = change_direction()
99
100 time.sleep(SPEED)
see my Github account for more: https://github.com/pagong