Bewegingsdetector

Infraroodsensoren zijn sensoren die gebruik maken van infrarood licht. Ze worden voor verschillende doeleinden gebruikt, zoals het detecteren van beweging, ontvangers voor IrDA-systemen, contactloze temperatuursensoren en het maken van afstandschattingen. Beeldvormende infraroodsensoren worden bovendien ingezet als nachtzichtapparatuur.

Werking PIR

Veelgebruikt wordt de passieve infraroodsensor (PIR) voor bewegingsdetectie. Je hebt ze wellicht al gezien, ze worden gebruikt in alarmsystemen (de sensoren in de hoeken van kamers zijn meestal PIR sensors). Alle voorwerpen die een temperatuur heeft van meer dan het absolute nulpunt zendt infrarood licht uit. Infrarood licht is niet zichtbaar voor het menselijk oog, maar kan wel door elektronica gedetecteerd worden.

Een sensor is passief als deze geen licht uitstraalt om beweging te detecteren. Het past zich aan de infrarood straling van een kamer aan en reageert op veranderingen daarin. Elk bewegend voorwerp zal deze infrarood straling beïnvloeden en dus door de PIR opgemerkt worden.

We houden ons niet bezig met de interne werking van een PIR sensor, wel zijn we geïnteresseerd in hoe we een PIR sensor op de Raspberry Pi kunnen aansluiten.

PIR sensor aansluiten

Voor je de Raspberry Pi opstart, verbind je de PIR sensor met de Pi. Let daarbij goed op de aansluitingen, niet op elke PIR staan de aansluitingen op dezelfde plaats en/of volgorde.

Met behulp van drie female-to-female draadverbindingen verbind je de PIR sensor met de Raspberry Pi:

PIR aansluiten

De PIR bewegingssensor testen

Zorg dat Raspberry Pi OS bijgewerkt is.

We gaan een script gebruiken om wat code te schrijven waarbij we tekst laten verschijnen bij het detecteren van beweging.

Start Geany (Menu > Programmeren > Geany), maak een nieuw Bash script (Bestand > Opslaan als met de bestandsnaam beweging.sh) en typ de volgende code:

#!/bin/bash
# Eerst definiëren we enkele functies
# Functie waarmee je wacht op beweging:
wait_for_motion () {
  while :
  do
    pinctrl get grep -" hi "
    if $? -eq ]; then
      break
    fi
    sleep 1
  done
}
# Functie waarmee je wacht tot er geen beweging meer is
wait_for_no_motion () {
  while :
  do
    pinctrl get grep -" lo "
    if $? -eq ]; then
      break
    fi
    sleep 1
  done
}
# Hier begint ons programma
# Oneindig lang worden bewegingen gemeld
# Breek het programma af met Ctrl+c
while :
do
  wait_for_motion
  echo "Beweging waargenomen"
  wait_for_no_motion
  echo "Geen beweging"
done

Hoe is het script opgebouwd? Eerst schrijven we functies om het script te laten wachten op beweging of juist geen beweging. De PIR sensor meldt beweging op GPIO pen 4. De status van GPIO pen vier kan je met de volgende opdracht opvragen:

pi@raspberrypi:~ $ pinctrl get 4
4: ip    pu | lo // GPIO_GCLK/GPIO4 = input

Dit was zonder dat de PIR beweging detecteerde, met beweging krijgen we:

pi@raspberrypi:~ $ pinctrl get 4
4: ip    pu | hi // GPIO_GCLK/GPIO4 = input

M.a.w. de PIR-uitgang krijgt bij beweging de waarde hi, zonder beweging de waarde lo.

Dit moet constant gebeuren en gebruiken daarvoor een while lus. In de lus controleren we GPIO pen 4 op beweging ( hi ). Als dit zo is ($? gelijk aan 0) wordt de lus verlaten (break). Als dit niet zo is, wordt 1 seconde gewacht (sleep 1) en wordt de lus opnieuw uitgevoerd. M.a.w. de functie is pas klaar als er beweging (eerste functie) of juist geen beweging (tweede functie) werd waargenomen.

De sleep opdracht zorgt dat ons script 1 seconden niets doet, waardoor andere programma's en het besturingssysteem andere taken kunnen uitvoeren. Zonder de sleep opdracht zou alle processorkracht naar ons script gaan en de Raspberry Pi vastlopen.

Ook ons programma bestaat uit een eindeloze lus. Daarin wachten we met behulp van onze functies respectievelijk op beweging en geen beweging waarbij we dit telkens melden (echo). De programmalus onderbreken we manueel met Ctrl+c en het script wordt beëindigd.

Sla het bestand op en voer in een terminal de volgende opdracht uit om het script te kunnen uitvoeren:

pi@raspberrypi:~ $ chmod +x beweging.sh

