Hlavní navigace

Snap! ide do sveta: zostavte si vlastné bloky

Peter Fabo

Ak ste s vašou ratolesťou pri učení programovania už vyčerpali možnosti prostredia Scratch, vyskúšajte interakciu s reálnym svetom. Jednoduchý návod ako na to nájdete v príspevku.

Doba čtení: 6 minut

Sdílet

Prostredie Scratch určené pre výuku programovania na základných školách asi netreba zvlášť čitateľom predstavovať. Základom je idea skladania programu pomocou významovo farebne odlíšených blokov, pričom konštrukcia a pravidlá ukladanie blokov vylučujú, resp. výrazne obmedzujú vznik syntaktických chýb. Podstatou programovania je interaktívna práca s grafikou a zvukom založená na intuitívnom riadení pohybu a akcií kocúra (a ďaľších sprite) na pracovnej ploche. 

Pôvodná verzia napísaná v Smalltalku sa prepísaním do JavaScriptu pretransformovala do webovej aplikácie bežiacej v prostredí www prehliadača bez potreby inštalácie, čo výrazne zjednodušilo používanie programu v procese výuky na základných a stredných školách. Aktuálne sa vývoj programu na MIT sústreďuje primárne na pedagogické aspekty aplikácie prostredia, výsledkom čoho sú fantasticky prepracované návody pre učiteľov a pracovné listy a návody pre žiakov

Jeden zo zakladajúcich autorov sa v priebehu času presunul na Univerzitu v Berkley, kde pôvodnú koncepciu ďalej rozvíjal do hĺbky, takto vzniklo aktuálne trocha menej známe prostredie Snap! (pôvodne pod menom BOB – Build your Own Blocks), rovnako bežiace vo www prehliadači. Vlastnosti prostredia prekvapia aj ostrielaného programátorského harcovníka. Pod pekným farebným prostredím kompatibilným so Scratch je zakomponovaná tvorba vlastných blokov, čo je prakticky ekvivalentom makra alebo podprogramu, rozšírené možnosti riadenia programu, paralelné programovanie pomocou vlákien, udalosti a komunikácia medzi vláknami, možnosť vkladania vlastných skriptov a ďaľšie. 

Možnosť úpravy a rozšírenia prostredia Snap! je samozrejme lákavá aj pre interakciu mimo www prehliadača – jednoduchý zber dát, robotika a ďaľšie. Z dôvodu bezpečnostných obmedzení v JavaSkripte ale nie je možné priamo komunikovať s inými perifériami s výnimkou štandardných periférií (myš, klávesnica, zvuk, kamera atď.). Pretože JavaSript umožňuje komunikáciu s www pomocou HTTP soketov, jednou z možností, ako toto obmedzenie prekonať, je použitie jednoduchého HTTP serveru, ktorý bude mostom medzi Snap! a reálnym svetom. 

Predmetom príspevku je príklad jednoduchej minimalistickej konfigurácie, ktorá umožňuje riadenie LED na doske Arduina pomocou Snap!, použiť môžete samozrejme aj čokoľvek iné, vlastnú implementáciu vlastného klienta na vhodnom MCU, dosku s MicroPython a pod. Podstatou príkladu je demonštrácia princípu, z tohoto dôvodu sú ukážkové programy ošklbané do minimálneho funkčného tvaru, originálny Snap! je použitý bez zásahov a úprav kódu. 

Pokiaľ sa vám nebude chcieť predložené návrhy ďalej rozvíjať a experimentovať podľa predstáv vašej ratolesti, môžete použiť instantné riešenie v podobe upraveného Snap! priamo pre Arduino – Snap4Arduino, prípadne aj iné platformy

Arduino ako klient 

Ako vstupno-výstupné zariadenie použijeme dosku Arduino, pre náš demo príklad ľubovolnú verziu. Pre experimenty sú vhodné Mini a Nano, ktoré sa dajú zasunúť do breadboardu pre pripojenie ďaľších periférií. Náš primitívny klient bude prijímať znaky zo sériového portu, pri prijatí sekvencie 'D1' rozsvieti LED, 'D0' zhasne. Potvrdenie (v tomto jednoduchom prípade) nazad neposielame. 

#include <Arduino.h>

char buffer[2];
int byteReads=0;

void setup() {
   pinMode(LED_BUILTIN, OUTPUT);                  // init on-board LED
   Serial.begin(115200);                          // init serial comm
}

void loop() {
   if (Serial.available()){
     byteReads = Serial.readBytes(buffer, 2);

     if (byteReads == 2 && buffer[0] == 'D'){     // parse data
       if((buffer[1] - '0') == 1){                // command 'D1'
           digitalWrite(LED_BUILTIN, HIGH);
       }
       else{                                      // command 'D0'
           digitalWrite(LED_BUILTIN, LOW);
       }
     }
   }
}

Vo vami preferovanom prostredí (Arduino IDE, Platformio…) naprogramujte Arduino, zapamätajte si port, ku ktorému je pripojené. 

