Intelligente Ontsmettingstunnel: Geautomatiseerde Sanitisering voor Drukke Locaties
Onderdelen en benodigdheden
| Onderdeel | Aantal |
|---|---|
| Arduino UNO | 1 |
| Draadbruggen (standaard) | 1 |
| PIR-bewegingssensor (standaard) | 2 |
| 12V Power Relay (4PDT) | 1 |
| 12 Volt SMPS | 1 |
| Seeed Grove - 2-Kanaals SPDT Relay | 1 |
| 5 Volt SMPS | 1 |
| Wipschakelaar, (On)-Off-(On) | 1 |
| Raspberry Pi 3 Model B | 1 |
| Raspberry Pi Camera Module V2 | 1 |
| Micro SD-kaart | 1 |
| Micro-USB naar USB-kabel (standaard) | 1 |
| Koelblok | 1 |
| 1 PK Waterpomp | 1 |
| Stalen Buisprofiel | 1 |
| Watertank (200 L) | 1 |
| PVC-kunststofbuis | 1 |
| 4-Way Fogger | 1 |
| Banner Flex | 1 |
| T-Stuk | 1 |
| Microbuis | 1 |
| Wandfixatie lamp | 1 |
| Knie | 1 |
| Kabelbinder, Dubbelzijdig | 1 |
Benodigde tools en machines
- Lasmachine
- Zaagmachine
- Soldeerbout (standaard)
- Soldeerdraad, Loodvrij
- Lasercutter (standaard)
Apps en online diensten
- Arduino IDE
- Raspberry Pi Raspbian
- OpenCV
Over dit project
Inleiding
De Slimme Ontsmettings- en Sanitatiestunnel is een demonstratie van hoe deze is ontworpen om maximale bescherming te bieden aan mensen die door de tunnel lopen in ongeveer 15 seconden. Wat de gemeenschap kan helpen in de strijd tegen COVID-19.
Het hoofddoel van dit project is een tunnel te maken die de verspreiding van COVID-19 kan proberen te voorkomen.
Deze ontsmettings- en sanitatiestunnel is gemaakt om mensen binnen 15 seconden te ontdoen van eventuele bacteriën.
Het onsmettingsmiddel bestaat uit een combinatie van natriumhypochloriet (NaOCl) en water (H2O). Het onsmettingsmiddel is niet-vluchtig, wat langdurige virucide en bactericide activiteit mogelijk maakt en de oppervlaktes saniteert.
Daarom nam ik de initiatief om deze Slimme Ontsmettings- en Sanitatiestunnel te maken. Deze tunnel werd in een tijdspanne van 12 uur gebouwd. Het kan een persoon volledig van top tot teen ontdoen in slechts 15 seconden en de gebruikte oplossing is volledig onschadelijk*. De totale kosten van de tunnel zijn ongeveer ₹30.000 of $400. (Gereviseerde kosten)


Waar te gebruiken?
- Voedselmarkten
- Kantoren
- Winkels/shoppingmalls
- Vliegvelden
- Bushaltes
- Treinstations
- Politiebureaus
- Colleges/universiteiten
- Ziekenhuizen
- Wijken
Hoe het werkt
Een 1PK Waterpomp wordt aan de zijkant van elke tunnel geplaatst die de oplossing van 0,4% natriumhypochloriet in 100 liter water uit de tank oppompt. Omdat de machine automatisch is, detecteert deze of iemand de tunnel binnenkomt. Zodra iemand de tunnel binnenkomt, start de waterpomp voor 15 seconden. Zo kan de gebruiker door de tunnel lopen en als er niemand in de tunnel is, schakelt de pomp uit om water en elektriciteit te besparen. De mistvormige onsmettingsspray beschermt burgers voor een periode van ten minste 60 minuten (Benadering*) tegen bacteriën. Omdat het de lucht, blootgestelde huid en kleding van mensen desinfecteert.

Een kunststof tank van 200 liter oplossing en een pomp voor het hoogdruk-pijpsysteem bevindt zich aan de zijkant van de tunnel. Volgens berekening zou de oplossing 8-10 uur volgen. Omdat er een bewegingsboven de ingang zit om desinfectiemiddel te besparen. (Kan variëren volgens het aantal mensen dat de tunnel binnenkomt**)
Stroomdiagram

