Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

Raspberry PI Pico #9 – kleines Spiel „Pixel Chaser“

Posted on 28. Juni 20219. März 2024 by Stefan Draeger

Wie du das kleine Spiel „Pixel Chaser“ für den Raspberry PI Pico programmierst, möchte ich dir in diesem Beitrag zeigen.

Raspberry PI Pico - Pixel Chaser
Dieses Video auf YouTube ansehen.

  • Was ist Pixel Chaser?
  • Aufbau der Schaltung
    • Achtung!
    • Anschluss des NeoPixel Ring
    • Schaltbild
  • Programmieren in CircuitPython
    • Download & kopieren der NeoPixel Bibliothek
    • Erstellen des Programmes im MU Editor
    • Programmieren des Spieles „Pixel Chaser“ in X Schritten
      • Schritt 1 – steuern eines NeoPixel Rings
        • steuern der Geschwindigkeit mit einem Drehpotentiometer
          • Quellcode
          • Video
    • Schritt 2 – einbau des Tasters
    • Schritt 3 – Piezo Buzzer für die Ausgabe eines Tones
  • fertiges Spiel „Pixel Chaser“

Was ist Pixel Chaser?

Das Spiel „Pixel Chaser“ funktioniert recht einfach. Du musst lediglich eine Taste betätigen, wenn zwei NeoPixel übereinander liegen. Die Schwierigkeit dabei liegt daran dass, der eine Pixel feststeht und der andere sich im Kreis dreht.

Aufbau der Schaltung

Für den Aufbau der Schaltung benötigst du:

  • Raspberry PI Pico*,
    • USB Datenkabel*
  • ein 8bit NeoPixel Ring* (besser noch ein 16bit* oder 24bit*)
  • ein Piezo Buzzer*,
  • ein Taster für die Printmontage* inkl. Kappe,
  • ein 10 kOhm Widerstand*,
  • diverse Breadboardkabel*,
  • ein 170 Pin Breadboard*

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Achtung!

Der Raspberry PI Pico kann nur maximal 30 NeoPixel gleichzeitig betreiben, d.h. alle NeoPixel sind aktiviert. Wenn du mehr als 30 an einem Pi Pico steuern möchtest, so musst du eine externe 5V Stromquelle einbinden.

Das kannst du zbsp. mit einem Power Shield für die 400 bzw. 720 Pin Breadboards* erledigen.

Power Shield für ein 400 / 720 Pin Breadboard
Power Shield für ein 400 / 720 Pin Breadboard

Das Modul „Power Supply for Breadboards“ kann 3,3V und 5V liefern, welches mit einem Jumper gesetzt werden kann.

Wenn du dieses Modul in deine Schaltung integrierst, dann musst du zusätzlich noch den Minus-Pol des Power Supply Moduls mit einem GND des Raspberry PI Pico verbinden!

Anschluss des NeoPixel Ring

Zunächst widmen wir uns dem Pixel Ring, dieser verfügt auf der Rückseite über 3 Lötpunkte an welche Breadboardkabel angelötet werden können.

12bit NeoPixel Ring Ansicht vorne
12bit NeoPixel Ring Ansicht vorne
12bit NeoPixel Ring Ansicht hinten
12bit NeoPixel Ring Ansicht hinten
Breadboardkabel am 12bit NeoPixel Ring
Breadboardkabel am 12bit NeoPixel Ring

ABER diese Kabel sind recht dünn und daher reißen diese bei mehrmaliger Bewegung recht schnell ab.

Da an diesem Pixel Ring ein NeoPixel defekt ist, habe ich mir schnell ein neuen, etwas größeren Ring (16bit = 16 NeoPixel) bei Roboter-Bausatz.de für knapp 7 € inkl. Versandkosten bestellt.

Anschluss eines NeoPixel Rings
Anschluss eines NeoPixel Rings

Dieser NeoPixel Ring hat vier Pins.

BeschriftungBeschreibung
DIdigital IN
5VVersorgungsspannung
GNDMinus-Pol
DOdigital OUT

Über den DO Pin kann ein oder mehrere NeoPixel Ringe kaskadierend angeschlossen werden.

Schaltbild

Schaltung – Raspberry PI Pico „Pixel Chaser“

Programmieren in CircuitPython

Für die Programmierung des NeoPixel Rings für den Raspberry PI Pico gibt es diverse Bibliotheken. Jedoch habe ich mit der Adafruit Bibliothek deutlichen erfolg gehabt. Diese Bibliothek findest du als Download unter https://circuitpython.org/libraries bzw. zum direkten Download der knapp 4 MB großen ZIP Datei.

Der Download hat mit meiner 100MBit Leitung knapp 4 Minuten gedauert, also bitte etwas Zeit beim Download mitbringen.

