Anfang August 24 ging die Eilmeldung durch die üblichen Kanäle, dass der Raspberry Pi Pico 2 als Nachfolger des Pico erschienen ist und spätestens bis Ende des Jahres verfügbar sein wird. Überraschenderweise konnte ich schon vor Ende August ein Exemplar käuflich erwerben. Ein Zeichen, dass die Chip-Knappheit der Vorjahre überwunden ist.

Raspberry Pi Pico 2
Die neue MCU basiert auf dem RP 2350 Prozessor von Raspberry Pi, der zwei Cortex-M33 Kerne und zwei Hazard 3 RISC-V Kerne besitzt. Die Taktfrequenz beträgt jetzt 150MHz. Es ist immer nur ein Kernpaar gleichzeitig nutzbar.
Die Größe des Hauptspeichers wurde auf 520kB angehoben. Je nach Chip-Revision hat der neue Pico 30 oder 48 GPIO Pins. RP2350A mit 30 GPIO, RP2350B mit 48. Auch bei den PIO hat sich was getan, es gibt jetzt einen mehr, so dass der Pico 2 insgesamt 12 State-Machines besitzt.
Die Platinendimensionen sind unverändert, ebenso die Anordnung des Micro-USB Buchse, so das alte Gehäuse weiter benutzt werden können.
Pico | Pico 2 | Pico 2W | |
---|---|---|---|
Chip | RP2040 | RP2350 | RP2350 |
Kerne | Dual ARM Cortex-M0+ | Dual ARMCortex-M33 oder 2* Hazard3 RISC-V | Dual ARM Cortex-M33 oder 2* Hazard3 RISC-V |
Takt | 133MHz | 150MHz | 150MHz |
Speicher | 264kB | 520kB | 520kB |
PIO | 2 | 3 | 3 |
State Machines | 8 | 12 | 12 |
I²C | 2 | 2 | 2 |
GPIO | 26 | 26 | 26 |
SPI | 2 | 2 | 2 |
PWM | 16x | 24x | 24x |
USB | 1.1 | 1.1 | 1.1 |
Flash (onboard) | 2 MByte | 4 MByte | 4 MByte |
WLAN | beim Pico W | – | 802.11n |
Bluetooth | Pico W | – | 5.2 LE |
MicroPython
Ein für den Pico 2 angepasstes Firmwareimage steht momentan in der Version 1.24 als Preview bereit. Das flashen geschieht wie bei Pico: BootSelButton gedrückt halten während der USB-Stecker in den Rechner gesteckt wird. Der Pico 2 meldet sich dann als Datenträger mit dem Namen RP2350. Dort kopierst du das .uf2 File einfach drauf und der Pico 2 startet dann neu.
Thonny erkennt den Raspberry Pi Pico 2 sofort. Eventuell musst du einmal den Start/Stop-Button der IDE drücken.

