Bescherm je kersenboom met een robot-vogelverschrikker

Gepubliceerd door Robot One op

Laserstraal in de kersenboom

Als de dood voor groene laser

Laatste update 9 mei 2023

Voorjaar is voor de liefhebbers van kersen een spannende tijd. Hebben de netten, vogelverschrikkers, geluidskanonnen en stukjes aluminiumfolie in de kersenboom effect? Of zal de oogst ook dit jaar worden opgevreten door brutale vogels?

Na het twee jaar te moeten doen met de schamele restjes die een plaatselijke roekenbende niet de moeite waard vond om op te eten, vond ik het welletjes. High Tech to the Rescue! In dit geval: met een (groene) laser. Zo leuk als katten laserpointers vinden om daar achteraan te jagen, zo paniekerig reageren vogels op zo’n groen puntje. Toch is dit geheime wapen een stuk diervriendelijker dan een net over je kersenboom heen spannen waarin vogels verstrikt raken.

Technofobe vogels

Vogels zijn absoluut technofoob. Daarvan kun je gebruik maken door bijvoorbeeld een ‘Agrilaser’ in te zetten. Dat is een merknaam voor krachtige (en fors geprijsde) laserpointers die boeren gebruiken om ganzen van hun akkers te jagen. De gedachte is dat vogels de laserpunt als bedreiging zien en wegvliegen. Na een paar keer te zijn weggejaagd, leren ze dat het niet pluis is op die locatie. Daarna blijven ze weg. Dat moeten we hebben!

Een Agrilaser met een prijs vanaf € 2.000, waarmee je handmatig de vogels in je achtertuin moet laten oplaseren, staat echter in geen verhouding tot de prijs van een bakje kersen in de supermarkt. En ik wil geen hele dagen de wacht houden bij de kersenboom. Daarom besloot ik het proces te automatiseren door middel van robotica. De gedachte was dat een robotarm met een laserpointer de kersenboom geautomatiseerd kon beschijnen.

Bouwdoos RobotarmNa wat uren puzzelen en schroeven, stond-ie er, mijn eenarmige batterijgevoede Laser Terminator. Met bediening via USB en software op de Raspberry Pi zoals omscheven in het blad MagPi nummer 3 onder de projectnaam ‘Skutter’. Leuk om mee te experimenteren, maar helaas niet meer dan dat.

De robotarm wordt aangedreven met gelijkstroom-motortjes die via een plastic wormwiel een vertragingsmechanisme met plastic tandradertjes aandrijven. Voed je zo’n motortje -3 volt dan draait het knarsend linksom en bij +3 volt draait het net zo karsend rechtsom. Bij 0 volt staat het stil. Deze robotarm is lawaaiig, langzaam, kwetsbaar en te onprecies om goed te kunnen mikken. Je kunt dus alleen maar hopen dat de vogels er vandoor gaan vanwege het afschuwelijke geknars. Dat kan dus beter.

Voor het volgende prototype koos ik een metalen pan-tilt (PTZ) mechanisme met twee servo’s: de LOBOT 2DOF PTZ. DOF staat voor Degrees of Freedom en als je er twee hebt, betekent dit dus dat je langs 2 assen kunt bewegen, in dit geval op en neer of links en rechts. Dat is voldoende voor onze laserzapper. PTZ staat overigens voor pan-tilt-zoom en is een term uit de wereld van bewakingscamera’s. Zoomen kun je met dit apparaat niet. Dat is ook niet nodig, want het bereik van een laserpointer is op zich groot genoeg.

LOBOT 2DOF Pan-tilt mechanisme

Pan-tilt mechanisme bestaande uit 2 sterke servo’s die met stevige metalen beugels zijn gemonteerd. Verkrijgbaar in zwart en metaalkleur. Tip: het type bij Amazon heeft geen bodemplaat, maar scheelt tientjes in prijs. Daarvoor kun je zelf een superdeluxe bodemplaat maken!

