Arduino cursus/Dag 3

Uit Lab
< Arduino cursus
Versie door Eelco (overleg | bijdragen) op 23 feb 2018 om 09:38 (→‎NFC-opdrachten)
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Naar navigatie springen Naar zoeken springen
Dag 3 Arduino cursus

Zie ook Regels en richtlijnen
Zie ook Artikelen bewerken

Dag 3 Arduino cursus

Het thema van deze dag is communicatie. We behandelen verschillende vormen van communicatie:

  • communicatie met de host - via de seriële verbinding
    • je kunt op de host ook programma's draaien die met de Arduino communiceren; bijv. Firmata; Processing
  • IR-communicatie (afstandsbesturing)
  • NFC communicatie (NFC chips)
  • radio packet communicatie (RFM69)

Algemene principes van communicatie

Je hebt te maken met twee (of meer) partijen ("agents") die met elkaar communiceren:

  • er moeten goede onderlinge afspraken zijn hoe deze communicatie eruit ziet (protocollen)
  • elk van de betrokken agents is autonoom, en kan in een eigen tempo communiceren (of niet)
    • je kunt op elk moment invoer verwachten;
    • de invoer kan willekeurig lang uitblijven (dit moet de andere verwerking op de Arduino niet blokkeren)

Een communicatieverbinding is kwetsbaar: deze kan om allerlei redenen uitvallen

  • de communicatie kan stoppen door een verbinding die verbroken wordt; of doordat "de andere partij" stopt of erg traag wordt.

De communicatievoorbeelden die we geven zijn gebaseerd op "discrete berichten":

  • seriële communicatie: een opdracht via de Seriële Monitor, eventueel met argumenten;
  • IR communicatie: opdrachten van een afstandsbediening;
  • RFID: opdrachten via RFID-tags
  • Radio: communicatie van pakketten.

Veel communicatiemethodes maken gebruik van een gedeeld medium voor de overdracht van de data. Dit betekent dat de verschillende zenders elkaar in de weg kunnen zitten, en dat je allerlei externe storingen kunt krijgen.

  • in het geval van IR communicatie kun je storingen krijgen van andere IR-bronnen (zoals de zon); deze storing kun je verminderen door gebruik te maken van een gemoduleerd signaal. (De meeste afstandsbedieningen gebruiken LEDs die knipperen op 36 of 38 kHz: zo kun je deze onderscheiden van de zon e.d.)
  • meerdere IR-zenders in één ruimte kunnen elkaar verstoren;
  • meerdere radiozenders kunnen elkaar verstoren; voor de 868MHz band geldt daarom dat een radio niet meer dan 1% van de tijd mag zenden.

