Python → MicroPython i Processing → Vizuelni kontroler nagiba
Projekat: „Vizuelni kontroler nagiba“
MicroPython + Processing: Povratak na hub
U ovom projektu micro:bit postaje kontroler pokreta, dok Processing prikazuje objekat koji se pomera u realnom vremenu.
Nagni micro:bit ➝ objekat se pomera na ekranu.
U ovom projektu povezujemo:
- fizički pokret uređaja
- serial komunikaciju
- grafičku vizualizaciju
Arhitektura sistema
micro:bit (akcelerometar)
↓
uart.write("x,y\n")
↓
USB Serial
↓
Processing čita podatke
↓
Pomera objekat na ekranu
Sistem funkcioniše kao real-time kontroler pokreta.
micro:bit ne crta grafiku. Njegov posao je:
- da meri nagib
- da šalje podatke
Korak 1 — MicroPython kod (micro:bit)
Micro:bit šalje vrednosti nagiba po X i Y osi.
from microbit import *
import utime
while True:
# očitavanje nagiba uređaja
x = accelerometer.get_x()
y = accelerometer.get_y()
# slanje podataka kao tekst:
# x,y\n
uart.write(str(x) + "," + str(y) + "\n")
# mala pauza između poruka
utime.sleep(0.1)
x,y\n
- x ➝ nagib po X osi
- y ➝ nagib po Y osi
\n➝ kraj poruke
Korak 2 — Processing Python Mode (vizuelizacija)
Pošto učenici rade u Python Mode, koristimo Python sintaksu i Python stil pisanja koda.
add_library('serial')
from processing.serial import *
xPos = 300
yPos = 200
def setup():
global myPort
size(600, 400)
# prikaz dostupnih portova
print(Serial.list())
# povezivanje sa prvim serial portom
myPort = Serial(this, Serial.list()[0], 115200)
def draw():
global xPos, yPos
background(240)
# crtanje objekta
ellipse(xPos, yPos, 50, 50)
# proveravamo da li postoje podaci
while myPort.available() > 0:
# čitanje jedne linije
data = myPort.readStringUntil('\n')
if data != None:
# uklanjanje praznih karaktera
data = data.strip()
# razdvajanje po zarezu
values = data.split(',')
# provera da li imamo dve vrednosti
if len(values) == 2:
x = float(values[0])
y = float(values[1])
# mapiranje senzora na ekran
xPos = width/2 + x/10
yPos = height/2 + y/10
Ovo je kod za: Processing Python Mode Nije isti kao klasični Java Processing mod.
Kako sistem radi?
- Micro:bit meri nagib pomoću akcelerometra
- Šalje podatke kao tekstualnu poruku
- Processing čita kompletnu liniju
- Podaci se razdvajaju po zarezu
- Objekat se pomera proporcionalno nagibu
Ovo je primer direktne veze između fizičkog pokreta i grafike.
Pokušaj sledeće izmene:
- Promeni veličinu kruga
- Promeni boju pozadine
- Promeni brzinu pomeranja
background(0)
fill(0, 255, 0)
Zašto delimo sa 10?
Vrednosti akcelerometra mogu biti veoma velike (često preko ±1000).
Ako bismo koristili originalne vrednosti, objekat bi se pomerao previše brzo.
Zato koristimo:
x/10
y/10
Time smanjujemo opseg kretanja.
Ovo je primer pretvaranja sirovih senzorskih podataka u vizuelno upotrebljiv opseg. To se naziva: mapiranje podataka.
Napredna verzija (izazov)
Proširi projekat:
- Dodaj granice da objekat ne izađe van ekrana
- Dodaj promenu boje u zavisnosti od nagiba
- Dodaj „inerciju“ (glatko kretanje)
- Dodaj prepreke koje treba izbegavati
Na taj način projekat prelazi iz demonstracije u pravu mini-igru.
Možeš li da napraviš:
- labirint
- kontrolu automobila
- balansiranje lopte
Pedagoški cilj projekta
Učenici ovde uče:
- kako se senzorski podaci prenose
- kako se dizajnira format poruke
- kako se parsiraju podaci
- kako se fizički pokret pretvara u grafiku
- kako se pravi interaktivni sistem
Ovo je pravi primer povezivanja:
- hardvera
- programiranja
- grafike
- interakcije
Mini izazov za razmišljanje
Kako bi napravio igru: „Izbegni zidove“ gde se objekat kreće samo pomoću nagiba micro:bit-a?
Razmisli:
- Gde se proverava sudar?
- Da li micro:bit treba da zna za prepreke?
- Da li logika ostaje u Processing-u?
micro:bit ne mora da zna ništa o igri. Njegov posao može biti samo:
- očitaj senzore
- pošalji podatke
Time prelaziš sa jednostavne vizualizacije na dizajn pravog interaktivnog sistema.
Važna napomena za korisnike Processing 4+
Primeri prikazani u ovoj lekciji koriste Processing Python Mode.
Međutim, u novijim verzijama Processing-a (posebno Processing 4.x), mogu se javiti problemi sa kompatibilnošću pojedinih biblioteka i Python Mode dodatka.
Postoje dva pouzdana puta:
- Processing 3.4.5 ili stariji — najbolji za praćenje starijih tutorijala i primera.
- py5 — moderno rešenje zasnovano na Python 3 koje predstavlja preporučeni pravac za nove projekte.
Ako koristiš Processing 4.x ili želiš da pređeš na moderniji Python pristup, pogledaj sledeće lekcije:
- Processing 4+, Python Mode i alternative
- Instalacija py5 na Windows i Linux sistemima
- micro:bit i py5 — serijska komunikacija i grafika
Ako tek počinješ sa novim projektima, preporučujemo da upoznaš py5, jer koristi standardni Python 3 i moderniji razvojni ekosistem.
Kako izgleda čitanje sa serijskog porta u Python modu?
Ako koristiš Processing Python Mode, kod izgleda drugačije nego u Java modu.
Sintaksa je mnogo bliža standardnom Python-u, što učenicima često olakšava razumevanje.
U Processing-u postoje različiti modovi rada:
- Java Mode — podrazumevani mod
- Python Mode — koristi Python sintaksu
Primer — čitanje podataka sa micro:bit-a
Ovaj program:
- čita podatke sa serial porta
- prima vrednosti x i y
- pomera objekat na ekranu
# Učitavanje biblioteke za serijsku komunikaciju
add_library('serial')
from processing.serial import *
# Globalne promenljive za poziciju objekta
xPos = 300
yPos = 200
# Promenljiva za serijski port
myPort = None
def setup():
global myPort
# Veličina prozora
size(600, 400)
# Prikaz svih dostupnih COM portova
print(Serial.list())
# Otvaranje prvog pronađenog porta
myPort = Serial(this, Serial.list()[0], 115200)
# Processing čeka kraj linije (\n)
myPort.bufferUntil('\n')
def draw():
global xPos, yPos
# Boja pozadine
background(240)
# Crtanje objekta
ellipse(xPos, yPos, 50, 50)
# Ova funkcija se automatski pokreće
# kada stigne nova linija podataka
def serialEvent(port):
global xPos, yPos
# Čitanje jedne linije teksta
data = port.readStringUntil('\n')
# Provera da li je nešto stiglo
if data != None:
# Uklanjanje praznih karaktera
data = data.strip()
# Razdvajanje teksta po zarezu
values = data.split(',')
# Očekujemo 2 vrednosti: x i y
if len(values) == 2:
# Pretvaranje teksta u brojeve
x = float(values[0])
y = float(values[1])
# Pomeranje objekta
xPos = width/2 + x/10
yPos = height/2 + y/10
Kako program funkcioniše?
Pogledajmo korak po korak šta se dešava.
1. Učitavanje serial biblioteke
add_library('serial')
from processing.serial import *
Ovim uključujemo podršku za:
- COM portove
- USB serial komunikaciju
- čitanje podataka sa micro:bit-a
Bez serial biblioteke Processing ne može da komunicira sa micro:bit uređajem.
2. Otvaranje serial porta
print(Serial.list())
Ova linija prikazuje sve dostupne serial portove.
Na primer:
['COM3', 'COM5']
Zatim otvaramo prvi pronađeni port:
myPort = Serial(this, Serial.list()[0], 115200)
this➝ trenutni Processing sketch115200➝ brzina komunikacije (baudrate)
Baudrate mora biti isti u MicroPython i Processing programu. Ako brzine nisu iste, podaci neće biti pravilno pročitani.
3. Čekanje kraja poruke
myPort.bufferUntil('\n')
Ova linija govori Processing-u:
„Sačekaj dok ne stigne znak novog reda.”
To omogućava da čitamo celu poruku odjednom.
Na primer:
120,-45
Probaj da ukloniš:
bufferUntil('\n')
i posmatraj šta se dešava sa podacima.
4. Funkcija serialEvent()
Funkcija:
def serialEvent(port):
automatski se pokreće kada stigne nova poruka.
To znači da ne moramo stalno ručno proveravati port.
Ovo je primer: event-driven programiranja. Program reaguje na događaj (pristizanje podataka).
5. Razdvajanje podataka
Micro:bit šalje tekstualnu poruku:
120,-45
Processing zatim koristi:
values = data.split(',')
Rezultat je lista:
['120', '-45']
Nakon toga:
x = float(values[0])
y = float(values[1])
pretvaramo tekst u brojeve.
6. Pomeranje objekta
xPos = width/2 + x/10
yPos = height/2 + y/10
Na ovaj način:
- nagib uređaja utiče na poziciju objekta
- senzorski podaci postaju grafika
Deljenje sa 10 smanjuje prevelike vrednosti senzora.
Pretvaranje senzorskih vrednosti u pozicije na ekranu naziva se: mapiranje podataka.
Zašto koristimo global?
U Python modu promenljive unutar funkcije su lokalne osim ako ne napišemo:
global xPos
Na taj način Processing zna da želimo da menjamo globalnu promenljivu, a ne da pravimo novu lokalnu kopiju.
Ako promenljivu menjaš unutar funkcije, a definisana je van funkcije, često će ti biti potreban
global.
Java Mode vs Python Mode
| Java Mode | Python Mode |
|---|---|
void setup() |
def setup() |
String[] |
list |
float x |
x = float() |
| Tačka-zarez ; | Nema ; |
| Java sintaksa | Python sintaksa |
Oba moda koriste isti Processing engine, ali je sintaksa drugačija.
Ako učenici već znaju Python, Python Mode je često prirodniji izbor.
Mini izazov
Probaj da proširiš program:
- promeni boju objekta kada se micro:bit nagne
- dodaj više objekata
- dodaj granice ekrana
- dodaj „glatko“ kretanje
Možeš li da napraviš mini igru u kojoj se lopta kontroliše isključivo nagibom micro:bit-a?
Kako izgleda čitanje sa serijskog porta u Python modu?
Ako koristiš Processing Python Mode, kod izgleda bliže standardnom Python-u nego Java verzija.
To znači:
- koristi se
def setup()umesto Java funkcija - nema tačka-zarez sintakse
- liste i stringovi rade kao u Python-u
Ovo je i dalje Processing engine, ali sa Python sintaksom preko Jython-a.
Primer: čitanje podataka sa micro:bit-a
# Uključivanje serial biblioteke Processing-a
add_library('serial')
from processing.serial import *
# Globalne promenljive (pozicija objekta)
xPos = 300
yPos = 200
# Serijski port
myPort = None
def setup():
global myPort
size(600, 400)
# Prikaz dostupnih portova
print(Serial.list())
# Otvaranje serijske veze
myPort = Serial(this, Serial.list()[0], 115200)
# Čekamo kraj linije (\n)
myPort.bufferUntil('\n')
def draw():
background(240)
# Crtanje objekta
ellipse(xPos, yPos, 50, 50)
def serialEvent(port):
global xPos, yPos
# Čitanje jedne linije
data = port.readStringUntil('\n')
if data is not None:
# Čišćenje stringa
data = data.strip()
# Razdvajanje x,y
values = data.split(',')
if len(values) == 2:
x = float(values[0])
y = float(values[1])
# Mapiranje na ekran
xPos = width/2 + x/10
yPos = height/2 + y/10
Promeni skalu kretanja:
xPos = width/2 + x/20
yPos = height/2 + y/20
Šta se dešava kada povećavaš ili smanjuješ delilac?
Kako ovo zapravo radi?
- micro:bit šalje tekst:
x,y\n - Processing prima celu liniju
- split(',') razdvaja vrednosti
- float() pretvara tekst u broj
- objekat se pomera na ekranu
Zašto je bufferUntil('\n') važan?
Bez ovog, Processing bi čitao “polu-poruke”.
\n označava kraj jedne poruke.
Processing tada zna:
□ “sada imam kompletnu informaciju”
Mini zaključak
Ovo je osnovni obrazac svih real-time sistema:
- uređaj šalje podatke
- računar ih parsira
- grafika reaguje u realnom vremenu
Trenutno micro:bit kontroliše samo poziciju objekta. Pokušaj da proširiš program:
- promeni boju objekta pri nagibu
- dodaj više objekata na ekranu
- ograniči kretanje na granice prozora
- dodaj brojčani prikaz X i Y vrednosti
Do sada smo koristili micro:bit za upravljanje jednim objektom. U ovoj lekciji naučio si kako da micro:bit šalje podatke o nagibu i kako Processing može da ih pretvori u grafiku u realnom vremenu.
U narednoj lekciji pretvorićemo isti princip u jednostavnu igru u kojoj će micro:bit postati pravi gejming kontroler.
Nastavi na projekat: Micro:bit gejming kontroler →
U tom projektu koristićemo nagib micro:bit-a za kontrolu objekata, izbegavanje prepreka i sakupljanje poena.