Hardware-opstelling
Ik legde het frame uit een metalen profiel, vouwbaar zodat het van plek naar plek getransporteerd kan worden, en als het voorbij is, op te bergen voor de volgende apocalyps. De bekleding is door de banner (die gebruikt wordt voor buitenreclame). De banner is makkelijk te bevestigen aan het metalen profiel met plastic binders. Het is snel en vereist geen speciale vaardigheden.

Bekijk het 3D-model - https://skfb.ly/6RGvZ

Een kunststof tank van 200 liter oplossing en een pomp voor het hoogdruk-pijpsysteem bevindt zich aan de zijkant van de tunnel, verbonden met de 4-Way Fogger-montage.

Microbuizen zijn door de hele tunnel gebruikt om de oplossing aan de foggers te leveren.

Binnenin zit een hoogdruk-pijpleiding met 4 4-Way Foggers die aangesloten kunnen worden. De mist laat geen vlekken op kleding, terwijl ze de binnenkomende persoon volledig omhult en het virus vernietigt zelfs in moeilijk berekenbare vouwen van kleding en beschermt voor enige tijd na het verlaten.
Als oplossing wordt een gecertificeerde oplossing gebruikt in dit project. (Certificaat hieronder bijgevoegd)

4-Way Fogger Specificaties
- Afgiftesnelheid: 30 LPH/0,5 LPM (per fogger)
- Aanbevolen druk: 45-60 psi
- Gemiddelde druppeltjesgrootte: 65 micron (bij 55-60 psi)
- Benodigde filtratie: 130 micron (120 mesh)
- Benodigde pomp: 40 tot 45 meter hooft
Overige accessoires


De Arduino voorbereiden
De waterpomp werkt eigenlijk door infraroodstraling te detecteren. Wanneer een menselijk lichaam nabij een bewegingssensor komt, reflecteert het lichaam infraroodstraling, de bewegingsensor detecteert deze infraroodstraling en geeft een HIGH-signaal via de uitgangspin. Dit HIGH-signaal wordt door de Arduino gelezen. Als de Arduino een HIGH-signaal leest, geeft hij een HIGH-signaal aan de relaismodule, wat betekent dat het relais aanzet, en als resultaat zet de Power Relay aan en de Waterpomp gaat 15 seconden draaien (Kan gewijzigd worden). Op dezelfde manier, als de Arduino een LOW-signaal leest, maakt hij de relaispin LOW en blijft de Waterpomp uit.
In deze gebruikte ik 2 PIR-sensoren om het nauwkeuriger te maken: als een van ze beweging detecteert, schakelt het relais 15 seconden in (Kan gewijzigd worden).
We kunnen geen 5V-relais direct met de waterpomp gebruiken omdat in mijn geval de waterpomp een ampère-nominale waarde heeft van 16 Ampere en het 5V-relais een maximale belasting van 10 Ampere heeft. Om de waterpomp te besturen gebruikte ik nog een relais met de 5V-relaismodule, namelijk een 12V Power Relay.

Code:
/*
* Slimme Ontsmettings- en Sanitatiestunnel
*/
int relayPin = 12; // kies de pin voor de Relais-pin
int inputPin = 2; // kies de invoerpin (voor PIR-sensor)
int inputPin2 = 3; // kies de invoerpin (voor PIR-sensor 02)
int pirState = LOW; // bij start, aannemend geen beweging gedetecteerd
int val = 0; // variabele voor het lezen van de pinstatus
int val2 = 0; // variabele voor het lezen van de pinstatus
void setup() {
pinMode(relayPin, OUTPUT); // declareer relais als output
pinMode(inputPin, INPUT); // declareer sensor als input
pinMode(inputPin2, INPUT);
Serial.begin(9600);
}
void loop() {
val = digitalRead(inputPin); // lees invoerwaarde
val2 = digitalRead(inputPin2); // lees invoerwaarde
if (val == HIGH || val2 == HIGH) { // controleer of de invoer HIGH is
digitalWrite(relayPin, HIGH); // zet relais AAN
if (pirState == LOW) {
// zojuist aangezet
Serial.println("Beweging gedetecteerd!");
// 15 sec vertraging
delay(15000);
pirState = HIGH;
}
} else {
digitalWrite(relayPin, 0); // zet relais UIT
if (pirState == HIGH) {
// zojuist uitgezet
Serial.println("Beweging beëindigd!");
pirState = LOW;
}
}
}
De uiteindelijke bedrading ziet er wat rommelig uit maar werkte prima.