Kontrola 

Otvorte ľubovolný terminálový emulátor (CuteCom, picocom …), otvorte komunikáciu na port s Arduinom pre štandardnú prenosovú rýchlosť 115200 Bd. Vyslaním sekvencie znakov 'D1' a 'D0' by ste mali LED na doske rozsvietiť a zhasnúť. 

Jednoduchý HTTP Server 

HTTP server je štandardná aplikácia v Python-e, okrem bežných modulov vyžaduje len inštaláciu podpory pre komunikáciu cez sériový port a zaradenie do skupiny s právami prístupu k sériovému portu 

$ sudo python -m pip install pyserial
$ sudo usermod -a -G dialout MY_USER_NAME 

V zdrojovom kóde upravte meno portu podľa vašej aktuálnej konfigurácie. 

import serial
import struct
from socketserver import ThreadingMixIn
from http.server import HTTPServer, SimpleHTTPRequestHandler

port = None
port_name = '/dev/ttyACM0' # /dev/ttyUSB0 ...

class BoardHandler(SimpleHTTPRequestHandler):
    def log_message(self, format, *args):
        return

    def do_GET(self):
        global port
        s = self.path.split('/')
        if 'cmd' in s:
            for c in s[2]:
                port.write(struct.pack('B', ord(c)))

            resp = 'ok'
            message = resp.encode()
            self.request.send(message)
        else:
            SimpleHTTPRequestHandler.do_GET(self)

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

def http_server():
    try:
        server = ThreadedHTTPServer(('127.0.0.1', 1111), BoardHandler)
        server.daemon_threads = True
        print( "HTTP Server at port 1111, ^C to exit")
        server.serve_forever()
     except KeyboardInterrupt:
        server.socket.close()
if __name__ == '__main__':
    port = serial.Serial(port_name, 115200)
    http_server()

Server spustíme v konzole: 

$ python server.py

Server štandardne očakáva platnú HTTP požiadavku na porte 1111, defaultne očakáva v adresári súbor index.html, ak sa v texte požiadavky vyskytne 'cmd', pošle nasledujúcu sekvenciu znakov na sériový port. 

Kontrola 

Pripojte Arduino, spustite server a vo vašom www prehliadači ako URL zadajte 127.0.0.1:1111/cmd/D1 a 127.0.0.1:1111/cmd/D0.

LED na doske Arduina by sa mala rozsvietiť a zhasnúť. 

Snap! 

Na záver ešte potrebujeme lokálnu kópiu prostredia Snap! podľa návodu. Celá „inštalácia“ spočíva v stiahnutí z GitHubu do lokálneho adresára. Pre náš server ešte potrebujeme vytvoriť súbor index.html s nasledujúcim obsahom: 

<!DOCTYPE html>
<html>
    <head>
      <title>Redirecting to Snap!</title>
    </head>
    <body>
      <p>If you are not automatically redirected to Snap<i>!</i>,
      <a href="snap.html">please click here.</a> </p>
    </body>
</html>

Náš pracovný adresár má potom nasledujúcu štruktúru 

MyDirectory
   |
   +--- server.py  <- HTTP server source code
   +--- index.html <- redirector file
   |
   +--- snap.html  <- from Snap! install
   +--- Snap-5.1.0 <- Snap! code
          +---
          +---
          ...

Kontrola 

Pripojte Arduino, skontrolujte meno portu server.py a spustite HTTP server. Vo www prehliadači zadajte  127.0.0.1:1111. Vo vašom prehliadači by sa mala spustiť lokálna kópia prostredia Snap!. 

Programovanie Snap! 

Vytvorte nové bloky


a zažite novú úroveň programovania.


Záver a technické poznámky 

Ako už bolo spomenuté v úvode, príspevok popisuje možnosti komunikácie Snap! v tej najjednoduchšej možnej podobe, uvedené programíky si už zrejme každý upraví tak ako bude potrebovať. Bežné Arduíno takto môžete pretvoriť na analogovo-digitálne vstupno-výstupné zaradenie, s pomocou ktorej váš potomok môže riadiť nejakého robota, hrať sa na domáceho meteorológa alebo merať rýchlosť áut na autodráhe. 

Pri nejakých náročnejších pokusoch vyžadujúcich nejaké exaktnejšie časovanie treba brať do úvahy technologické obmedzenia, ako je prenosová rýchlosť, vlastný spôsob komunikácie cez server ako aj to, že Snap! je multithreadingová aplikácia s množstvom vlákien a náhodným prideľovaním času. Autori s týmto obmedzením zrejme počítali, takže v zbierke blokov nájdeme aj špeciálny blok označený ako warp, pomocou ktorého vieme vyhradiť exkluzívne vykonávanie kódu uzatvoreného v tomto bloku.


Výsledok je celkom obstojný, na obrázku je záznam z osciloskopu pre vyššie uvedený program.