MKR1000 Multi-Mode Omgevingssensor Dek – Bliksem, Gas, UV, Temp, Vocht & Druk
Onderdelen en benodigdheden
| Arduino MKR1000 | 1 |
| MOD-1016 Bliksemsensor (AS3935) | 1 |
| DFRobot MQ-9 Gassensor | 1 |
| Adafruit Luchtvochtigheids- en Temperatuursensor (HTU21D-F) | 1 |
| Adafruit Druk/Hoogte/Temperatuursensor (BMP180) | 1 |
| SparkFun ML8511 UV-sensor | 1 |
| Chronodot RTC (DS3231) | 1 |
| SparkFun Photon Weather Shield | 1 |
| Adafruit NeoPixels | 1 set |
| Breadboard (generiek) | 1 |
| Jumper-kabels (generiek) | 1 set |
Over dit project
Ik hou van het waarnemen van het weer en wilde het vastleggen en grafisch weergeven. Thuisweerstations laten me de details voor "nu" zien, en soms totalen voor het afgelopen uur of de dag. Ik wilde meer, en een Arduino gebruiken voor de klus. Iedereen begint met temperatuur en luchtvochtigheid, soms barometrische druk, maar ik wilde meer! Windsnelheid en regenmeting wilden elk hardware-ingangen. Zodra ik I2C onder de knie had, ontdekte ik dingen als de AS3935 Bliksemdetector! En dan zette de teleurstelling in... Ik had niet genoeg hardware-onderbrekingen om de klus te doen met een basis Arduino. Sparkfun heeft wel een weer-sensorbord voor de Photon, maar dat is nog steeds beperkt. Ik moest kiezen, en sommige sensoren weglaten. :-(
Toen zag ik de MKR1000, en ik ontdekte de BESTE FUNCTIE: het heeft 8 hardware-onderbrekingen! Nu kon ik het allemaal hebben!
Je sensoren kiezen
Sensoren komen in drie basisvarianten:
- Analog: licht (inclusief IR en UV), windrichting, gassen, belastingcellen...
- I2C: temperatuur, luchtvochtigheid, baro druk, accelerometer, gyroscoop...
- Onderbrekingen (Interrupts): regentonners, windsnelheid, bliksem, timers... (Functies als serieel, PWM, klokken, servos gebruiken timing-interrupts)
De MKR1000 heeft voldoende I/O voor al deze typen!
LET OP DE SPANNING DIE JE NODIG HEBT VOOR JE I/O OP I2C EN INTERRUPTS! Bijvoorbeeld, de MKR1000, de Photon, en veel Arduino-varianten gebruiken 3,3V I/O in plaats van 5V. Als je CPU en de sensor(en) die je wilt gebruiken verschillende spanningen gebruiken, heb je ook level-shifters nodig tussen die apparaten.
Alle sensoren die ik gebruik zijn algemeen verkrijgbaar via Adafruit, SparkFun, Element-14 en anderen, en kosten meestal tussen $5-10 (US). Gassensoren kosten meestal $10-$20. Voor de bliksemdetector (AS3935-chip) koos ik de Embedded Adventures MOD-1016, die $26 (US) kost om de antenne op het bord te krijgen. Ik kocht ook de Sparkfun Photon Weather Shield, omdat ik een Photon heb, en ik zal waarschijnlijk hun "weather meters" (windsnelheid en richting instrumenten) kopen. Misschien voeg ik later een Bodemvochtigheidssensor toe, zodra ik uitmaak waar ik de MKR1000 ga monteren. Sommige sensoren houden niet van lange leads.
Je sensoren toewijzen aan pinnen
Zodra je weet welke sensoren je wilt, weet je welke typen ingangen je nodig hebt. De volgende stap is te beslissen welke sensoren op welke pinnen gaan. Ik begin op papier, maar ik voeg deze lijst ook als blokcommentaar in mijn code toe, als herinnering.
Hier zijn de MKR1000 pin-toewijzingen die ik voor mijn sensor-deck gemaakt heb:
- A0 (Ik reserveer A0 voor het geval ik de DAC later nodig heb...)
- A1 ML8511 UV-sensor
- A2 Zichtbaar-lichtsensor (TEMT6000)
- A3 TMP36 lokale temperatuursensor
- A4 MQ-9 gassensor
- A5 Vochtigheidssensor
- A6 Windsnelheidssensor?
- 0 (HW INT) Drukknop
- 1 (HW INT) AS Bliksemdetector
- 2 (HW INT) Windsnelheid aanemometer (interrupt per rotatie)
- 3 (HW INT) Regentonner…
- 4
- 5
- 6 (gedeeld met on-board LED)
- 7 NeoPixel-uitgang…
Aan de slag...
Voor beginners raad ik aan om met elke sensor die je gaat gebruiken, één voor één te beginnen, en de voorbeeldcode te laden, en de benodigde bibliotheken te installeren. Vergeet niet de sensorpin te wijzigen naar de pin-toewijzing van je keuze, en bewaar een kopie van de democode in je projectmap.
Als je de testcode kunt draaien en de resultaten kunt lezen via de Seriële Monitor, ben je klaar om de volgende sensor toe te voegen. En als je klaar bent met testen van elke sensor, zijn ze allemaal bedraad en klaar om je grotere sketch te bouwen!
Mijn oorspronkelijke experimenten met de sensoren omvatten een I2C-gebaseerde Real-Time Clock (RTC), zodat ik kon loggen naar een SD-geheugenkaart. Hoewel de MKR1000 een eigen RTC en batterij heeft, kon ik de klok niet met alleen de batterij laten lopen, dus ik houd de ChronoDot v2.1 I2C RTC ook.
Kijk naar het breadboard in mijn afbeelding hieronder, je ziet de diverse jumpers in gebruik. De oranje zijn voor de 3,3V voeding naar elke sensor, zodat ik ze alleen insteek als ik ermee aan het werk ben. (Het is makkelijk een sensor uit te schakelen door de oranje jumper eruit te halen.)
Een opmerking over bibliotheken
Ik heb ontdekt dat sommige bibliotheken die je kunt installeren, NIET perfect werken met de MKR1000, en/of met Arduino.cc IDE versie 1.6.7, en je moet misschien wat tunen, afhankelijk van hoe oud je sensor is. Een voorbeeld is de oudere ATOMIC_* macro's in de oudere AVR libc bibliotheek (ze zijn verwijderd in Arduino IDE 1.6.5), en er is een geweldig draadje over problemen en voorgestelde oplossingen in een forumtopic op Arduino.cc. Het aanbrengen van enkele van de voorgestelde wijzigingen is iets voor een intermediaire Arduino-hacker, maar zal waarschijnlijk intimiderend zijn voor nieuwere hackers. En voor iets oudere bibliotheken is de oorspronkelijke auteur misschien niet meer in de buurt om de bibliotheek bij te werken en de afhankelijkheid te elimineren.
Helaas kun je meestal niet weten welke bibliotheken getund moeten worden voordat je je sensoren koopt en test. Op dat moment raad ik aan de foutmeldingen die in oranje verschijnen bij het uploaden van je sketch zorgvuldig te bestuderen, om te zien of het probleem in jouw code zit of in een bibliotheek, voordat je begint met je code te wijzigen. Als het in de bibliotheek zit, doe een webzoekopdracht naar "arduino" en de foutmelding. Als je geen oplossing vindt, probeer de auteur te mailen en laat ze weten over de fout, misschien updaten ze de bibliotheek.
Ik heb individuele chips gekocht om geld te besparen. Ik heb besloten dat, totdat ik klaar ben om mijn eigen printplaten te maken (waarschijnlijk met EagleCAD en OSHPark), het makkelijker is om sensormodules van Adafruit en SparkFun te kopen, omdat ze geweldig zijn in het up-to-date houden van hun bibliotheken.
Een beetje over WiFi en Encryptie
Ik dacht ook aan de WiFi om mijn weersensoren te laten rapporteren naar een website. We hebben zelfs een encryptiemotor op de MKR1000, om onze data veilig te houden tijdens transit over het Internet! Maar dat is meer dan ik in dit eerste project kan doen. Het staat op mijn lijst, omdat het maken van datastructuur onderdeel van je ontwerp belangrijk is voor het Internet of Things, maar ik loop uit aan tijd voor mijn inschrijving voor de MKR1000-wedstrijd. Kijk uit voor mijn "versie 2" van dit project. Hier is een blokdiagram van de SAMD-module die het hart is van je bord.
Ik kan je één tip geven om te beginnen met de on-board WiFi: Zorg ervoor dat je de meest recente versie van de WiFi101-bibliotheek gebruikt! Als je dat niet doet, herkent je sketch de WiFi-module niet, en je WiFi-sketches zullen alleen melden dat er een fout is als er foutcontrole op de aanroepen naar de WiFi-module zit. Ik moet Charif Mahmoudi danken voor het wijzen daarop in zijn geweldige "Getting Started with MKR1000" tutorial hier op Hackster! Op het moment van mijn knutselen was de WiFi101 GitHub hier te vinden.
Tips voor Analog Sensoren
Meeste "analoge uitgang" sensormodules produceren een simpele analoge spanningsuitgang, en dit is eenvoudig te lezen met de analogRead van de sensorpin. Maar dan moet je weten wat dat betekent. Normaal gesproken zul je het map commando moeten gebruiken, of je moet een beetje rekenen. Weerstandselementen hebben meestal extra schakelingen nodig. Je wilt misschien een potentiometer toevoegen om de spanning "fijn af te stellen".
In andere gevallen heb je vergelijkingen nodig om de uitgangsspanning om te zetten in iets dat mensen begrijpen. De TMP36 temperatuursensor is een goed gedocumenteerd voorbeeld hiervan. Dit onderdeel was ontworpen om uit te lezen in graden Celsius, dus je moet de spanning meten en wat rekenen om C te krijgen, en als je Fahrenheit wilt, moet je C naar F converteren. Het lezen van de datasheets van componenten legt uit hoe het onderdeel werkt, maar je vindt het makkelijker om in iemands voetsporen te treden terwijl je je ervaring opbouwt.
Andere sensoren hebben een versterker nodig, om de kleine spanningswisselingen groot genoeg te maken voor je ADC om een goed bereik van hoog naar laag te krijgen. Deze typen sensoren (belastingcellen, vochtigheid, accelerometer) zijn waar ik het beste geld uitgeef, en een module koop die al een versterker en een bibliotheek heeft om het bereik van de uitgang te begrijpen.
Tips voor het gebruik van I2C-apparaten
I2C wordt soms een "two-wire interface" genoemd, omdat je een kloksignaal en een datasignaal nodig hebt. (Je hebt maar één data-draad nodig, omdat de "master" en de "slave(s)" beurtelings data op die draad zullen sturen.) Natuurlijk hebben je I2C-sensoren ook een ground- en voedingslead nodig, en die ground-lead moet teruggekoppeld worden aan je CPU.
Elk I2C-apparaat heeft een hexadecimaal adres op de bus. Het is het beste om meerdere apparaten met hetzelfde adres te vermijden. (Als je multiples wilt hebben, moet je ze beheren met extra schakelingen, om degene die je wilt te communiceren te "enablen", en weer te disablen voordat je een andere voor communicatie enablest.) De documentatie zou moeten vertellen welke adres(sen) een apparaat kan hebben. (LET OP: Als je twee apparaten op de I2C-bus hebt met hetzelfde adres, en beide een "Enable" of "Shutdown"-pin hebben, kun je de ene uitschakelen terwijl de andere wakker is. Je kunt echter niet zomaar de voeding op de VDD-pin uitschakelen, want de sensoren kunnen stroom opvangen van de SDA- en SCL-pinnen, wat resulteert in slechte metingen voor dat adres. De foutcontrole voor I2C is niet goed genoeg om dit geval te detecteren/corrigeren.)
De I2C-specificaties vertellen ons dat we een "sterke" pull-up-weerstand op zowel de klok- als de dataleads moeten hebben, op de sensor die het verst op de draad zit. Hierdoor hebben sommige sensormodules al weerstanden op het bord, en hoef je misschien alleen een paar jumpers toe te voegen, dus lees zeker de documentatie voor de module(s).
Naast de "bus-ending-weerstanden", heb ik ook een hint gevonden van een hacker lang geleden, om een weerstand in serie te zetten in zowel de data (SDA) als klok (SCL) leads. Dit verbeterde de betrouwbaarheid van data-uitlezing van een paar sensoren aanzienlijk. Met de MKR1000, die 3,3V signalering gebruikt, gebruik ik 220Ω weerstanden. Op een 5V CPU wil je misschien 330Ω proberen. Zie het schema hieronder voor het verschil in plaatsing.
Wat ga je met de data doen?
Op dit moment stuurt ik het alleen naar de Seriële Monitor. Je kunt een LCD toevoegen. Ik wilde een SD-kaart toevoegen, maar nu ik ingebouwde WiFi heb, wil ik de data naar een cloud uploaden... stel je voor dat je een paar van deze sensor-decks hebt, met bekende lengte- en breedtegraad, en in staat bent een blikseminslag te trianguleren door de stroommetingen van elk station voor een gegeven blikseminslag te vergelijken!
TERZIJDE: 2017-11-29; Ik heb de hardware-interrupts nog niet werkend gekregen op de MKR1000. Ik maak notities en sensorexperimenten voor een 9e-klas (leeftijd 13-14), en misschien vind je de schetsen interessant. De les is gebouwd rond het Adalogger M0-bord, en bewaart de data op een SD-kaart, en er zijn nog steeds genoeg pinnen voor een WiFi-module. https://arduinoclass.pbworks.com
Terwijl ik aan de sensoren werkte, zag ik ook de SODERSVIK-lampfixtuur bij IKEA (zie afbeelding hieronder). Stel je voor dat je de witte LEDs in deze lamp vervangt door 20 NeoPixels, en een IR-ontvanger toevoegt. Waaiende wind zou kunnen lijken op wolken die voorbij trekken, en de kleur kan de temperatuur aangeven. De afstandsbediening kan ook momentaan andere informatie tonen, zoals de temperatuurverandering de afgelopen 12 uur.
Wat wil jij monitoren en weergeven?
Code
De complete monitoring sketch
Er zijn veel sensoren die in deze sketch rapporteren, en de bibliotheken werken goed samen. Echter, de klassieke interrupt-vergrendelingsmethoden in AVR-libc zijn verwijderd in de recente versies van de Arduino IDE, wat de bibliotheken voor NeoPixel en de Bliksemsensor heeft uitgeschakeld. Ik verwacht dat dit ergens dit jaar opgelost wordt, maar het betekent dat ik ze uit de finale sketch heb gelaten.
/********************************
* RTC-Weather-Sensors_v6_MKR1000
* by Zonker Harris, Spring 2016
* Hooray! Een klein bord, met meer dan 2 hardware interrupts!
* Plus WiFi, *en* crypto (HEEL noodzakelijk voor IoT toepassingen!)
*********************************/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_HTU21DF.h>
// Neopixels als placeholder, maar bibliotheek interrupt vector heeft update nodig
// #include <Adafruit_NeoPixel.h>
// const int numLeds = 1;
// Adafruit_NeoPixel strip = Adafruit_NeoPixel(numLeds, 6, NEO_GRB + NEO_KHZ800);
/* BMP085/BMP180 driver gebruikt Adafruit Unified Sensor Library */
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10180);
/* HTU21D-F sensor van Adafruit */
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
/* Macetech Chronodot v2.1 Battery-backed RTC */
int addrRTC = (0x68);
// ... (variabele declaraties voor RTC registers)
int UVOUT = A1; // ML8511 UV sensor
int lightOut = A2; // TEMT6000 zichtbaar licht sensor
int tmp36out = A3; // TMP36 temperatuursensor
int mq9out = A4; // MQ-9 gas sensor
int sounderPin = 6; // Piezo buzzer (gedeeld met on-board LED)
int neopixelPin = 7; // NeoPixel uitgang
void setup(void) {
Serial.begin(9600);
delay(1000);
Serial.println("i2c Sensor Deck");
pinMode(UVOUT, INPUT);
pinMode(lightOut, INPUT);
pinMode(tmp36out, INPUT);
pinMode(sounderPin, OUTPUT);
pinMode(neopixelPin, OUTPUT);
// BMP180 initialiseren
if(!bmp.begin()) {
Serial.println("Ooops, geen BMP085/180 gedetecteerd... Check wiring of I2C ADDR!");
while(1);
}
displaySensorDetails();
// HTU21D initialiseren
if (!htu.begin()) {
Serial.println("Kon HTU21-DF sensor niet vinden!");
while (1);
}
// Chronodot RTC initialiseren (waarden aanpassen, uncomment, upload, comment weer uit)
/* seconds = 0; minutes = 41; hours = 20; day = 7; date = 3; month = 1; years = 16; initChrono(); */
}
void loop(void) {
beep(50, 2); // start lus aan kondigen op buzzer
// Chronodot RTC uitlezen (0x68)
Wire.beginTransmission(0x68);
Wire.write((byte)0);
Wire.endTransmission();
Wire.requestFrom(0x68, 13);
// ... BCD data uitlezen en converteren ...
get_date();
Serial.print("ChronoDot - ");
Serial.print(hours10); Serial.print(hours1); Serial.print(":");
Serial.print(minutes10); Serial.print(minutes1); Serial.print(":");
Serial.print(seconds10); Serial.print(seconds1); Serial.print(" 20");
Serial.print(years); Serial.print(" "); Serial.print(month); Serial.print(" ");
Serial.print(date); Serial.print(" \t"); Serial.print(temprtc); Serial.println(" C");
delay(100);
// BMP180 data (0x77)
sensors_event_t event;
bmp.getEvent(&event);
float BMPtemperature;
bmp.getTemperature(&BMPtemperature);
float BMPtempF = (BMPtemperature * 1.8 + 32);
Serial.print("Temp: "); Serial.print(BMPtemperature); Serial.print(" C (");
Serial.print(BMPtempF); Serial.print(" F) \t");
if (event.pressure) {
Serial.print("BMP180 - Pres: "); Serial.print(event.pressure); Serial.print(" hPa\t");
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
Serial.print("Alt: "); Serial.print(bmp.pressureToAltitude(seaLevelPressure, event.pressure)); Serial.println(" m");
} else {
Serial.println("Sensor error");
}
delay(100);
// HTU21-DF data (0x40)
float HTUtemperature = htu.readTemperature();
float HTUtempF = (HTUtemperature * 1.8 + 32);
Serial.print("HTU21-DF - Temp: "); Serial.print(HTUtemperature); Serial.print(" C (");
Serial.print(HTUtempF); Serial.print(" F)\tHum: "); Serial.print(htu.readHumidity()); Serial.println("%");
delay(100);
// TMP36 analog temperatuur
int reading = averageAnalogRead(tmp36out);
float tmp36voltage = 0.0032258064516129 * reading; // 3.3V / 1023
float tmp36temperatureC = (tmp36voltage - 0.5) * 100;
Serial.print("TMP36 - temp: "); Serial.print(tmp36temperatureC); Serial.print(" C \t");
float tmp36temperatureF = (tmp36temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(tmp36temperatureF); Serial.print(" F, out: "); Serial.print(tmp36voltage); Serial.println("v");
delay(100);
// TEMT6000 zichtbaar licht
int vLevel = averageAnalogRead(lightOut);
float newVOutVolts = 0.0032258064516129 * vLevel;
Serial.print("TEMT6000 out: "); Serial.println(vLevel);
delay(100);
// ML8511 UV sensor
int uvLevel = averageAnalogRead(UVOUT);
float newOutVolts = 0.0032258064516129 * uvLevel;
float uvIntensity = mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0);
Serial.print("ML8511 UV out: "); Serial.print(uvLevel);
Serial.print(" / UV Intensiteit (mW/cm^2): "); Serial.println(uvIntensity);
delay(100);
// MQ-9 Gas sensor
int MQ9volts = analogRead(mq9out);
Serial.print("MQ-9 Gas: "); Serial.println(MQ9volts, DEC);
delay(100);
Serial.println("");
delay(3500); // loop ~5 seconden
}
// Helper functies: averageAnalogRead, mapfloat, beep, RTC-functies, displaySensorDetails...
// (Zie volledige code op GitHub voor complete implementatie)
Gemiddelde Analog Uitname nemen
Dit was een slimme truc die ik in de SparkFun bibliotheek voor de ML8511 UV-sensor vond, maar ik haal het specifiek uit, want je kunt het voor elke analoge meting gebruiken! Als je Nathan Seidl ooit ontmoet, koop hem een biertje (het is een Beerware-licentie).
int averageAnalogRead(int pinToRead) {
byte numberOfReadings = 8;
unsigned int runningValue = 0;
for(int x = 0; x < numberOfReadings; x++)
runningValue += analogRead(pinToRead);
runningValue /= numberOfReadings;
return runningValue;
}
I2C Bus Scanner
Als je het basisadres voor je I2C-apparaten niet weet, gebruik deze scanner om het bereik van geldige adressen te scannen. Hij kent de sensoren waar ik mee gewerkt heb. Je kunt secties toevoegen voor je andere sensoren.
// I2C Scanner - vindt apparaten op de bus
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Scanner");
}
void loop() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) Serial.print("0");
Serial.print(address, HEX);
// Bekende sensoren labelen
if (address == 3) Serial.print(" - AS3935 Bliksem Sensor");
if (address == 64) Serial.print(" - HTU21D Vocht/Temp Sensor");
if (address == 104) Serial.print(" - DS1307 RTC (Chrono-Dot?)");
if (address == 119) Serial.print(" - BMP180 Baro Druk/Temp Sensor");
Serial.println("");
nDevices++;
} else if (error == 4) {
Serial.print("Onbekende fout op adres 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0) Serial.println("Geen I2C apparaten gevonden\n");
else Serial.println("klaar\n");
delay(5000);
}
ML8511 Demo Code
Aangepast voor gebruik met een 3,3V-native CPU (voor DAC-referentie-eenheden).
/* ML8511 UV Sensor Read Example - SparkFun
* Aangepast voor MKR1000 door Zonker Harris, MAR 2016
*/
int UVOUT = A1;
void setup() {
Serial.begin(9600);
pinMode(UVOUT, INPUT);
Serial.println("ML8511 voorbeeld");
}
void loop() {
int uvLevel = averageAnalogRead(UVOUT);
float newOutVolts = 0.0032258064516129 * uvLevel; // 3.3V / 1023
float uvIntensity = mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0);
Serial.print("ML8511 out: "); Serial.print(uvLevel);
Serial.print(" / UV Intensiteit (mW/cm^2): "); Serial.print(uvIntensity);
Serial.println();
delay(100);
}
// averageAnalogRead en mapfloat functies hierboven...
Schema
Ik ben te nieuw voor Fritzing en kon niet veel onderdelen in de bibliotheek vinden, dus maakte ik deze mock-up:
Productieproces
- Sensordata integreren in een Raspberry Pi: Een praktische gids
- Lijnvolgsensor met Raspberry Pi – Simpele KY-033 deur/lijndetector
- Een robuuste temperatuur- en sensor-API bouwen op Raspberry Pi met de GY-91-module
- Een geautomatiseerd aeroponisch systeem bouwen met Raspberry Pi en vochtigheidssensor
- Raspberry Pi GPIO onder de knie: Een PIR-bewegingsensor interfacen op B+/Model 2
- De Acconeer A111 gepulste radar integreren met een Raspberry Pi: Een praktische gids
- Hoe de HC‑SR501 PIR-bewegingsensor aan te sluiten, kalibreren en programmeren met een Raspberry Pi
- Python/MicroPython Sensor Logger: Naadloos Sensordata Opslaan in Google Sheets
- Adafruit 10DOF IMU-data van Raspberry Pi 2 naar Azure Event Hubs Sturen met Windows 10 IoT Core
- Netjes Afslapen & Slaapstand voor Raspberry Pi – DIY Stroombeheercircuit
- Hoe sensorfusie betrouwbaarheid, beveiliging en efficiëntie verbetert in autonome systemen