Python → MicroPython i Processing → Vizuelni kontroler nagiba


Projekat: „Vizuelni kontroler nagiba“


Lekcija 14 od 14

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.

Šta je cilj projekta?

U ovom projektu povezujemo:
  • fizički pokret uređaja
  • serial komunikaciju
  • grafičku vizualizaciju
To je pravi primer interaktivnog sistema.

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.

Važna ideja:

micro:bit ne crta grafiku. Njegov posao je:
  • da meri nagib
  • da šalje podatke
Processing zatim koristi te podatke za crtanje objekata na ekranu.

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)

Format poruke:

x,y\n
  • x ➝ nagib po X osi
  • y ➝ nagib po Y osi
  • \n ➝ kraj poruke
Podaci se šalju približno 10 puta u sekundi.

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

Važno:

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.

Eksperiment:

Pokušaj sledeće izmene:
  • Promeni veličinu kruga
  • Promeni boju pozadine
  • Promeni brzinu pomeranja
Na primer:

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.

Mapiranje podataka:

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.

Mini izazov:

Možeš li da napraviš:
  • labirint
  • kontrolu automobila
  • balansiranje lopte
koristeći samo nagib micro:bit-a?

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?
Važna ideja:

micro:bit ne mora da zna ništa o igri. Njegov posao može biti samo:
  • očitaj senzore
  • pošalji podatke
Sva logika igre može ostati u Processing-u.

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.

Šta preporučujemo?

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:

Preporuka za nove učenike:

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.

Važno:

U Processing-u postoje različiti modovi rada:
  • Java Mode — podrazumevani mod
  • Python Mode — koristi Python sintaksu
Iako oba koriste isti Processing engine, način pisanja koda je drugačiji.

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
Zapamti:

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 sketch
  • 115200 ➝ brzina komunikacije (baudrate)
Važno:

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
Eksperiment:

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.

Važna ideja:

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.

Mapiranje podataka:

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.

Praktično pravilo:

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
Ideja za projekat:

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

Važno:

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

Eksperiment:

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?


Logika sistema:

  • 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”.

Objašnjenje:

\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

Mini izazov:

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
Ove ideje predstavljaju prvi korak ka pravljenju jednostavne igre.
Šta sledi?

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.