Schon seit längerem war ich auf der Suche nach einer interessanten Weiterbildung, dabei stiess ich auf das CAS IOT Manager an der HSLU. In verschiedenen Modulen haben wir Einblick in die Themen von IoT bekommen. IoT ist nicht neu es ist schon heute an vielen Orten anzutreffen. Es gibt viele positive Anwendungen die uns heute schon das Leben erleichtern. Natürlich gibt es bei IoT auch Gefahren und Ängste, welche einem noch mehr bewusst werden, wenn man sich näher damit befasst.
Die Ängste sind nicht neu, der Kabarettist Erwin Pelzig hatte schon Anfang der neunziger Jahre Angst vor intelligenten Haushaltgeräten.
https://www.youtube.com/watch?v=Y8RbhJXqeVk
Nun zu meinem eigentlichen Thema
Die Module Iot Grundlagen und Prototyping mit dem praktischen Teil haben mich begeistert und mich und meine Kollegen zu einer praktischen Projektarbeit motiviert.
Unser Ziel ist es den Signa Guard-S Parkplatz Parkbügel intelligent zu machen.
https://www.signal.ch/sortiment/signa-guard-parkbuegel/
Ausgangslage
Heute wird dieser Parkbügel über einem Funkhandsender hoch und runtergefahren. Ziel ist es, dass der Parkbügel die Fahrzeugkennziffer erkennt und prüfen kann ob das Fahrzeug für diesen Parkplatz erlaubt ist.
Beim durchstöbern des Internet fand ich viele Lösungen für die Fahrzeugkennziffer-Erkennung welche auf den Raspberry Pi realisiert wurden. Ich entschied mich, für folgende Tests als Vorbereitung für unsere Projektarbeit.
Hardware
Als Edge: Raspberry Pi 3, SD Karte min 32GB
Kamera: Rasperry Pi Camera V2 oder USB Kamera
Bewegungssensor: PIR Motion Sensor
Parkbügelsimulation: SG90 9G Micro Servo Motor
Verdrahtung
Software
Raspbian Stretch with desktop
Node Red
Python 2.7 oder neuer
Weiter braucht es für diese Lösung der Fahrzeugkennziffer-Erkennung einen kostenlosen Account bei OpenALPR. Mit diesem Account kann man 2000 kostenlose Anfrage pro Monat senden. Dieser kann man unter folgendem Link erstellen.
https://cloud.openalpr.com/account/register
Test 1 – Wird die Fahrzeugkennziffer erkannt?
Als erstes machte ich einen Test mit NodeRed, OpenALPR Cloud und der Raspberry Pi Camera V2. Die Qualität der Fotos der Pi Cam V2 waren so schlecht, dass ich den Test mit der USB Kamera aufbaute.
Hier der Aufbau mit der USB Kamera in NodeRed
Sobald der Flow mit „Timestamp“ gestartet wird erstellt die USB Kamera ein Bild, welches dann im Node cURL POST an die OpenALPR Cloud gesendet wird.
Die Antwort ist dann in „Debug“ ersichtlich.
Hier der NodeRed Code zum importieren
[{"id":"b85e85cb.8b3c8","type":"tab","label":"Camera Test","disabled":false,"info":""},{"id":"1cf41548.8ed4fb","type":"exec","z":"b85e85cb.8b3c8","command":"sudo curl -X POST \"https://api.openalpr.com/v2/recognize?secret_key=sk_secret key&recognize_vehicle=1&country=eu&return_image=0&topn=10\" -F image=@/home/pi/Pictures/car.jpg","addpay":false,"append":"","useSpawn":"false","timer":"", "oldrc":false,"name":"cURL POST","x":501,"y":300,"wires":[["7f3aeff7.dbdb"],[],[]]},{"id":"7f3aeff7.dbdb","type":"json","z":"b85e85cb.8b3c8","name":"JSON","property":"payload", "action":"","pretty":false,"x":647.5,"y":287.5,"wires":[["8ce73fa.f56fdc"]]},{"id":"8ce73fa.f56fdc","type":"debug","z":"b85e85cb.8b3c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":799,"y":287,"wires":[]},{"id":"22ed60b8.04ec6","type":"inject","z":"b85e85cb.8b3c8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":178.5,"y":301,"wires":[["9fdba568.c9ea58"]]},{"id":"9fdba568.c9ea58","type":"usbcamera","z":"b85e85cb.8b3c8","filemode":"1","filename":"car.jpg","filedefpath":"1","filepath":"","fileformat":"jpeg","resolution":"2","name":"","x":361,"y":220,"wires":[["1cf41548.8ed4fb"]]}]
Hinweis: Je nach verwendeter Kamera muss noch der richtige Kamera Node in NodeRed importiert werden.
Die Konfiguration des cURL POST Nodes muss noch angepasst werden.
Mit dem cURL POST Node wir das Bild zur Erkennung der Fahrzeugkennziffer an OpenALPR gesendet.
sudo curl -X POST "https://api.openalpr.com/v2/recognize?secret_key=sk_Secret key&recognize_vehicle=1&country=eu& return_image=0&topn=10" -F image=@/home/pi/Pictures/car.jpg
„Secret key“ muss mit dem eigenen Key ersetzt werden den findet man im OpenALPR Account
https://cloud.openalpr.com/account/
Der Test von OpenALPR und Kamera war erfolgreich, jetzt geht’s ans eigentliche Vorhaben.
Test 2 – Testaufbau mit Parkbügel Simulation
Mit diesem Aufbau möchte ich die Fahrzeugkennziffer-Erkennung und die Ansteuerung des Parkbügels simulieren.
Dabei dient mir der SG90 9G Micro Servo Motor als Parkbügel.
Funktionschema
Ablauf des Flows:
- Timestamp gibt Impuls (Auto kommt)
- Bügel oben? Wenn ja, Foto wird gemacht
- Abfrage bei OpenALPR
- die Antwort wird im „Identify Car“ kontrolliert => nicht richtig dann passiert nichts
- Fahrzeugkennziffer erlaubt => Bügel geht runter (Bügel down)
- Parkplatz noch besetzt => Bügel bleibt oben
- Parkplatz frei => Bügel geht nach 10 Sekunden hoch
Bilder vom Testaufbau
Kamera nimmt Foto von Auto auf. Verdratung des Raspberry Pi und der Servo
Hier der NodeRed Code zum Importieren
[{"id":"b32d02f5.5b8d2","type":"tab","label":"auto-plate-rec","disabled":false,"info":""},{"id":"b8496327.a7dcb","type":"exec","z":"b32d02f5.5b8d2","command":"sudo curl -X POST \"https://api.openalpr.com/v2/recognize?secret_key=sk_mykey&recognize_vehicle=1&country=eu&return_image=0&topn=10\" -F image=@/home/pi/Pictures/car.jpg","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"cURL POST","x":710,"y":120,"wires":[["7e37f727.b44e48"],[],[]]},{"id":"7e37f727.b44e48","type":"json","z":"b32d02f5.5b8d2","name":"JSON","pretty":false,"x":872.5,"y":135.5,"wires":[["8686e97f.a17c78","7bcb5290.29d70c"]]},{"id":"7bcb5290.29d70c","type":"function","z":"b32d02f5.5b8d2","name":"Identify Car","func":"var carPlate1 = (\"H786POJ\");\nvar carPlate2 = (\"MNP4675\")\n//var carModel = \"renault_r-4\";\n\n//No car or car plate found in photo\nif(msg.payload.results.length === 0) {\n msg.payload=0;\n global.set(\"garageOpen\",\"0\"); \n}\n//If car plate and car model match\nelse if(msg.payload.results[0].plate==carPlate1 || carPlate2 ) {\n//&& msg.payload.results[0].vehicle.make_model[0].name==carModel\n msg.payload=1;\n global.set(\"garageOpen\",\"1\"); \n}\n//If car plate and car model don't match\nelse {\n msg.payload=0; \n global.set(\"garageOpen\",\"0\"); \n}\n\nreturn msg;\n\n","outputs":1,"noerr":0,"x":161,"y":320,"wires":[["aaa9772.e5b5088","244e10e7.d44af"]]},{"id":"aaa9772.e5b5088","type":"switch","z":"b32d02f5.5b8d2","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","outputs":2,"x":301,"y":320,"wires":[["4accb9b7.b228d8","739992ce.6e012c"],["625922d6.0c39bc"]]},{"id":"8686e97f.a17c78","type":"debug","z":"b32d02f5.5b8d2","name":"","active":true,"tosidebar":true,"console":false,"complete":"false","x":1018,"y":100,"wires":[]},{"id":"f8c007ac.ede8f8","type":"switch","z":"b32d02f5.5b8d2","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":401,"y":160,"wires":[["5df5174a.83c738"],["928f3928.a09898"]]},{"id":"951677d2.eac4e8","type":"function","z":"b32d02f5.5b8d2","name":"Buegel oben","func":"var garageOpen = global.get(\"garageOpen\"); \n\nif(garageOpen == \"1\"){\n msg.payload = 1;\n}\nelse {\n msg.payload = 0;\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":241.5,"y":162,"wires":[["f8c007ac.ede8f8"]]},{"id":"4accb9b7.b228d8","type":"delay","z":"b32d02f5.5b8d2","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":600,"y":331,"wires":[["793cbbe3.a1bb74"]]},{"id":"793cbbe3.a1bb74","type":"function","z":"b32d02f5.5b8d2","name":"Bügel oben","func":"msg.payload=0; \nglobal.set(\"garageOpen\",\"0\"); \nreturn msg;\n\n","outputs":1,"noerr":0,"x":750,"y":331,"wires":[["b26082d7.1d7a2"]]},{"id":"928f3928.a09898","type":"debug","z":"b32d02f5.5b8d2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":548,"y":169,"wires":[]},{"id":"625922d6.0c39bc","type":"debug","z":"b32d02f5.5b8d2","name":"","active":true,"console":"false","complete":"false","x":597,"y":388,"wires":[]},{"id":"5df5174a.83c738","type":"usbcamera","z":"b32d02f5.5b8d2","filemode":"1","filename":"car.jpg","filedefpath":"1","filepath":"","fileformat":"jpeg","resolution":"2","name":"","x":541,"y":80,"wires":[["b8496327.a7dcb"]]},{"id":"daa9a368.eb6c5","type":"inject","z":"b32d02f5.5b8d2","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":100,"y":240,"wires":[["951677d2.eac4e8"]]},{"id":"739992ce.6e012c","type":"pythonshell in","z":"b32d02f5.5b8d2","name":"Bügel down","pyfile":"/home/pi/close.py","virtualenv":"","continuous":false,"stdInData":false,"x":741,"y":240,"wires":[[]]},{"id":"b26082d7.1d7a2","type":"pythonshell in","z":"b32d02f5.5b8d2","name":"Bügel Auf","pyfile":"/home/pi/open.py","virtualenv":"","continuous":false,"stdInData":false,"x":940,"y":420,"wires":[[]]},{"id":"244e10e7.d44af","type":"debug","z":"b32d02f5.5b8d2","name":"","active":true,"tosidebar":true,"console":false,"complete":"false","x":310,"y":420,"wires":[]}]
Für diesen Aufbau wird in NodeRed der „pythonshel Node“ benötigt.
In der Funktion „Identify Car“ muss die erlaubte Fahrzeugkennziffer eingetragen werden.
Pythonscripts für Servo Ansteuerung
Bügel down: close.py
import RPi.GPIO as GPIO import time servoPIN = 24 GPIO.setmode(GPIO.BCM) GPIO.setup(servoPIN, GPIO.OUT) p = GPIO.PWM(servoPIN, 50) # GPIO 17 als PWM mit 50Hz p.start(2.5) # Initialisierung p.ChangeDutyCycle(2.5) time.sleep(0.5) p.stop() GPIO.cleanup()
Bügel up: open.py
import RPi.GPIO as GPIO import time servoPIN = 24 GPIO.setmode(GPIO.BCM) GPIO.setup(servoPIN, GPIO.OUT) p = GPIO.PWM(servoPIN, 50) # GPIO 17 als PWM mit 50Hz p.start(2.5) # Initialisierung p.ChangeDutyCycle(12.5) time.sleep(0.5) p.stop() GPIO.cleanup()
Viel Spass beim Nachbauen 🙂
Fazit
Es hat Spass gemacht meine IT Kenntnisse wiedermal aufzufrischen. Es braucht auf jeden Fall viel Zeit und Geduld bis alles so wie gewünscht funktioniert. Mit diesen Tests habe ich nun eine Basis für die eigentliche Projektarbeit geschaffen. Ziel ist es nun die Fahrzeugkennziffer-Erkennung lokal auf dem Raspberry Pi zu realisieren plus ein Webinterface für die Eingabe der erlaubten Fahrzeugkennziffern zu bauen. Bin gespannt wie weit wir dies realisieren können.
Auf jeden Fall hat mir das gezeigt, dass es auch mit Ü50 noch Spass macht ein CAS zu besuchen. Ich habe viele positive Reaktionen in meinem privaten Umfeld erhalten. Es gab auch einige die sich fragten wieso ich mir dies in meinem Alter noch antue. Ich bin der Meinung, dass es in jedem Alter wichtig ist, sich weiterzubilden. Speziell im Bereich der Informatik. Man sollte immer seine Kompetenzen und Skills erhalten und erweitern.