Na het aansturen van alles, testte ik het met basisdetectie en controleerde daarna of het relais correct schakelde.
De Raspberry Pi 3 voorbereiden (Optioneel)
Dit is optioneel. Als je analyse van de data wilt doen en het aantal mensen dat de tunnel gebruikt precies wilt tellen, kun je dit deel implementeren.
Hoewel er veel manieren zijn om dat te tellen met fysieke sensoren zoals PIR-sensor en ultrasone sensor, vond ik deze methode nauwkeuriger na alle scenario's te hebben overwogen.
Er is een machine learning-model dat het menselijk lichaam detecteert met OpenCV in Python en de log in een bestand opslaat, wat verwerkt kan worden om de data in de app te tonen.
De Pi-camera aansluiten
- Zet de Raspberry Pi uit
- Lokaliseer de Camera Module, tussen de USB-module en HDMI-modules
- Ontgrendel de zwarte plastic clip door (voorzichtig) omhoog te trekken
- Steek het lintkabel van de Camera Module in (metalene connectoren wegwijzend van de Ethernet/USB-poorten op een Raspberry Pi 4)
- Grendel de zwarte plastic clip


De Pi-camera inschakelen
- Voer uit:
sudo raspi-config - Selecteer Interfacing Options (4e optie) in het hoofdmenu van de Raspberry Pi Software Configuration Tool. Druk ENTER.

- Selecteer
Enable Camera(5e optie) en druk ENTER.

- In het volgende menu, gebruik de rechterpijlt om
ENABLEte markeren en druk ENTER.

Pi-camera testen
Vervolgens verifieer je of de Pi-camera correct geïnstalleerd is door de preview-overlay van de camera te starten. De overlay wordt op het scherm gerenderd.
- Verbind met Raspberry Pi via VNC Viewer.
- Voer de volgende opdracht uit:
raspistill -v -o test.jpg
Als je de Pi-camera correct hebt geïnstalleerd, zou je beelden van de camera op je scherm moeten zien.