Activeer Geany terug en druk F5 om het programma te starten.

Telkens wanneer de PIR sensor beweging detecteert verschijnt de tekst Beweging waargenomen! in het terminal venster. Indien er geen beweging meer wordt opgemerkt, verschijnt de tekst Geen beweging!. Druk Ctrl+c om het programma af te sluiten.

PIR potentiometers Op de PIR sensor staan twee oranje componenten die je met een Philips schroevendraaier kunt aanpassen. Dit zijn potentiometers en ze laten toe de gevoeligheid en de detectievertraging van de sensor in te stellen. Je begint meestal met een maximale gevoeligheid en de kortste detectievertraging. De gevoeligheid regelt de afstand waarop de sensor nog reageert (van 3 tot 7 meter, in wijzerzin draaien om te vergroten). De detectie vertraging regel je tussen de 0,3 en 600 seconden (in wijzerzin draaien om te vergroten)

Praktijk opdracht
  1. Schakel de Raspberry Pi uit en verbindt de Pi Camera met de Raspberry Pi.
  2. Start de Raspberry Pi en zorg dat de Pi Camera werkt. M.a.w. installeer de rpicam opdrachten en neem een foto.
  3. Nu kunnen we de Pi Camera inzetten om bij het detecteren van beweging een opname te maken. We beginnen met het weergeven van een voorvertoning bij een bewegingsdetectie. De functies blijven onveranderd aanwezig. Binnen de while lus starten we een voorvertoning bij elke bewegingsdetectie, m.a.w. pas het volgende programma-onderdeel aan:

    # Hier begint ons programma
    # Oneindig lang worden bewegingen gemeld
    # Breek het programma af met Ctrl+c
    timeout=4
    preview="0,50,640,360"
    while :
    do
      wait_for_motion
      rpicam-hello -t $((timeout*1000)) -p $preview
      wait_for_no_motion
      echo "Geen beweging"
    done

  4. Met wat meer code kunnen we een opname maken om later te bekijken. Zo wil je bij meerdere indringers in de kamer, ze allemaal vastleggen en niet alleen de laatste. Om dit te realiseren, moeten we voor elke opname een andere bestandsnaam hebben. De eenvoudigste en veiligste is een naam te maken die bestaat uit de datum en tijd van de opname.

    Een voorbeeld: de bestandsnaam 2023-12-08_18.41.34.h264 wordt gebruikt voor een opname gemaakt op 12 december 2023 om 18u41m34s. Dit gebruikt het formaat YEAR-MONTH-DAY_HOUR.MINUTE.SECOND.h264 dat ook door YouTube wordt gebruikt.

    Daarvoor gebruiken we de dateopdracht en schrijven we code om een bestandsnaam met een datum en tijd te genereren. Daarna kan je de opname starten met de aangemaakte bestandsnaam. Juist zoals dat ging met het starten van de voorvertoning:

    # Hier begint ons programma
    # Oneindig lang worden bewegingen gemeld
    # Breek het programma af met Ctrl+c
    timeout=4
    preview="0,50,640,360"
    while :
    do
      wait_for_motion
      bestandsnaam=$(date +"%Y-%m-%d_%H.%M.%S.h264")
      rpicam-vid -t $((timeout*1000)) -p $preview -o $bestandsnaam
      wait_for_no_motion
      echo "Geen beweging"
    done

    Test het programma en laat een paar opnames maken.
  5. Test de opnames in de terminal met de opdracht ffplay <bestandsnaam>, een voorbeeld:
    pi@raspberrypi:~ $ ffplay -autoexit 2023-12-08_18.59.05.h264 
    ffplay version 5.1.4-0+rpt1+deb12u1 Copyright (c) 2003-2023 the FFmpeg developers
      built with gcc 12 (Debian 12.2.0-14)
      configuration: --prefix=/usr --extra-version=0+rpt1+deb12u1 --toolchain=hardened --incdir=/usr/include/aarch64-linux-gnu --enable-gpl --disable-stripping --disable-mmal --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sand --enable-sdl2 --disable-sndio --enable-libjxl --enable-neon --enable-v4l2-request --enable-libudev --enable-epoxy --libdir=/usr/lib/aarch64-linux-gnu --arch=arm64 --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-vout-drm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
      libavutil      57. 28.100 / 57. 28.100
      libavcodec     59. 37.100 / 59. 37.100
      libavformat    59. 27.100 / 59. 27.100
      libavdevice    59.  7.100 / 59.  7.100
      libavfilter     8. 44.100 /  8. 44.100
      libswscale      6.  7.100 /  6.  7.100
      libswresample   4.  7.100 /  4.  7.100
      libpostproc    56.  6.100 / 56.  6.100
    Input #0, h264, from '2023-12-08_18.59.05.h264':B sq=    0B f=0/0   
      Duration: N/A, bitrate: N/A
      Stream #0:0: Video: h264 (High), yuv420p(progressive), 640x480, 30 fps, 30 tbr, 1200k tbn
        nan M-V:    nan fd=   1 aq=    0KB vq=    0KB sq=    0B f=0/0
  6. Soms verloopt de opname niet zo onopvallend. Soms wordt bij elke opname een rode led op de Pi Camera actief, dit valt enorm op. Deze led kan je uitschakelen in het configuratiebestand /boot/config.txt van de Raspberry Pi. Open als systeembeheerder dit configuratiebestand
    pi@raspberrypi:~ $ sudo nano /boot/config.txt
    en voeg de volgende regel toe:
    disable_camera_led=1
    Sla de aanpassing op en herstart de Pi om de nieuwe instelling te activeren. Test of alles nog werkt.
  7. Voor een bepaalde toepassing bestaan soms meerdere oplossingen. Je moet dus voor je aan iets begint, nadenken over hoe je het gaat aanpakken. Hou rekening met jouw eigen vaardigheden, zo zal een handige Harry eerder voor een hardware oplossing kiezen, een programmeur (sterk in logisch denken) kiest eerder voor een software oplossing. Ga ook op zoek naar reeds bestaande oplossingen, de meeste bestaande oplossingen, zeker als die open source zijn, kan je verder uitbouwen om te voldoen aan jouw eigen noden. We gaan het project om beweging te detecteren helemaal omgooien. We gebruiken minder hardware en vervangen die door software. Schakel de Raspberry Pi daarvoor eerst uit en koppel de PIR sensor los.
  8. Start de Raspberry Pi opnieuw op.
  9. We gaan de Pi Camera inzetten als bewegingsdetector. Het gebruik van de Pi Camera heeft zowel voordelen als nadelen:

    Nadelen:

    • Je moet de videobeelden afkomstig van de Pi Camera analyseren om beweging te detecteren. De bewegingsdetectie wordt dus verzorgt door software en belast de processor. Een PIR belast de processor niet.
    • De Pi Camera werkt niet in het donker. Een PIR werkt met infrarood en dus ook in het donker. Met een NoIR Pi Camera en infraroodverlichting werkt het wel.

    Voordelen:

    • Je kunt de bewegingsdetectie eenvoudiger instellen. Zo kan je het te controleren gebied als video of foto bekijken. De gevoeligheid en andere parameters kan je via de software instellen en niet op de PIR zelf. Belangrijk als de bewegingsdetector op een moeilijk te bereiken plaats staat.
    • Je kunt de Pi Camera ook gebruiken om opnames te maken. M.a.w. je hebt dan maar één hardware-uitbreiding nodig, nml. de Pi Camera.
  10. Om dit te realiseren, gebruiken we postProcessing (zie Pi Camera). We gaan ook elke beweging opnemen en dus niet langer wachten tot er geen beweging meer is. M.a.w. de functie wait_for_no_motion wordt overbodig. Het nieuwe script wordt dan:

    #!/bin/bash
    # Eerst definiëren we enkele instellingen (constanten)
    timeout=4
    preview="0,50,640,360"
    motion=$(cat << EOF
    {
        "motion_detect" :
        {
        "roi_x" : 0.1,
        "roi_y" : 0.1,
        "roi_width" : 0.8,
        "roi_height" : 0.8,
        "difference_m" : 0.1,
        "difference_c" : 10,
        "region_threshold" : 0.005,
        "frame_period" : 5,
        "hskip" : 2,
        "vskip" : 2,
        "verbose" : 1
        }
    }
    EOF
    )
    echo $motion postProcess.json
    # Daarna definiëren we enkele functies
    # Functie waarmee je wacht op beweging:
    wait_for_motion () {
      while read -r line do
        if [[ "$line" == *"Motion detected"* ]]; then
          echo "Er is beweging."
          break
        fi
      # We gebruiken --nopreview om zo onopvallend mogelijk beweging te detecteren.
      # Gebruik een preview om het detectiegebied te bekijken/af te regelen.
      done < <(rpicam-hello -t --nopreview --lores-width 128 --lores-height 96 --post-process-file postProcess.json 2>&1)
    }
    # Hier begint ons programma
    # Oneindig lang worden bewegingen gemeld
    # Breek het programma af met Ctrl+c
    while :
    do
      wait_for_motion
      bestandsnaam=$(date +"%Y-%m-%d_%H.%M.%S.h264")
      rpicam-vid -t $((timeout*1000)) -p $preview -o $bestandsnaam
    done

  11. Test of het script werkt.
  12. Als je een specialist wat betreft camera bewegingsdetectie wilt gebruiken, kijk dan eens naar Motion.

Openbare reacties op deze pagina (kunnen door alle bezoekers gelezen worden)

, vrijdag 2 juni 2023 19:28