Koop op AliExpress Koop op Amazon

PTZ onderdelenAls je de PTZ set bestelt, krijg je een plastic zak met losse onderdelen thuis, zonder instructies. Dat is inmiddels geen verrassing meer voor bouwprojecten uit China, maar in dit geval is er zelfs geen handleiding online te vinden. Daarom hier een beknopte beschrijving die ik door schade en schande (en een paar keer mopperen en demonteren) heb kunnen maken.

STAP 1:
Voor je begint: zet de servo’s in de neutrale stand. Dit is belangrijk, want het voorkomt dat je na het voltooien van het project weer bijna helemaal opnieuw kunt beginnen. Je kunt er niet vanuit gaan dat de servo’s op ‘neutraal’ staan als ze uit de fabriek komen.

Servotester

Testapparaatje waarmee je de werking van tot drie servo’s tegelijk kunt testen, maar ze ook in neutrale stand kunt zetten. Je hebt hier wel nog een 5V voeding bij nodig.

Koop op Amazon.nl Koop op Bol.com

De servo’s in neutrale stand zetten kan met een goedkoop servotestertje en een 5V voeding. Hiervoor heb ik een regelbare labvoeding gebruikt die ook het stroomverbruik laat zien. Heel precies komt dit echter niet: in de praktijk werken de servo’s en de tester met 4 tot 6V. Je kunt dus ook een batterypack of goedkope telefoonlader gebruiken, zo lang je maar twee voedingsdraadjes kunt aansluiten op de driepolige connector van de tester (waarvan maar 2 aansluitingen worden gebruikt: de + in het midden en de – aan de buitenkant). Sluit de servo’s op de 3-polige connectoren aan de overzijde aan. De stekkers gaan er liggend in, met vlnr. oranje (s), rood (+) en bruin (-).

De tester heeft een drukknopje met diverse testmogelijkheden: handbediening (linker led brandt, de servo’s reageren op de draaiknop), neutraal (middelste led brandt, servo’s gaan naar hun neutrale stand) en automatisch (rechter led brandt, de servo’s draaien heen en weer). Nadat je de servo’s beide in neutrale stand hebt gezet, kun je de tester loskoppelen. Zorg er in de volgende stappen voor dat je de assen niet meer verdraait tijdens het monteren. Want daar doen we dit allemaal voor: om het geheel niet weer uit elkaar te hoeven halen als de neutrale stand niet klopt.

STAP 2:
Nu gaan we het bouwwerk monteren. Bevestig eerst de 2 grote U-vormige delen met de langere moertjes en boutjes aan elkaar om een soort bodemplaat te maken.

PTZ monteren stap 2,3

STAP 3:
Bevestig een van de servobeugels in het midden van een van de U-delen, met de langere boutjes en moertjes.

PTZ monteren, stap 4

STAP 4:
Bevestig de eerste servo (verticaal) met de langere boutjes en moertjes in de servobeugel, zodanig dat de as het dichtst bij de buitenrand van de bodemplaats zit. Waarschuwing: draai de boutjes niet te hard aan, anders gaat het kopje dwars door de plastic beugel van de servo heen. Ik heb dit meegemaakt en moest lang zoeken in de rommeldoos om M2 tussenringetjes te vinden waarmee de servo weer normaal is vast te zetten.

STAP 5:
Bevestig een van de twee ronde plaatjes met korte boutjes aan de brede kant van de tweede beugel. De plaatjes hebben schroefdraad, dus moertjes zijn hier niet nodig.

PTZ monteren, stap 5,6

STAP 6:
Druk het plaatje in de tweede beugel op de as met tandwiel van de eerste servo. Schroef een kort boutje door de as zodat de beugel vastzit.

STAP 7:
Schroef de tweede servo (horizontaal) met 4 langere boutjes en moertjes vast aan de tweede beugel, zodanig dat de as van de tweede servo ter hoogte van de as van de verticale eerste servo zit.