In het geval van RFID/NFC (near field communication) wordt met opzet een zwak radiosignaal gebruikt, dat alleen op korte afstand werkt (gewoonlijk enkele cm's). Dit vermindert de externe storingen sterk, maar heeft ook invloed op de manier van gebruik.

Radiocommunicatie is altijd een vorm van broadcast: je moet er rekening mee houden dat deze door anderen afgeluisterd kan worden. Je kunt dit risico verminderen door versleutelde communicatie te gebruiken.

Seriële communicatie (met de host computer)

In de voorgaande lessen hebben we de seriële communicatie gebruikt voor uitvoer naar de host, via de Serial Monitor. Je kunt de Serial Monitor ook gebruiken om opdrachten en andere invoer naar de Arduino te sturen. Het verwerken van tekst-invoer is in het algemeen lastiger dan het versturen van tekst-output: de programma's worden dan ook wat ingewikkelder.

Bij het verwerken van invoer moeten we er rekening mee houden dat communicatie tijd kost: we verwerken deze invoer als deze beschikbaar is, en we laten het Arduino-programma niet blokkeren op invoer die nog niet beschikbaar is. De functie Serial.available() geeft aan of er invoer beschikbaar is: deze zullen we dan ook veelvuldig gebruiken. Bij het verwerken van (tekst)invoer moeten we er bovendien rekening mee houden dat een gebruiker een fout kan maken in de invoer: we moeten er van te voren over nadenken wat we in zo'n geval doen.

Let op! De tekstinvoer vanuit de Serial Monitor is gebufferd: toetsaanslagen worden niet direct doorgestuurd, maar de invoer in de invoerregel wordt pas naar de Arduino gestuurd door een Return of het gebruik van de "Verstuur"-knop.

Serial input-opdrachten

Commando's naar de Arduino geven we een vaste structuur. We behandelen hier twee voorbeelden; deze kun je voor allerlei toepassingen gebruiken.

  1. commando's bestaan uit enkelvoudige tekens
    1. bijvoorbeeld: "1" om een LED in te schakelen, "0" om deze uit te schakelen.
  2. commando's bestaan uit een enkelvoudig letterteken gevolgd door een (niet-negatief) getal.
    1. bijvoorbeeld: "a" met een getal om de lichtsterkte van de LED aan te geven, "s" om een servo aan te sturen.

Dit geeft in combinatie met de uitvoermogelijkheden van de eerdere lessen veel mogelijke toepassingen.

Omschrijving Opdracht programma
input van enkelvoudige tekens Arduino cursus/Serial-input-0 serial-input-0a
serial-input-0b
input van letter met getal Arduino cursus/Serial-input-1 serial-input-1

Communicatie met andere host-programma's

De seriële communicatie met de host kun je ook gebruiken om de Arduino door andere host-programma's te laten besturen. Op de Arduino zelf gebruik je dan meestal een universeel besturingsprogramma, zoals Firmata. In dit moet je de Arduino wel met een USB-kabel aan de host verbinden. Enkele voorbeelden van host-programma's waarmee je een Arduino kunt besturen:

Communicatie met andere Arduino's

In principe kun je via een seriële verbinding ook met andere Arduino's communiceren. De mogelijkheden van de Arduino Uno hiervoor zijn beperkt: er is maar één seriële verbinding in hardware beschikbaar, deze wordt gebruikt voor de communicatie met de host. Andere Arduino-versies hebben soms meerdere seriële verbindingen.

IR communicatie

Met behulp van een normale afstandsbediening en een IR ontvanger op je Arduino kun je je Arduino op afstand bedienen. Hiermee kun je bijvoorbeeld een robotkarretje maken dat je op afstand bestuurt.

Met een IR-led kun je je Arduino gebruiken als IR zender, bijvoorbeeld voor het automatisch bedienen van een apparaat met een IR ontvanger (TV, enz.)

Als je meerdere Arduino's hebt met elk een IR zender en ontvanger, dan kunnen deze met elkaar communiceren via IR.

IR opdrachten

De eerste opdracht is bedoeld om de IR-ontvanger te testen, in combinatie met een afstandsbediening. Je kunt hiermee nagaan welke codes de afstandsbediening stuurt voor de verschillende toetsen. Als je de codes van de afstandsbediening weet, kun je via de afstandsbediening opdrachten geven aan de Arduino. Je gebruikt dit in programma IRrecvLED-0 om een LED aan- en uit te schakelen. Voor het ontvangen van meerdere IR-codes kun je een switch-statement gebruiken. We demonstreren dit in programma IRrecvLED-1.

In de opdracht Arduino cursus/IR-zender-0 stuur je de code van een afstandsbediening via een IR-LED naar een IR-ontvanger op een andere Arduino. Op deze andere Arduino gebruik je het programma IRrecvLED van de vorige opdracht, voor het aan- en uitzetten van een LED.

Omschrijving Opdracht programma
Testen van IR ontvanger Arduino cursus/IR-ontvanger-0
IR-commando's ontvangen en verwerken Arduino cursus/IR-ontvanger-1 IRrecvLED
Arduino cursus/IR-ontvanger-1 IRrecvLED-1
IR-commando's versturen Arduino cursus/IR-zender-0 IRsendLED

Opmerkingen

Gebruik van pinnen

De IR-library geeft niet veel vrijheid in de keuze van de pinnen:

  • Arduino pin 3 is de enige pin voor het aansturen van een IR-led


Idempotente opdrachten

Een afstandsbediening kan bij het indrukken van een toets dezelfde code herhaald versturen. Het is dan handig om de functies van de afstandsbediening "idempotent" te maken: voor een idempotente opdracht maakt het niet uit of je deze eenmaal of vaker geeft.

  • voorbeelden van een idempotente opdrachten: schakel LED uit; zet LED-lichtsterkte op 50%
  • voorbeelden van niet-idempotente opdrachten: schakel LED om (van aan naar uit of omgekeerd); halveer de huidige LED-lichtsterkte.

In het geval van idempotente opdrachten gebruik je verschillende toetsen voor verschillende functies.

IR codes (NEC)

De NEC-codering van een eenvoudige afstandsbediening:

toets code toets code
CH- FFA25D
CH FF629D 0 FF6897
CH+ FFE21D 1 FF30CF
<< FF22DD 2 FF18E7
> FFC23D 3 FF7A85
>> FF02FD 4 FF10EF
- FFE01F 5 FF38C7
+ FFA857 6 FF5AA5
EQ FF906F 7 FF42BD
100+ FF9867 8 FF48B5
200+ FFB04F 9 FF52AD

Merk op dat de eerste byte de inverse is van de tweede byte; in andere gevallen kan het eerste byte de code van het apparaat bevatten, om de TV-afstandsbediening te kunnen onderscheiden van de radio-afstandsbediening enz.

IR zenden met meer vermogen

In de opstelling van Arduino cursus/IR-zender-0 heeft de IR LED weinig vermogen: je kunt dus maar een korte afstand overbruggen. Als de afstand groter wordt, ontvang je niet meer de juiste codering. Voor een krachtiger LED-signaal kun je de LED met een transistor aansturen. In dat geval kun je een kleinere serieweerstand gebruiken (bijv. 47Ohm): de meeste IR-leds kunnen ca. 100mA verwerken; of je kunt die weglaten, omdat de IR-LED steeds maar kort aangestuurd wordt.

RFID/NFC communicatie

Bij RFID/NFC (near field communication) gaat het om communicatie over korte afstand - gewoonlijk enkele cm's. Deze communicatie kan ook plaatsvinden met een passief device (dus zonder batterij), bijvoorbeeld een chipkaart (OV chipkaart; bankkaart; e.d.). Ook de moderne smartphones hebben vaak mogelijkheden voor NFC-communicatie.

De zender zendt niet alleen een informatiesignaal naar de chipkaart, maar ook een hoeveelheid energie. De ontvanger gebruikt deze energie om het bericht te ontvangen, te verwerken, en een reactie te versturen. Dit allemaal in tijdsbestek van ca. 0.1sec.

NFC-opdrachten

De eerste opdracht is bedoeld voor het testen van de RFID/NFC-lezer in combinatie met enkele verschillende kaarten. Als resultaat krijg je de ID's van de kaarten te zien, en eventueel een gedeelte van de inhoud (als die niet versleuteld is).

Met NFC-kaarten kun je opdrachten geven aan een Arduino: verschillende kaarten staan dan voor verschillende opdrachten. Hiervoor heb je alleen de IDs van de betrokken kaarten nodig. In de tweede opdracht gebruik je één kaart om een LED aan te zetten, en een andere kaart om de LED uit te schakelen.

Omschrijving Opdracht library programma
NFC-test, lezen van kaarten Arduino cursus/NFC-reader nfc.zip nfc_mifare_mf1s50_reader
NFC: aan- en uitzetten van LED Arduino cursus/NFC-reader nfc.zip nfc_led

Je kunt ook data schrijven naar een NFC kaart, of de data op een NFC-kaart aanpassen. Zie voor een voorbeeld: nfc->nfc_mifare_mf1s50_reader. Dit programma bevat in commentaar de code voor het schrijven van een blok. Door de commentaarhaken /* en */ te verwijderen, kun je die code actief maken.

Elechouse NFC-reader

De opdracht is uitgewerkt voor de Elechouse NFC reader. Deze kun je aansturen via I2C.

Let op! Je moet op het bordje met kleine schakelaars instellen welk interface je gebruikt. De default-instellingen zijn niet voor I2C: die moet je dus aanpassen. De juiste instelling staat op de kaart. Voor de documentatie, zie:

We gebruiken deze laatstgenoemde software voor de opdrachten. De driver-software hebben we op één plaats aangepast, in nfc.h, vanwege een conflict met de Arduino-types:

//typedef uint16_t u16;

De aangepaste library is te vinden op: https://infvo.nl/labfiles/arduino/programs/libraries/nfc/

NFC documentatie

Documentatie van MiFare (Classic) kaarten:

De Adafruit-tutorial bevat ook de nodige links naar NFC-kaarten e.d:

RFM69 radio

De RFM69-radio is geschikt voor pakketcommunicatie in de 868MHz band. Deze heeft een bereik van enkele tientallen meters in de bebouwde omgeving; de high-power variant heeft een bereik van enkele 100-en meters met vrij zicht. RFM69-radio's kunnen verschillende kanalen gebruiken in de 868MHz band.

Om conflicten met andere gebruikers van de 868MHz-band te vermijden mag een zender deze band max. 1% van de tijd gebruiken.

Wij gebruiken deze zender met een bitsnelheid van ca. 50 kbits/sec; de maximale grootte van een enkel pakket is ca. 64 bytes (ca. 500 bits). Dit betekent dat de tijd voor een pakket ca. 500/50.000 sec is, ofwel 1/100sec. We mogen dan niet vaker dan eens per seconde een dergelijk pakket versturen.

Elke RFM69-radio heeft een node-ID; deze stel je via de software in, bij voorkeur op een unieke waarde. Een RFM69-pakket bevat de node-ID van de bestemming. De waarde 0 als bestemming geeft een broadcast aan: dit pakket wordt door alle nodes ontvangen.

Radio-opdrachten

omschrijving opdracht library programma
RFM69 radio-test Arduino cursus/Radio-0 rf69.zip rf69demo
RFM69 zenden van pakketten Arduino cursus/Radio-1 rf69.zip rf69_temp_node
RFM69 ontvangen van pakketten ... ... ...
  • Arduino cursus/Radio-0: Deze opdracht is bedoeld om de werking van de RFM69-radio te testen. Deze gaat uit van het gebruik van meerdere nodes die een broadcast uitvoeren. De ontvangen berichten worden via de Serial Monitor getoond.
  • Arduino cursus/Radio-1: In deze opdracht verstuurt een Arduino-node via de radio de waarde van een lokale sensor. Als sensor gebruiken we de temperatuursensor.
  • Arduino cursus/Radio-2: In deze opdracht ontvangt een Arduino-node een opdracht: als voorbeeld gebruiken we deze om een LED aan- en uit te schakelen.

RFM69-libraries

Er zijn meerdere libraries voor radio-communicatie, zie hieronder. We gebruiken in de opdrachten de Jeelabs/Embello RF69-library: deze is eenvoudig in het gebruik.

Software

De software voor deze opdrachten is te vinden op: programma's

Gebruikte hardware

onderdeel datasheet link naar leverancier prijs
IR LED https://www.tinytronics.nl/shop/nl/verlichting/led-los/ir-led-940nm-5mm-helder Euro 0,20
IR receiver 38 kHz https://www.tinytronics.nl/shop/nl/communicatie/infrarood/hx1838-ir-ontvanger-38khz Euro 0,75
IR ontvanger 36 kHz TSOP34836 (= SFH5110-36) https://www.eoo-bv.nl/opto-elektronica/8052-tsop34836.html Euro 0,60
IR afstandsbediening https://www.tinytronics.nl/shop/nl/communicatie/infrarood/kleine-ir-afstandsbediening Euro 1,00
RFID-NFC kit Elechouse datasheet https://www.tinytronics.nl/shop/nl/communicatie/rf(id)-wifi-bt/rfid-nfc-kit-pn532-met-s50-kaart-en-s50-key-tag Euro 8,00
RF69HCW breakout Adafruit tutorial https://www.sossolutions.nl/3070-adafruit-rfm69hcw-transceiver-radio-breakout-868-or-915-mhz Euro 12,95
RFM69CW breakout JeeLabs Arduino example https://www.digitalsmarties.net/products/rfm-board Euro 12,00