OpenCV installeren
Volg deze link om OpenCV te installeren:
https://www.learnopencv.com/install-opencv-4-on-raspberry-pi/
Code
Voer de volgende opdracht uit om een nieuw scriptbestand aan te maken en te openen:
cd Desktop
sudo nano main.py
Kopieer het script en plak het in het nieuwe bestand dat je hebt aangemaakt.
import cv2.cv as cv
from datetime import datetime
import time
import sys
import datetime
count=0
class MotionDetector():
def onChange(self, val): #callback when the user change the ceil
self.ceil = val
def __init__(self,ceil=8, doRecord=True, showWindows=True):
self.writer = None
self.font = None
self.doRecord=doRecord #Either or not record the moving object
self.show = showWindows #Either or not show the 2 windows
self.frame = None
self.capture=cv.CaptureFromCAM(0)
self.frame = cv.QueryFrame(self.capture) #Take a frame to init recorder
if doRecord:
self.initRecorder()
self.frame1gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U) #Gray frame at t-1
cv.CvtColor(self.frame, self.frame1gray, cv.CV_RGB2GRAY)
#Will hold the thresholded result
self.res = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U)
self.frame2gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U) #Gray frame at t
self.width = self.frame.width
self.height = self.frame.height
self.nb_pixels = self.width * self.height
self.ceil = ceil
self.isRecording = False
self.trigger_time = 0 #Hold timestamp of the last detection
if showWindows:
cv.NamedWindow("Image")
def initRecorder(self): #Create the recorder
codec = cv.CV_FOURCC('D', 'I', 'V', 'X')
self.writer=cv.CreateVideoWriter(datetime.now().strftime("%b-%d_%H:%M:%S")+".avi", codec, 15, cv.GetSize(self.frame), 1)
self.font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 1, 1, 0, 2, 8) #Creates a font
def run(self):
global count
started = time.time()
while True:
curframe = cv.QueryFrame(self.capture)
instant = time.time() #Get timestamp o the frame
self.processImage(curframe) #Process the image
if not self.isRecording:
if self.somethingHasMoved():
self.trigger_time = instant #Update the trigger_time
if instant > started +5:#Wait 5 second after the webcam start for luminosity adjusting etc..
print "Human Detected"
count += 1
print(count/2)
orig_stdout = sys.stdout
f = open('out.txt', 'a+')
sys.stdout = f
print(count/2)
sys.stdout = orig_stdout
f.close()
#timestamp log
orig_stdout = sys.stdout
f = open('log.txt', 'a+')
sys.stdout = f
timestampc =('Timestamp: {:%Y-%b-%d %H:%M:%S}'.format(datetime.datetime.now()))
print(timestampc+' Log Entry : 1')
sys.stdout = orig_stdout
f.close()
if self.doRecord: #set isRecording=True only if we record a video
self.isRecording = True
else:
if instant >= self.trigger_time +10: #Record during 10 seconds
print "Stop recording"
self.isRecording = False
else:
cv.PutText(curframe,datetime.now().strftime("%b %d, %H:%M:%S"), (25,30),self.font, 0) #Put date on the frame
cv.WriteFrame(self.writer, curframe) #Write the frame
if self.show:
cv.ShowImage("Image", curframe)
cv.Copy(self.frame2gray, self.frame1gray)
c=cv.WaitKey(1)
if c==27 or c == 1048603: #Break if user enters 'Esc'.
break
def processImage(self, frame):
cv.CvtColor(frame, self.frame2gray, cv.CV_RGB2GRAY)
#Absdiff to get the difference between to the frames
cv.AbsDiff(self.frame1gray, self.frame2gray, self.res)
#Remove the noise and do the threshold
cv.Smooth(self.res, self.res, cv.CV_BLUR, 5,5)
element = cv.CreateStructuringElementEx(5*2+1, 5*2+1, 5, 5, cv.CV_SHAPE_RECT)
cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_OPEN)
cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_CLOSE)
cv.Threshold(self.res, self.res, 10, 255, cv.CV_THRESH_BINARY_INV)
def somethingHasMoved(self):
nb=0 #Will hold the number of black pixels
for y in range(self.height): #Iterate the hole image
for x in range(self.width):
if self.res[y,x] == 0.0: #If the pixel is black keep it
nb += 1
avg = (nb*100.0)/self.nb_pixels #Calculate the average of black pixel in the image
if avg > self.ceil:#If over the ceil trigger the alarm
return True
else:
return False
if __name__=="__main__":
detect = MotionDetector(doRecord=False)
detect.run()
Download - https://www.hackster.io/code_files/438321/download
Zodra dat gedaan is, sla het bestand op door "CTRL+X" in te typen, dan Y, en dan ENTER. Het script kan gestart worden door in te typen:
python main.py
Je zou een afbeelding op het scherm moeten zien en de video kunt bekijken om te verifiëren, indien nodig, en er is de mensenteller door het programma in de terminal.

Ik maakte een behuizing van MDF-plaat voor de Arduino en Raspberry Pi 3.

Een dashboard maken voor Desktop/App
Stap 1: Apache installeren
Installeer het apache2-pakket met deze opdracht:
sudo apt install apache2 -y
Stap 2: PHP installeren
Om je Apache-server PHP-bestanden te laten verwerken, moet je de nieuwste versie van PHP en de PHP-module voor Apache installeren. Typ de volgende opdracht:
sudo apt install php libapache2-mod-php -y
Download nu Dashboard.zip:
cd /var/www/html
wget "https://hacksterio.s3.amazonaws.com/uploads/attachments/1097966/Dashboard.zip"
En installeer unzip:
sudo apt-get install unzip
Pak de bestanden uit het ZIP-bestand:
unzip Dashboard.zip
Sla nu op en vernieuw je browser. Je zou dit moeten zien:


Raspberry Pi instellen als Wireless Access Point
Volg deze link: https://www.raspberrypi.org/documentation/configuration/wireless/access-point.md
Let op: Naam Wireless Access Point als SanitizingTunnel
interface=wlan0
driver=nl80211
ssid=SanitizingTunnel
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=SecretPassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Nu laten we de app bouwen
Android App:
Vereiste: Android Studio
Je kunt de code direct downloaden van hier. En wijzig je inloggegevens zoals IP-adres van je Raspberry Pi naar je behoeften.

iOS App:
Vereiste: XCode
Je kunt de code direct downloaden van hier. En wijzig je inloggegevens zoals IP-adres van je Raspberry Pi naar je behoeften.

Gebruikte chemische oplossing
De ontsmettingstunnel bevat 0,4% natriumhypochloriet-oplossing in 100 liter water.

Update - Ik heb veel reacties gezien dat ik schadelijke chemicaliën zou gebruiken.
Dus ik heb de informatie verzameld van de leverancier die me dit chemische middel leverde. Hij vertelde me dat het chemische middel dat ik in deze tunnel gebruik van Raman & Weil Pvt. Ltd is en ze hebben een "Verklaring" van Bode Chemie Duitsland, over de effectiviteit tegen COVID-19.
Officiële link - https://ramanweil.com/pdf/Declaration%20from%20Bode%20Chemie%20Germany%20on%20efficacy%20against%20COVID%2019.pdf

Alles samenvoegen
Ten slotte was het tijd om de tunnel aan te zetten en alle routines en apps te controleren of ze werken volgens plan.



Kosten