PTZ monteren, stap 8

STAP 8:
Schroef het kleine wieltje met een langere bout en moer vast aan de beugel van de tweede servo, zodat deze recht tegenover de as van de servo zit.

STAP 9:
Schroef het tweede ronde plaatje met 4 korte boutjes aan de binnenzijde van de kleinere U-beugel. N.b. het plaatje zit dus aan de binnenzijde, de boutjes zitten aan de buitenzijde.

PTZ monteren, stap 9

STAP 10:
Bevestig de U-beugel recht overeind op de tweede servo waarbij je het een beetje uit elkaar moet buigen, maar niet met lomp geweld! Het losse wieltje komt nu aan de ene kant, waar niks zit. Het plaatje aan de beugel valt over het tandwiel van de servo. Schroef het vast met een kort boutje.

PTZ monteren, stap 10

STAP 11:
Sluit de servotester nog eens op beide servo’s aan zet ze in neutrale stand (het middelste lampje op de tester brandt). De bovenste beugel moet rechtop staan en eenwijdig lopen met de rand van de bodemplaat van 2 U-profielen. Controleer nu of de beugels heen en weer en op en neer kunnen bewegen.

Proefdraaien met de servotester

Met de servotester en een labvoeding aangesloten kunnen we zien dat alles soepel beweegt, maar ook dat de twee servo’s samen tot 310mA aan stroom verbruiken, wat nogal wisselt. Zo is meteen duidelijk waarom ze een eigen voeding nodig hebben. We gaan ze nu aansturen met een Raspberry Pi (via een Servo Hat) en een stukje Python script.

Servo Hat

Nu we de hardware zo ver klaar hebben, wordt het tijd voor de besturing van het apparaat. Hoewel het software- en hardwarematig niet echt spannend is en in principe op een goedkope ESP8266 (of NodeMCU, of Wemos D1) kan draaien, heb ik vanwege het gemak voor het prototype een Raspberry Pi 3B+ gebruikt die ik nog had liggen. Testen en installeren via een terminal (Command Line Interface, CLI) gaat immers een stuk soepeler dan wanneer je de software na iedere aanpassing via de Arduino IDE moet compileren en uploaden. Bovendien zijn voor de RPi diverse makkelijke (Python) libraries kant en klaar beschikbaar.

Maar eerst moeten we zorgen dat we de RPi in staat stellen om servo’s en een relais aan te sturen. Dat kan hij niet zelfstandig omdat de stroom op de uitgangsbus (GPIO) beperkt is. Er zijn interfaces nodig die de RPi beschermen én voldoende power leveren aan de te besturen apparaten: een enkelvoudige relaismodule voor het aan- en uitzetten van de laser en een servo-interface die het mogelijk maakt om meerdere servo’s aan te sturen (16 om precies te zijn).

PCA9685 servo hat

Met deze ‘servo hat’ kun je vanuit je Raspberry Pi (of Arduino, of ESP8266 etc.) tot 16 servo’s aansturen. Ideaal voor robotica, maar ook onmisbaar bij het aansturen van de birdzapper.

Koop op Amazon.nl Koop op Bol.com

Voor de servo-interface gebruik ik een Adafruit PCA9685. Die wordt verkocht als interface voor de Arduino en kan met slechts drie snoertjes eenvoudig aan de RPi worden bevestigd. Er is wel een specifieke servo-HAT die je rechtstreeks op de RPi kunt klikken, maar die kost al gauw het dubbele of meer en bezet dan ook nog eens de GPIO-aansluitingen.

Voor de aansturing van de laser heb ik een goedkope enkelvoudige relaismodule gebruikt. Deze kan 230V schakelen, maar we gebruiken hem hier gewoon als aanstuurbare drukknop.

Aansluiten