Download & kopieren der NeoPixel Bibliothek

Wenn die knapp 4 MB große ZIP Datei heruntergeladen und entpackt wurde, muss die Datei „neopixel.mpy“ nach X:\CIRCUPY\lib kopiert werden.

Inhalt vom Laufwerk „CIRCUITPY“

Erstellen des Programmes im MU Editor

Für die Programmierung nutze ich die kostenfreie, kleine IDE „MU Editor“ welche du von der Seite https://codewith.mu/en/download herunterladen kannst. Diesen Editor bekommst du für Microsoft Windows, MacOS sowie als Python Package (für Linux).

Editor Mu - wählen des Modus
Editor Mu – wählen des Modus

Programmieren des Spieles „Pixel Chaser“ in X Schritten

Wie du das Spiel „Pixel Chaser“ programmierst, möchte ich dir in x einfachen Schritten zeigen.

Schritt 1 – steuern eines NeoPixel Rings

Im ersten Schritt wollen wir einen NeoPixel Ring ansteuern. Im Detail heißt dass, das wir zunächst einmal prüfen, wie wir die einzelnen Pixel eines NeoPixel Rings ansteuern können.

# importieren der Funktion sleep aus dem Modul time
from time import sleep
# Modul "board" für die Ansteuerung der GPIOs
import board
# Modul zum Ansteuern eines NeoPixel
import neopixel

#Anzahl der verfügbaren NeoPixel
numPixels = 12

#initialisieren der NeoPixel am GPO0 und der Anzahl "numPixels"
pixels = neopixel.NeoPixel(board.GP0, numPixels)
#Helligkeit auf 50% setzen
pixels.brightness = 0.5

#Endlosschleife
while True:
    #von 0 bis Anzahl "numPixels" mache...
    for pixel in range(num_pixels):
        #NeoPixel an Position "pixel" in die Farbe grün färben
        pixels[pixel] = (0, 255, 0)
        #eine Pause von 0,03 Sekunden
        sleep(0.03)
        #NeoPixel an Position "pixel" in die Farbe schwarz färben
        #quasi den Pixel deaktivieren
        pixels[pixel] = (0, 0, 0)
steuern der Geschwindigkeit mit einem Drehpotentiometer

Die Geschwindigkeit des Umschaltens steuern wir im Code mit einer kleinen Pause, in diesem Fall sind es 0,03 Sekunden. Wir können diese Pause auch über einen 50 kOhm Drehpotentiometer manipulieren.

Aufbau der Schaltung „Drehpotentiometer am Raspberry PI Pico“
Quellcode
# importieren der Funktion sleep aus dem Modul time
from time import sleep
# Modul "board" für die Ansteuerung der GPIOs
import board
# Modul zum Ansteuern eines NeoPixel
import neopixel

from analogio import AnalogIn

#Anzahl der verfügbaren NeoPixel
numPixels = 12

#initialisieren der NeoPixel am GPO0 und der Anzahl "numPixels"
pixels = neopixel.NeoPixel(board.GP0, numPixels)
#Helligkeit auf 50% setzen
pixels.brightness = 0.5

poti = AnalogIn(board.GP27)

#Funktion zum Mappen eines Werte zu einer Range
#https://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
def translate(value, leftMin, leftMax, rightMin, rightMax):
    leftSpan = leftMax - leftMin
    rightSpan = rightMax - rightMin

    valueScaled = float(value - leftMin) / float(leftSpan)

    return rightMin + (valueScaled * rightSpan)

#berechnen eines Wertes für die Pause
def pauseValue():
    value = poti.value
    return translate(value, 0,65520, 0,5)
    
#Endlosschleife
while True:
    #von 0 bis Anzahl "numPixels" mache...
    for pixel in range(numPixels):
        #NeoPixel an Position "pixel" in die Farbe grün färben
        pixels[pixel] = (0, 255, 0)
        #eine Pause von 0,03 Sekunden
        sleep(pauseValue())
        #NeoPixel an Position "pixel" in die Farbe schwarz färben
        #quasi den Pixel deaktivieren
        pixels[pixel] = (0, 0, 0)
Video

Über diesen Drehpotentiometer können wir nun den Schwierigkeitsgrad des Spieles einstellen. Oder wir lassen diesen vom Mikrocontroller einstellen. Beide Varianten sind möglich.

Schritt 2 – einbau des Tasters

Wie du einen Taster an einem Raspberry PI Pico anschließt und auslesen kannst, habe ich dir bereits im Beitrag Raspberry PI Pico #4 – Taster mit PullDown & PullUp abfragen ausführlich erläutert.

# Modul "board" für die Ansteuerung der GPIOs
import board

# Modul um den Status eines Buttons einzulegen
import digitalio