Link - Kostenoverzicht Google Sheets
Code
- Arduino Code Tunnel
- main.py
- Dashboard Bestanden
- Sanitation-Tunnel Android Broncode
- Sanitation-Tunnel Android App
- Sanitation-Tunnel iOS Broncode
Arduino Code Tunnel C/C++
/* * Slimme Ontsmettings- en Sanitatiestunnel */
int relayPin = 12;
int inputPin = 2;
int inputPin2 = 3;
int pirState = LOW;
int val = 0;
int val2 = 0;
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(inputPin, INPUT);
pinMode(inputPin2, INPUT);
Serial.begin(9600);
}
void loop(){
val = digitalRead(inputPin);
val2 = digitalRead(inputPin2);
if (val == HIGH || val2 == HIGH) {
digitalWrite(relayPin, HIGH);
if (pirState == LOW) {
Serial.println("Motion detected!");
delay(15000);
pirState = HIGH;
}
} else {
digitalWrite(relayPin, 0);
if (pirState == HIGH){
Serial.println("Motion ended!");
pirState = LOW;
}
}
}
main.py Python
import cv2.cv as cv
from datetime import datetime
import time
import sys
import datetime
count=0
class MotionDetector():
def onChange(self, val):
self.ceil = val
def __init__(self,ceil=8, doRecord=True, showWindows=True):
self.writer = None
self.font = None
self.doRecord=doRecord
self.show = showWindows
self.frame = None
self.capture=cv.CaptureFromCAM(0)
self.frame = cv.QueryFrame(self.capture)
if doRecord:
self.initRecorder()
self.frame1gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U)
cv.CvtColor(self.frame, self.frame1gray, cv.CV_RGB2GRAY)
self.res = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U)
self.frame2gray = cv.CreateMat(self.frame.height, self.frame.width, cv.CV_8U)
self.width = self.frame.width
self.height = self.frame.height
self.nb_pixels = self.width * self.height
self.ceil = ceil
self.isRecording = False
self.trigger_time = 0
if showWindows:
cv.NamedWindow("Image")
def initRecorder(self):
codec = cv.CV_FOURCC('D', 'I', 'V', 'X')
self.writer=cv.CreateVideoWriter(datetime.now().strftime("%b-%d_%H:%M:%S")+".avi", codec, 15, cv.GetSize(self.frame), 1)
self.font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 1, 1, 0, 2, 8)
def run(self):
global count
started = time.time()
while True:
curframe = cv.QueryFrame(self.capture)
instant = time.time()
self.processImage(curframe)
if not self.isRecording:
if self.somethingHasMoved():
self.trigger_time = instant
if instant > started +5:
print "Human Detected"
count += 1
print(count/2)
orig_stdout = sys.stdout
f = open('out.txt', 'a+')
sys.stdout = f
print(count/2)
sys.stdout = orig_stdout
f.close()
orig_stdout = sys.stdout
f = open('log.txt', 'a+')
sys.stdout = f
timestampc =('Timestamp: {:%Y-%b-%d %H:%M:%S}'.format(datetime.datetime.now()))
print(timestampc+' Log Entry : 1')
sys.stdout = orig_stdout
f.close()
if self.doRecord:
self.isRecording = True
else:
if instant >= self.trigger_time +10:
print "Stop recording"
self.isRecording = False
else:
cv.PutText(curframe,datetime.now().strftime("%b %d, %H:%M:%S"), (25,30),self.font, 0)
cv.WriteFrame(self.writer, curframe)
if self.show:
cv.ShowImage("Image", curframe)
cv.Copy(self.frame2gray, self.frame1gray)
c=cv.WaitKey(1)
if c==27 or c == 1048603:
break
def processImage(self, frame):
cv.CvtColor(frame, self.frame2gray, cv.CV_RGB2GRAY)
cv.AbsDiff(self.frame1gray, self.frame2gray, self.res)
cv.Smooth(self.res, self.res, cv.CV_BLUR, 5,5)
element = cv.CreateStructuringElementEx(5*2+1, 5*2+1, 5, 5, cv.CV_SHAPE_RECT)
cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_OPEN)
cv.MorphologyEx(self.res, self.res, None, None, cv.CV_MOP_CLOSE)
cv.Threshold(self.res, self.res, 10, 255, cv.CV_THRESH_BINARY_INV)
def somethingHasMoved(self):
nb=0
for y in range(self.height):
for x in range(self.width):
if self.res[y,x] == 0.0:
nb += 1
avg = (nb*100.0)/self.nb_pixels
if avg > self.ceil:
return True
else:
return False
if __name__=="__main__":
detect = MotionDetector(doRecord=False)
detect.run()
Dashboard Bestanden PHP
Geen preview (alleen downloaden).
Sanitation-Tunnel Android Broncode Java
Geen preview (alleen downloaden).
Sanitation-Tunnel Android App Java
Demo App
Geen preview (alleen downloaden).
Sanitation-Tunnel iOS Broncode Swift
Geen preview (alleen downloaden).
Slimme Ontsmettings- en Sanitatiestunnel
https://github.com/yugn27/Smart-Disinfection-and-Sanitation-Tunnel
Aangepaste onderdelen en behuizingen
smart_disinfection_and_sanitation_tunnel_prlFu8ZRXO.3mf
Schema's
Schakelingsschema - Fritzing-bestand
smart_disinfection_and_sanitation_tunnel_Zkb20Q5S2B.fzz
Productieproces
- Arduino temperatuur- en vochtigheidslogger met DHT11 en Ethernet Shield
- Bouw een Slimme IoT Pot met ESP8266, Arduino & Ultrasonische Sensor – Real-time Monitoring
- Slimme huisautomatisering & beveiligingssysteem bouwen met 1Sheeld
- Slimme Zelfzittende Schoenen met Ingebouwde Energie-opwekking
- Vier met Licht en Geluid: DIY Verjaardags Arduino-project
- Autonome Gezichtsvolgende Robot Auto met Arduino Nano & OpenCV
- Bouw een Slimme Arduino-gestuurde Robotarm: Eenvoudige DIY Handleiding
- DIY Gitaar Speed Pick & Stomp Pedal – Bouw Je Eigen 3D-Gemotoriseerde Plektron
- Slimme Productie: Definitie, Voordelen en Implementatie
- Hydrauliek Gerevolutioneerd: Hoe Industrie 4.0 Slimme Productie Drijft
- Hoe IoT de landbouw revolutioneert: Sleutelvoordelen & Slimme Boerderij Inzichten