Internet-of-things i undervisningen med MicroPython

Den første start når man skal lære noget helt nyt er altid svær, og hård, så jo lettere vi kan gøre de første skridt, jo bedre. En af måderne er at tage udgangspunkt i noget af hvor nogle af elevens eksisterende færdigheder kan komme i spil, så ikke alt føles nyt og fremmed. Ved at inddrage et fysiske aspekt undervisningen i datalogi/informatik kan eleven bruge sine færdigheder til at tegne, bygge, klippeklistre og så videre, til at understøtte læringsprocessen.

Internet-of-things enheder er i bund og grund fysiske objekter eller enheder, hvor der er koblet et digitalt element på, i et forsøg på at gøre dem "smartere". Eksempler inkluderer sporingsenhed til cykler, digitalt styrede termostater, fitness-armbånd, overvågning af diverse processer i industrien, og meget mere.

I denne artikel beskriver jeg et setup hvor man relativt nemt kan lave internetforbundne enheder, der har et fysisk element, og hvor eleverne selv kan designe og bygge deres prototyper. Ved at koble dem til internettet kan de også blive mere virkelighedsnære, da de kan hente/sende live data.

Tangible computing og læring

Inden vi kommer til det tekniske vil jeg først lige bruge lidt flere ord på hvad fysiske objekter kan give af fordele i undervisningen. Inden for datalogien kalder vi user-interfaces hvor man benytter noget fysisk håndgribeligt til at interagere for tangible computing, eller tangible user-interfaces, og de står i kontrast til de mere almindelige grafiske user-interfaces baseret på pixels og mus/tastatur. I et tangible user-interface bliver data noget fysisk som man kan bruge sine hænder til at interagere med.

Fordelen er at vi ved at gøre det fysisk kan bruge flere af vores sanser, og så har det også en social funktion. Vi opnår ikke bare øget motivation, da vi taler ind til deres eksisterende interesser (som nævnt ovenfor), men også læringsmæssige fordele for eleverne. Forskningsartiklen Art and Artifact of Children's Designing: A Situated Cognition Perspective (Roth, 1996) præsenterer et par forskellige observationer:

  1. Fysiske objekter tillader at man kan tænke ved at håndtere objektet med hænderne, det giver mulighed for at eleven kan integrere handling og tænkning.
  2. Design af fysiske objekter har en vigtig social funktion: de gør designopgaver til et fælles projekt, eleverne kan bruge til at engagere hinanden, og fokuserer elevernes opmærksomhed og kommunikation. Samtidig kan det repræsentere viden på en fysisk form, som kan bruges som holdepunkt for elevernes diskussioner om design og det emne de nu er i gang med at lære om.
  3. Fysiske objekter gav også mulighed for at eleven kan begynde at bruge nye begreber i deres sprog allerede inden de helt forstået hvordan det skal bruges korrekt. Selv om de bruger ordene forkert, kan de samtidig manipulere objektet og gestikulere, så andre alligevel kan forstå hvad de mener. Over tid udvikles et mere konsistent sprogbrug.

Har du bud på andre fordele ved at integrere design af fysiske objekter i undervisningen, så skriv gerne en kommentar i bunden af indlægget.

Et eksempel på sådan et tangible user-interface som vi har brugt i en undervisningssituation kan ses i denne video:

CryptoSphere: Et tangible design vi har brugt i undervisning. Man vælger krypteringskode ved at rotere, og sender ved at ryste. Udviklet af Christopher Belhage som del af hans speciale. Læs mere på Femtech.dk

Microcontrollere og MicroPython

Nu skal vi til det tekniske. En microcontroller er basalt set en programmerbar mini computer, der består af CPU, hukommelse og input/output porte til sensorer/aktuatorer. Microcontrolleren ESP8266 og den nyere ESP32 er pt. et godt valg, primært fordi de er billige og de giver mulighed for WiFi forbindelse, hvilket gør dem idéelle til Internet-of-things projekter. De kan programmeres i Arduino IDE'et i C++, men fornyeligt er der blevet lavet en variant af Python der kan køre på dem, der hedder MicroPython. Sidst i artiklen sammenligner jeg fordele/ulemper ved at vælge hhv. Arduino og MicroPython.

Sidste sommer gjorde jeg det muligt at interagere med MicroPython enheder via begynder teksteditoren Mu, og min udvidelse er nu en del af seneste alpha-release af Mu der kan downloades her: https://github.com/mu-editor/mu/releases/tag/1.1.0-alpha.1

I denne 1 min screencast kan man se hvor nemt det er at kode et lille "Blink"-program, med LED tilsluttet pin 5 og hvordan man interagerer via interaktiv Python der kører på microcontrolleren:

Screencast af brug af Mu-editoren

LED strips