Kompatibilität
Der Pico 2 soll softwareseitig kompatibel zum Vorgänger sein, daher nehme ich mir mal die bisherigen Programme und versuche sie ohne Modifikation zu starten.
Das Blink LED Programm funktionierte tadellos.
from machine import Pin
from utime import sleep
led = machine.Pin(25, machine.Pin.OUT)
state = False
running = True
#Endlosschleife
led.off()
while True:
state = not state # state hin- und herschalten
sleep(1.0)
if state:
print('LED on')
led.on()
# running = False
else:
print('LED off')
led.off()
Übertaktung
Den nächsten Kompatibilitätstest mache ich mit dem Programm zur Übertaktung. Während mich MicroPython beim Pico nicht über 275MHz takten lies, Kann ich beim Pico 2 den Takt mit 300MHz sogar verdoppeln. Zunächst mach den Test mit dem Sieb des Eratosthenes:
# sieve_oc.py
import time
import machine
from machine import Pin
led = Pin(25, Pin.OUT)
#Berechnung von Primzahlen mit dem Sieb des Eratosthenes.
def sieb_des_eratosthenes(limit):
# Erzeuge eine Liste, die angibt, ob eine Zahl eine Primzahl ist
is_prime = [True] * (limit + 1)
p = 2
while (p * p <= limit):
# Wenn is_prime[p] nicht verändert wurde, ist p eine Primzahl
if is_prime[p]:
# Alle Vielfachen von p können keine Primzahl sein.
for i in range(p * p, limit + 1, p):
is_prime[i] = False
p += 1
# Sammle alle Primzahlen in einer Liste.
prime_numbers = [p for p in range(2, limit + 1) if is_prime[p]]
return prime_numbers
# Methode zur Laufzeitbestimmung
def berechnung(limit):
ergebnis = {}
start_time = time.ticks_ms()
prime_numbers = sieb_des_eratosthenes(limit)
ergebnis['primzahlen'] = prime_numbers
end_time = time.ticks_ms()
running_time =time.ticks_diff(end_time,start_time)
ergebnis['laufzeit'] = running_time
return ergebnis
# Liefert den Clock-Speed in MHz
def get_speed():
return str(round(machine.freq()/1000000,1))
# Beispielverwendung: Finde alle Primzahlen bis 1000
print(f'Durchgang #1 mit {get_speed()}MHz')
limit = 10000
ergebnis1 = berechnung(limit)
laufzeit1 = ergebnis1['laufzeit']
print(f'Laufzeit: {laufzeit1}ms')
#Übertaktung auf 270MHz
led.on()
machine.freq(300000000)
print(f'Durchgang #2 mit {get_speed()}MHz')
ergebnis2 = berechnung(limit)
laufzeit2 = ergebnis2['laufzeit']
primzahlen = ergebnis2['primzahlen']
led.off()
machine.freq(125000000)
print(f'Primzahlen bis {limit}: {primzahlen}')
print(f'Laufzeit: {laufzeit2}ms')
p = (laufzeit1 -laufzeit2) / laufzeit1 *100
print(f' prozentualer Unterschied: {p}%%')
Ein weiterer Performancetest, auf den mich Gary Sims in seinem YouTube Kanal gebracht hat, ist das 8-Damen Problem. Dabei geht in der Informatik um einen Algorithmus, um auf einem 8*8 Schalbrett 8 Damen so zu verteilen, dass keine die andere schlagen kann.
Da dieser Algorithmus mit Backtracking arbeitet, ist er komplex genug, um Last auf die Pico zu bringen.
import time
import machine
def is_safe(board, row, col, n):
# Überprüfe diese Spalte
for i in range(row):
if board[i][col] == 1:
return False
# Überprüfe die diagonale links oben
i, j = row, col
while i >= 0 and j >= 0:
if board[i][j] == 1:
return False
i -= 1
j -= 1
# Überprüfe die diagonale rechts oben
i, j = row, col
while i >= 0 and j < n:
if board[i][j] == 1:
return False
i -= 1
j += 1
return True
def solve_n_queens_util(board, row, n):
# Wenn alle Damen platziert sind, gib die Lösung zurück
if row >= n:
return True
# Versuche, die Dame in jeder Spalte der aktuellen Zeile zu platzieren
for col in range(n):
if is_safe(board, row, col, n):
# Platziere die Dame
board[row][col] = 1
# Rekursiv die nächste Zeile versuchen
if solve_n_queens_util(board, row + 1, n):
return True
# Wenn es nicht funktioniert, entferne die Dame (Backtracking)
board[row][col] = 0
# Wenn keine Spalte passt, gib False zurück
return False
# Liefert den Clock-Speed in MHz
def get_speed():
return str(round(machine.freq()/1000000,1))
def solve_n_queens(n):
board = [[0 for _ in range(n)] for _ in range(n)]
if not solve_n_queens_util(board, 0, n):
print("Es gibt keine Lösung für", n, "Damen.")
return
# Drucke das Schachbrett mit der Lösung
for row in board:
print(" ".join(["Q" if x == 1 else "." for x in row]))
# Beispielaufruf für das 8-Damen-Problem
print(f'Durchgang mit {get_speed()}MHz')
start_time = time.ticks_ms()
solve_n_queens(8)
end_time = time.ticks_ms()
running_time =time.ticks_diff(end_time,start_time)
print(f'Laufzeit {running_time}ms')
#machine.freq(270000000)
machine.freq(300000000)
print(f'Durchgang mit {get_speed()}MHz')
start_time = time.ticks_ms()
solve_n_queens(8)
end_time = time.ticks_ms()
running_time =time.ticks_diff(end_time,start_time)
print(f'Laufzeit {running_time}ms')
#machine.freq(125000000)
machine.freq(150000000)
Eine Lösung kann dann so aussehen:
Q . . . . . . .
. . . . Q . . .
. . . . . . . Q
. . . . . Q . .
. . Q . . . . .
. . . . . . Q .
. Q . . . . . .
. . . Q . . . .
Damit die Pico richtig was zu tun bekommen, habe ich das für ein 15*15 Schachbrett berechnen lassen.
Das Vergleichsergebnis sieht so aus:
Pico 2 150Mhz | Pico 2 300MHz | Pico 2W 150MHz | Pico 2W 300MHz | Pico 133MHz | Pico 275MHz |
|
---|---|---|---|---|---|---|
Primzahlen | 55ms | 23ms | 46ms | 26ms | 91ms | 38ms |
nQueens | 1304ms | 653ms | 1304ms | 625ms | 2319ms | 1073ms |
Im Basistakt ist der Raspberry Pi Pico 2 um 43,7% (Primzahlen) bzw. 39,5% schneller als sein Vorgänger.
Fazit
Von den Leistungsdaten her überzeugt der Pico 2 durchaus. Es ist allerdings schade, dass er nicht direkt mit einem WiFi Modul erschienen ist. Ebenso vermisse ich einen Reset-Button auf der Platine, der bei anderen MCU längst Standard ist.
Update 04.12.24: Im November erschien dann der Raspberry Pi Pico 2W, dessen technische Daten ich schonmal in die Tabelle oben aufgenommen habe.