Hoe sluit je de Servo interface en de Raspberry Pi nu op elkaar aan? Dat kan met soldeerverbindingen of met eenvoudige draadjes met aan beide kanten een stekkertje dat op de pinnetjes van de printplaten past. Dat gaat als volgt:

AansluitingRPiServo hat
3V3pin 1pin 2
SDApin 3pin 3
SCLpin 5pin 4
GNDpin 9pin 6

De driepolige servostekkers kunnen we rechstreeks op de driepolige connectoren van de Servo interface aansluiten. Ik heb hierbij gekozen voor aansluitingen 0 (horizontale beweging) en 3 (verticale beweging), maar desgewenst kun je dat helemaal naar je smaak aanpassen, als je er maar aan denkt dat dit ook consequenties heeft voor de besturingssoftware.

De relaismodule die de laser moet besturen is aangesloten op de GND van de RPi en een van de vrije GPIO-aansluitingen. Ik heb hier gekozen voor GPIO 17. Deze gaat naar de relaismodule

AansluitingRPiRelaismodule
GPIOpin 1pin 2
GNDpin 9pin 6

Vanuit de relaismodule gaan twee draden naar de laser. Ze worden vastgesoldeerd op twee aansluitingen van de momentschakelaar.

Laser

Onmisbaar in de vogelverschrikker is natuurlijk een groene laser die krachtig genoeg is om bij volle zon een roek van zijn tak te branden. Figuurlijk dan, want we hebben geen behoefte aan geflambeerde kersen. De meeste handlaserpointers voor kantoorgebruik zijn hiervoor te slap. Ik heb dan ook een flinke groene laserpointer besteld, type U303 en het lensje op de kop (voor de sterretjes-effecten) meteen eraf geschroefd. Wees voorzichtig: dit is een Class III laser, wat betekent dat rechtstreeks van dichtbij in de straal kijken binnen enkele seconden oogletsel oplevert. Je zou proefondervindelijk kunnen vaststellen of dit klopt: een keer met je linkeroog en een keer met je rechteroog. Maar: beter van niet.

Krachtige groene laser

Vogels verjagen lukt alleen met een groene laser. Kies er wel een die krachtig genoeg is om ook overdag bij zonnig weer te gebruiken, dus geen kattenspeeltje. Deze van het type U303 is veilig, maar wel sterk genoeg.

Koop op Amazon.nl

De laser bevat een ingebouwde accu met laadcircuit en een knop (een momentschakelaar) om hem aan te zetten, dit alles verpakt in een stevige aluminium koker. Op de onderstaande foto is te zien dat ik het ding behoorlijk heb toegetakeld om het eens goed te kunnen bestuderen. Ik de behuizing open gefreesd met een mini-slijptolletje (een Dremel kloon). En weer deels dichtgeplakt met wat epoxy-kneedmassa.

Gehavende laserpointer
Gehavende laserpointer. Zo bont hoef je het niet te maken.

Software

Nou hebben lasers niet het eeuwige leven. Als ze continu blijven branden, houden ze het geen lente vol. We willen de laser dus besturen via elektronica. Je zou er bijvoorbeeld voor kunnen kiezen om de aan/uit schakelaar vast te plakken met een stukje duct tape of een druppeltje secondenlijm en de accu te verwijderen, zodat je de laser aan of uit kunt zetten door al dan niet 3.7V op de accu-aansluitingen te zetten. Ik heb voor mijn prototype een iets andere oplossing gekozen: de accu laten zitten, twee draadjes parallel aan de aan/uit knop solderen en deze laten bedienen door een relaismodule, die wordt geschakeld via een GPIO-pin van de Raspberry Pi.

Relaismodule 5V

Deze eenvoudige relaismodule kan rechtstreeks door de Raspberry Pi worden aangestuurd. De aansluitingen van het maakcontact worden parallel over de drukknop van de laserpointer aangesloten, zodat deze galvanisch is gescheiden, maar wel via software is te bedienen.

Koop op Amazon.nl Koop op Bol.com