LED-strips som dem jeg bruger i videoen ovenfor er baseret på såkaldte WS2812B LED'er, der har 3 små farvede LED'er i rød, grøn, blå, og som kan styres individuelt og blandes sammen. De tilsluttes via en enkel datapin, og almindelig jævnstrøm (3-5V). Adafruit har døbt deres mærke af LED strips for "NeoPixels" og det er blevet den almindelige betegnelse for alle trods mærke, da det ligger noget bedre i munden end "WS2812B". Adafruit har en NeoPixel Überguide der er værd at læse, hvis man vil vide mere: https://learn.adafruit.com/adafruit-neopixel-uberguide/

Programmeringsmæssigt i MicroPython, kan LED-strippen programmeres som et array af RGB-værdier, med en speciel funktion "write", som sender arrayet afsted til LED-strippen hvor de bliver vist. Koden nedenfor skaber en lille regnbue med 7 forskellige farver på LED-strippen. Først defineres hvor lang LED-strippen er og hvor den er tilsluttet. Dernæst defineres hvilke LED'er der skal tændes med hvilken farve, og til sidst kaldes "write"-funktionen der før LED'erne i gang.

import machine
import neopixel

# LED strip tilsluttet Pin 16, med 30 LED'er
led_strip = neopixel.NeoPixel(machine.Pin(16), 30)

# Sæt farver
led_strip[0] = (255, 0, 0)   # rød
led_strip[1] = (255, 75, 0)  # orange
led_strip[2] = (255, 255, 0) # gul
led_strip[3] = (0, 255, 0)   # grøn
led_strip[4] = (0, 255, 127) # tyrkis
led_strip[5] = (0, 0, 255)   # blå
led_strip[6] = (143, 0, 255) # lilla

# Send til
led_strip.write()

Når først elever har fået forståelse for koden ovenfor kan de selv gå på opdagelse med hvad man kan bruge det til, de leger og finder på. Hurtigt kommer de til et punkt hvor de får idéer til ting hvor de stiller spørgsmål om hvordan de laver pauser, så de kan lave animationer, hvordan de slukker LED'er igen, og de kan måske næsten selv opfinde for-løkker, inden man fortæller dem syntaksen for den.

Wifi-forbindelse

Det indbyggede WiFi i MicroPython er lidt besværligt at bruge i undervisningen er min erfaring, så jeg har kodet et lille wifi-modul, som man kan overføre og dermed gøre det ultra simpelt at få koblet sine enheder på WiFi. Download det her: wifi.py

Når modulet er overført til microcontrolleren via "Files"-dialogen i Mu, så bruges bare følgende kode til at logge på internettet:

import wifi
wifi.connect("wifi-essid", "wifi-password")

Derefter kan man begynde at kommunikere via fx requests-biblioteket, hvor man kan lave almindelige HTTP-requests, og kommunikere med API'er. Se eksempler på det i næste sektion.

Datakilder

For at illustrere hvordan det kan bruges, kan jeg vise hvordan man kan hente data omkring nuværende CO2 udledning fra danske kraftværker via EnergiDataService.dk, hvor EnergiNet Danmark deler data omkring aktuel, historisk forbrug af energi, samt forudsigelser. Data trækkes i dette tilfælde fra tabellen co2emis.

import wifi
import urequests

status = wifi.connect("wifi-essid", "wifi-password")

# Seneste forureningsdata fra region DK2 (Sjælland)
# Resultatet er i gram CO2 per produceret kWh
# Andre drivhusgasser er også inkluderet, 
# men konverteret til gram CO2 ifht. deres forureningsgrad
query = ('SELECT "CO2Emission", "Minutes5DK"'
         'FROM "co2emis"'
         'WHERE "PriceArea"=\'DK2\''
         'ORDER BY "Minutes5DK"'
         'DESC LIMIT 1')

# Kør forespørgsel, hent data, indlæs JSON
requestUrl = 'http://api.energidataservice.dk/datastore_search_sql?sql=' + query
encodedUrl = requestUrl.replace(" ", "%20")
response = urequests.get(encodedUrl).json()

# Tilgå tidspunkt og CO2-værdi for første (eneste) resultat
records = response["result"]["records"]
timestamp = records[0]["Minutes5DK"]
co2level = records[0]["CO2Emission"]

print("Time:", timestamp)
print("CO2 level:", co2level)

På lignende vis kan man hente data fra mange andre kilder, fx Rejseplanens API, OpenWeatherMap, og mange mange andre, her er en lang liste af åbne API'er man kan gå på opdagelse i - ikke alle lige brugbare: https://github.com/toddmotto/public-apis