# Taster am GPIO1 angeschlossen
button = digitalio.DigitalInOut(board.GP1)
button.direction = digitalio.Direction.INPUT

Schritt 3 – Piezo Buzzer für die Ausgabe eines Tones

Damit wir eine akustische Rückmeldung haben, ob wir gewonnen oder verloren haben, bauen wir nun einen Piezo Buzzer ein.

import time

import board

import pulseio

tones = [ 200, 800]

buzzer = pulseio.PWMOut(board.GP2, variable_frequency=True)
buzzer.frequency = tones[0]
buzzer.duty_cycle = 2**15

while True:
    buzzer.frequency = tones[0]
    time.sleep(0.5)
    buzzer.frequency = tones[1]
    time.sleep(0.5)

fertiges Spiel „Pixel Chaser“

Hier nun der fertige Code.

# Modul für den Import einer Funktion zum einlegen einen Pause im Code
from time import sleep

# Modul "board" für die Ansteuerung der GPIOs
import board

# Modul um den Status eines Buttons einzulegen
import digitalio

# Modul zum Ansteuern eines NeoPixel
import neopixel

# Modul um eine Zufallszah lzu generieren
from random import randint

# Modul um ein PWM Signal zu erzeugen (wird für den Piezo Buzzer benötigt)
import pulseio

# Taster am GPIO1 angeschlossen
button = digitalio.DigitalInOut(board.GP1)
button.direction = digitalio.Direction.INPUT

# initialisieren des Piezo Buzzers am GPIO2 Pin
buzzer = pulseio.PWMOut(board.GP2, variable_frequency=True)
# zunächst die Frequenz auf 1 und die Wellenlänge auf 0
buzzer.frequency = 1
buzzer.duty_cycle = 0

# Anzahl der verfügbaren NeoPixel
numPixels = 16

# aktiver Pixel
activePixel = -1

# initialisieren der NeoPixel am GPO0 und der Anzahl "numPixels"
pixels = neopixel.NeoPixel(board.GP0, numPixels)
# Helligkeit auf 10% setzen
pixels.brightness = 0.1

# Töne welche wiedergegeben werden sollen
tone = [ 
    200,  # Ton für verloren
    800  # Ton für gewonnen
    ]

# erzeugen einer Zufallszahl & aktivieren des Pixels
# dieser aktivierte Pixel wird in der globalen Variable
# activePixel gespeichert
def activateRandomPixel():
    global activePixel
    activePixel = randint(0, numPixels-1)
    pixels[activePixel] = (255, 0, 0)

# löscht alle aktiven NeoPixel
def clearPixels():
    for pixel in range(numPixels):
        pixels[pixel] = (0, 0, 0)

# deaktivieren des Piezo Buzzers
def turnPiezoBuzzerOff():
    buzzer.duty_cycle = 0
    
# aktivieren des Piezo Buzzers
def turnPiezoBuzzerOn():
    buzzer.duty_cycle = 2**15

activateRandomPixel()

# Endlosschleife
while True:
    # von 0 bis Anzahl "numPixels" mache...
    for pixel in range(numPixels):
        # wenn der aktive Pixel nicht der gleiche aus der Schleife ist,
        # dann mache...
        if pixel != activePixel:
            # NeoPixel an Position "pixel" in die Farbe grün färben
            pixels[pixel] = (0, 255, 0)
            # eine Pause von 0,03 Sekunden
            sleep(0.25)
            # NeoPixel an Position "pixel" in die Farbe schwarz färben
            # quasi den Pixel deaktivieren
            pixels[pixel] = (0, 0, 0)

        # Wenn der Button gedrückt ist, dann...
        if not button.value:
            # aktivieren des Piezo Buzzers
            turnPiezoBuzzerOn()
            # ausgeben der Pixel auf der Console
            print(activePixel, pixel, sep="|")  
            # Wenn der aktive Pixel gleich der Pixel aus der 
            # Schleife ist, dann...
            if (activePixel-1) == pixel:
                # ausgeben der Zeichenkette "gewonnen"
                print("gewonnen")
                
                # ausgeben eines Tones
                buzzer.frequency = tone[1]
                # eine kleine Pause
                sleep(0.1)
                buzzer.frequency = tone[1]
                sleep(0.1)
                buzzer.frequency = 1
                
                # löschen aller Pixel
                clearPixels()
                # ermitteln eines neuen Pixels welcher gesucht werden soll
                activateRandomPixel()
            else: # Wenn die beiden Pixel nicht übereinander liegen dann...
                buzzer.frequency = tone[0]
                sleep(0.25)
                buzzer.frequency = 1
        # deaktivieren des Piezo Buzzers
        turnPiezoBuzzerOff()

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}