Om de servo’s te kunnen besturen zijn wat software-onderdelen nodig, te beginnen bij de I2C bus aansturing. Als je een nieuwere volledige versie van Raspbian op je RPi hebt geïnstalleerd, staat deze er al op. Dat kun je in de CLI checken met het volgende commando:

sudo i2cdetect -y 1

Installeer zo nodig de drivers met de commando’s:

sudo apt update
sudo apt upgrade
sudo apt-get install python-smbus
sudo apt-get install i2c-tools

Nu gaan we de de CircuitPython Blinka library installeren voor het besturen van I2C-apparaten zoals de Adafruit servo-hat:

sudo apt-get install python3-pip
sudo pip3 install --upgrade setuptools
cd ~
sudo pip3 install --upgrade adafruit-python-shell
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
sudo python3 raspi-blinka.py

Dit script meldt mogelijk ook dat een aantal pakketten al lang is geïnstalleerd. Geen probleem! Het script schakelt bovendien automatisch I2C en SPI in. Dat kun je checken met het volgende commando:

ls /dev/i2c* /dev/spi*

Als het goed is, krijg je als antwoord iets als:

/dev/i2c-1 /dev/spidev0.0 /dev/spidev0.1

Je kunt in Python nu testen of de Blinka lib werkt met het volgende programmaatje:

import board
import digitalio
import busio
 
print("Hello blinka!")
 
# Maak een digitale input
pin = digitalio.DigitalInOut(board.D4)
print("Digital IO ok!")
 
# Maak een I2C device aan
i2c = busio.I2C(board.SCL, board.SDA)
print("I2C ok!")
 
# Maak een SPI device aan
spi = busio.SPI(board.SCLK, board.MOSI, board.MISO)
print("SPI ok!")
 
print("done!")

Sla dit op als blinkatest.py en run het vanaf de commandline met:

python3 blinkatest.py

Als je geen foutmeldingen krijgt, is de installatie tot zover gelukt. De volgende stap is het installeren van de Adafruit bibliotheek:

sudo pip3 install adafruit-circuitpython-servokit

Deze bibliotheek maakt het aansturen van servo’s vanuit Python eenvoudig.

Praktijktest

Zoals je in de video van het prototype hieronder ziet, heb ik de laser provisorisch aan het pan-tilt mechanisme bevestigd met een stukje ijzerdraad. Het kan ook met tie-rips, een schroefbeugeltje en/of duct tape. De hele installatie staat op een oude projectortafel uit de tijd dat we nog met smalfilm- en diaprojectoren werkten.

Python scripts

De software die ik voor de eerste tests heb gebruikt bestaat uit twee Python scripts: een testprogramma om de minimale en maximale X en Y-coördinaten te bepalen, want je wilt uiteraard alleen je kersenboom instralen en niet de hele buurt.

from gpiozero import LED
from adafruit_servokit import ServoKit
import tty, sys, termios

kit = ServoKit(channels=16)
laser = LED(17)

filedescriptors = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
x = 0
y = 0

print (chr(12)) # dit is een truc die we nog uit Basic kennen (cls)
print ("BIRDZAPPER 0.2")
print ("______________")
print ()
print ()
print ("Gebruik de pijltjestoetsen om de laser te positioneren")
print ("Noteer de minimum an maximum waarden van x en y")
print ()
x = 0
y = 0

while True:
  print ("Waarde X = " + str(x) + " Y = " + str(y))
  print ()
  kit.servo[0].angle = x
  kit.servo[4].angle = y
  toets=sys.stdin.read(1)
  ascii = ord(toets)
  if (ascii == 27):  #esc, stop ermee
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN,filedescriptors)
    break
  if (toets == "a") or (toets == "A") or (toets == "4"): # left
    x -= 2 # stapjes van 1 zijn wel heel erg klein
    if (x < 0):
      x = 0
  if (toets == "d") or (toets == "D") or (toets == "6"): # right
    x += 2
    if (x > 180):
      x = 180
  if (toets == "w") or (toets == "W") or (toets == "8"): # up
    y += 2
    if (y > 180):
      y = 180
  if (toets == "s") or (toets == "S") or (toets == "2"): # down
    y -= 2
    if (y < 0):
      y = 0
  print ()