Det er også muligt at måle data med sensorer, og logge det til skyen, så det så kan analyseres. Til at logge data kan man fx bruge IoTPlotter.com, eller andre lignende services som fx ThingSpeak. Jeg vil ikke komme ind på tilslutning af sensorer, da det er forskelligt fra sensor til sensor, og kræver forskellige biblioteker fra sensor til sensor. Jeg har allerede fået tilsluttet knapper og sensorer som fx partikelsensor, mikrofon (fx til støjsensor), gyroskop og accelerometer. Sig til hvis du vil noget specielt, så kan jeg godt give hints og hjælpe hvis noget specielt ønskes.

Hardware indkøb

Jeg vil anbefale følgende hardware:

Har du brug for flere inputs/outputs, så er det måske værd at se på ESP32 Thing fra Sparkfun, den er dog en smule større og prisen er noget højere end prisen for en WeMos D1 Mini.

Installation af MicroPython

Microcontrollerne ovenfor kommer IKKE med MicroPython installeret. Det skal man selv gøre. Jeg håber på et tidspunkt at det bliver noget vi kan få integreret i Mu-editoren, så den automatisk downloader og overfører firmware, hvis det ikke findes allerede.

Der ligger en guide her der desværre kræver noget kommandolinje-arbejde for at overføre MicroPython: https://docs.micropython.org/en/latest/esp8266/tutorial/

Kontakt mig gerne hvis det volder problemer, så hjælper jeg gerne. Alternativt er der et GUI-program (ikke kommandolinje), der kan gøre det samme, som jeg dog ikke har fået testet: https://github.com/Rodmg/esptool-gui/releases

Sig til hvis det driller, så hjælper jeg gerne!

Alternativer til MicroPython

Jeg gik oprindeligt i gang med det her projekt, fordi jeg skulle undervise på det Kickstart-kursus i programmering jeg tidligere har omtalt her på bloggen, og jeg havde brug for at kunne bruge samme programmeringssprog i både første uge om grafik og simulering, og i anden uge hvor fokus var på denne type internet-of-things objekter. Det mest udbredte valg, som de fleste nok går med er at benytte Processing og Arduino-platformene. Jeg følte dog at der var mange udfordringer forbundet med at gå den vej. For det første benyttes der to forskellige sprog på de to platforme (Java og C++), og for det andet oplever jeg stadig mange problemer med Arduino både teknisk og didaktisk, trods dets 10 år på bagen. Jeg følte det derfor ikke velegnet til et kursus jeg gerne skal kunne skalere op til mere end 100 elever samtidig (som jeg skal i år).

Arduino's didaktiske problemer handler blandt andet om at bibliotekerne til sensorer, LED-strips m.m. ofte ikke er skrevet med simplicitet i mente, dårlige fejlmeddelelser, og langsomme udviklingsprocess pga. compilering og overførselstrin der giver mange lange pauser, hvor det med MicroPython bare kan køres direkte.  Der er også tekniske problemer med udviklingsmiljøet, der ikke på samme måde nemt opdager tilsluttet hardware, ikke har understøttelse for alle nyere microcontrollers indbygget og nogle gange blokerer, så nye programmer ikke kan overføres.

Et andet alternativ er Adafruit's boards der understøtter CircuitPython, men så vidt jeg ved har de endnu ikke understøttelse for WiFi-forbindelse, hvilket gør dem meget begrænsede i forhold til hvordan jeg i hvert fald gerne vil bruge dem. CircuitPython fungerer også med Mu-editoren.

Et tredje alternativ kunne være Raspberry Pi, men for mig er der med Raspberry Pi den ulempe at de kræver et helt operativsystem, og at der skal mange skridt til før man kan gå i gang med at kode dem. Der mangler basalt set en nem måde at overføre kode til dem fra sin egen computer via USB, og som ikke kræver at de studerende først lærer om SSH eller skal tilslutte ekstern skærm og tastatur.

Fremtiden

Jeg håber at MicroPython begynder at blive mere brugt i undervisningsverdenen, da det allerede nu virker som noget der kan blive en meget mere stabil platform end Arduino. Selv har jeg et håb om at finde tid til at gøre det nemmere at installere MicroPython firmwaren, så det primært kan ske automatisk, og man ikke skal bruge kommandolinje. Derudover, vil jeg gerne have bygget et samlet bibliotek der der kan aflæse diverse forskellige sensorer, så man kan bruge MicroPython til endnu flere projekter (fx sensorerne i TinkerKit til micro:bit der også fint kan bruges sammen med MicroPython).

Derudover har jeg netop medvirket i et forskningseksperiment hvor MicroPython og LED-strips også var i brug. Resultaterne af den undersøgelse, skal jeg nok vende tilbage til når det er udgivet.

Jeg håber det var brugbart for dig, giv mig gerne noget feedback nedenfor, eller stil spørgsmål, hvis der er noget der er uklart eller jeg ikke har forklaret godt nok. Tak til Jeppe Eimose Waagstein, der arbejder hos Bornholms Energi & Forsyning for idéen om at bruge CO2-data.