# Herstel terminal output
termios.tcsetattr(sys.stdin, termios.TCSADRAIN,filedescriptors)

Daarnaast zorgt het script birdzap.py ervoor dat de birdzapper random patronen ‘schiet’ binnen de opgegeven coördinaten.

#----------------------------------------------------------------------
#
#   BIRD ZAPPER v0.1
#
#----------------------------------------------------------------------


import time
import random
from gpiozero import LED
from adafruit_servokit import ServoKit

kit = ServoKit(channels=16)
laser = LED(17)

global lastx
global lasty


# Beweeg de servo's met vertraging naar hun positie X,Y

def moveto(xpos,ypos):
  global lastx
  global lasty
  global maxnum
  print(str(lastx) + "," + str(lasty) + " ---> " + str(xpos) + "," + str(ypos))

  xnum = abs(xpos - lastx) # aantal stappen x
  ynum = abs(ypos - lasty) # aantal stappen y

  if (xpos > lastx):
    xstep = 1
  else:
    xstep = -1             # omhoog of omlaag tellen?

  if (ypos > lasty):
    ystep = 1
  else:
    ystep = -1

  if (ynum > xnum): # bepaal het maximale aantal stappen
    maxnum = ynum
  else:
    maxnum = xnum

  print ("Stappen: " + str(maxnum))

  for n in range (0,maxnum):
    if (lastx != xpos):
      lastx += xstep
      kit.servo[0].angle = lastx
    if (ypos != lasty):
      lasty += ystep
      kit.servo[4].angle = lasty
    time.sleep(0.03) # slaaptijd, bepaalt de snelheid van bewegen


# Start hier

t = 0
lastx = 0
lasty = 0

# Grenswaarden van de servo's vooralsnog handmatig vaststellen

xmax = 160
xmin = 100
ymax = 140
ymin = 100

# Zet de  positie op 0,0

kit.servo[0].angle = xmin
kit.servo[4].angle = ymin

print ("BIRDZAPPER v0.1")
print ("---------------")
print ()
print ("Ctrl-C om te stoppen")
print ()

while True:

# Nu gaan we random aan de slag (random x,y en tijd tussen de bewegingen)

  xwaarde = random.randint(xmin,xmax)
  ywaarde = random.randint(ymin, ymax)
  laser.on()
  moveto(xwaarde,ywaarde)
  laser.off()
  time.sleep(random.randint(3,7)) # wacht 3..7 seconden voor de volgende stap

Beide scripts zijn bepaald geen toonbeeld van elegant programmeren, maar ze doen wat ze moeten doen. Mogelijke volgende stappen in de ontwikkeling zijn het opbouwen van een weerbestendige behuizing, het gebruiksvriendelijker maken van de software (incl. afstandsbediening via de smartphone), het installeren van een camera, het herkennen van vogels met een AI algoritme en het gericht mikken van de laser op de vogel in kwestie. Er is nog veel ontwikkelwerk te doen. Wordt vervolgd!


Low-tech alternatief

Vogels verjagen kan ook met low tech, suggereert een bericht in het dagblad Trouw van 26 maart 2022. Daarin staat dat horecabazen in Venetië de plaatselijke zeemeeuwenplaag bestrijden met oranje waterpistooltjes. Niet eens door meeuwen nat te spuiten. Als zij de wapens op tafel zien liggen, druipen ze vanzelf af. Ze zouden een hekel hebben aan oranje. Oranje waterpistooltjes in de fruitboom hangen zou dus ook moeten werken, maar: eerst zien, dan geloven.


0 reacties

Geef een reactie

Avatar plaatshouder

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *