Slimme Huisautomatisering met Raspberry Pi 2 & Windows 10 IoT
Onderdelen en benodigdheden
| Onderdeel | Aantal | Opmerking |
|---|---|---|
| Arduino UNO | 1 | Voor elke kamer die je wilt automatiseren, neem een aparte Arduino UNO. |
| Raspberry Pi 2 Model B | 1 | |
| Jumper draden (generic) | 1 | |
| Breadboard (generic) | 1 | |
| LDR (Lichtgevoelige Weerstand) | 1 | LDR levert verschillende spanningswaarden voor verschillende lichtintensiteit. |
| PIR Bewegingssensor (generic) | 1 | Passieve IR detecteert menselijke aanwezigheid. |
| Relais (generic) | 1 | Je kunt elk type relaismodule gebruiken. Aantal relais hangt af van hoeveel apparaten je wilt besturen. [AantalApparaten = AantalRelais] |
| Siemens Contactor (3TF32 00-0AP0) | 1 | Contactor wordt gebruikt om waterpomp te besturen max AC3: 16A 415VAC. Controleer ratings van je waterpomp en landelijke voorschriften. "3TF32 00-AP0" kan tot 16A en 415VAC aan. De spoel werkt op 250VAC. |
| Miniature Circuit Breaker (1P C16A) | 1 | MCB zit voor de contactor om waterpomp te beschermen tegen elektrische fouten en overbelasting. MCB heeft ook specifieke ratings. Onze contactor is 16A, dus 16A MCB gebruikt. Pas aan naar wens. |
Apps en online diensten
- Arduino IDE - Om Arduino-firmware te schrijven. Uitgelegd in het artikel.
- Microsoft Visual Studio 2015 - Community-editie is aanbevolen en gratis voor maximaal vijf gebruikers. Hogere versies mogelijk als je een licentie hebt.
- Microsoft Windows 10 IoT Core - Als primair besturingssysteem, dat apparaten bestuurt via Arduino en een beheerconsole biedt.
Over dit project
In het huidige tijdperk kan technologie het menselijk leven verbeteren. Technologie evolueert decennium na decennium. Automatisering was vroeger sciencefiction, maar niet meer. Door de nieuwste technologie met een huis te combineren, kunnen we een geweldig slim huis bouwen. Met de Raspberry Pi en Windows 10 kunnen we een huisautomatiseringssysteem bouwen dat in staat is om huishoudelijke apparaten automatisch te bedienen.
Aan de slag
Voordat we het project starten, laten we de basis begrijpen. Overweeg de volgende afbeelding (Algemene Configuratie):

Configuratie voor een kamer
In een kamerscenario bestuurt een Arduino UNO apparaten en leest sensordata. Periodiek vraagt de Raspberry Pi de sensordata op die door de Arduino UNO is verzameld. De afbeelding "Kamerarchitectuur" toont hoe de Arduino UNO met apparaten en sensoren verbonden is. Elke kamer heeft meerdere te besturen apparaten (licht(en), ventilator, wandstopcontact(en), etc.), één PassiveIR (om menselijke aanwezigheid te detecteren), één temperatuursensor (LM35 voor kamertemperatuur) en een LDR (om lichtintensiteit bij het raam te detecteren).

Apparaatadressering
Het belangrijkste deel is hoe we apparaten identificeren. Dat is simpel: we maken een apparaatadres door het kamernummer te combineren met het apparaatnummer.
Bijvoorbeeld:

Nu weten we de algemene configuratie. Kortom: een Raspberry Pi fungeert als primaire controller. Elke kamer heeft zijn eigen Arduino UNO die fungeert als slave van de Raspberry Pi. Communicatie tussen Raspberry Pi en Arduino UNO gebeurt via I2C.
Schema's
Om het makkelijker te maken, beginnen we met de implementatie voor de eerste kamer. Raadpleeg het schema om componenten correct te verbinden.
I2C Bus Strook: Om meer dan één Arduino te koppelen, kun je een I2C Bus Strook gebruiken zoals hieronder getoond.



Hoe een apparaat te bedraden met een relaisbord?

De hardware is klaar. Nu is het tijd om software te bouwen.
Software
Ons project bestaat uit een Raspberry Pi 2 en een Arduino UNO. De Raspberry Pi 2-software is ontwikkeld in Visual Studio 2015. Ik ga ervan uit dat de lezer bekend is met projectaanmaak voor Raspberry Pi 2 in Visual Studio 2015. Ik ga ook ervan uit dat de gebruiker intermediêre kennis heeft van het Arduino-framework, Visual C# en Windows Universal XAML.
Laten we de software als volgt begrijpen:
- Protocol (Hoe Raspberry Pi 2 en Arduino praten)
- Klasstructuur (Hoe Raspberry Pi 2 dergelijke complexe apparaten en kamers beheert)
- Gebruikersinterface (Wireframe)
Protocol (Hoe Raspberry Pi 2 en Arduino via I2C communiceren)
Voordat we verdergaan, laten we eerst beslissen hoe Raspberry Pi en Arduino communiceren. Om een betrouwbaar protocol te maken, moeten we eerst duidelijke doelen hebben voor de communicatie. In het kader van dit project zijn de doelen:
- Sensoren uitlezen
- Apparaatstatus uitlezen
- Apparaatstatus instellen
Laten we het protocol definiëren. Een protocol definieert regels voor communicatie over de bus. Een protocol is niets meer dan een bytesequentie.
Ik heb een protocol gedefinieerd voor het verzenden en ontvangen van bytes. Verzendbytes zijn vast drie, terwijl het ontvangen byte-array 14 bytes is.
Raadpleeg de volgende schema's om het protocol te begrijpen ('X' duidt op willekeurige waarde of '0', wordt genegeerd tijdens communicatie):





De klasse 'I2C_Helper' bevat de implementatie van het protocol in het Universal App-project van de Pi. Deze klasse is beschikbaar in het Universal Windows Project. Om het te openen: Ga naar Solution Explorer > Library > Communication map. Aan de Arduino-kant is de I2C-bibliotheek eenvoudig te begrijpen.
Nu hebben we een goed communicatieschema gedefinieerd dat status en waarden van sensoren en apparaten kan geven en ook toegang biedt om de apparaatstatus in te stellen.
Klasstructuur (Hoe Raspberry Pi 2 objecten beheert)
Zoals besproken, beschouwt dit project het hele huis. Een huis bestaat uit meerdere kamers en een kamer bestaat uit meerdere apparaten. De OOP-structuur van zo'n configuratie is hieronder getoond:


Primaire klasse "Home" bestaat uit meerdere kamerobjecten als generische lijst van kamers (List<Room>). De Home-klasse biedt statische methoden om het home-object op de Pi te laden en op te slaen voor later gebruik.
Een kamer bestaat uit apparaten als generische lijst van apparaten (List<Device>) en een sensorstructuur om alle sensoren in één te encapsuleren.
Een apparaat bestaat uit details ervan en functies om ze aan en uit te zetten via protocol Modus 2. AmbientLight, PassiveIR en Temperature-klassen bieden toegang tot de omgevingsdata van de kamer. Het Room-object houdt sensordata bij en ververst deze periodiek via protocol Modus 0.
Gebruikersinterface
Elke applicatie moet gebruiksvriendelijk zijn. Om een gebruiksvriendelijke applicatie te maken, begin met een wireframe. Stel je voor dat je je eigen applicatie gaat gebruiken en vind de belangrijkste doelen en hoe je ze integreert op een manier die voor de eindgebruiker het makkelijkst is.
In het scenario van deze applicatie zijn onze hoofddoelen:
- Kamerbeheer
- Apparaatbeheer
- Externe diensten zoals GSM-communicatie, internetcommunicatie, etc.
Om dit te doen, heb ik het probleem opgesplitst in:
- Home-pagina: Basisinformatie over apparaatstatus, datum-tijd en vergrendeling
- Favoriete apparaten: Directe toegang tot favoriete apparaten
- Kamerpagina: Toegang tot geconfigureerde kamers en hun apparaten
- Gemeenschappelijke waterapparaten: Waterpomp en geiser
- Instellingen/Configuratie: Beheer van kamers en hun apparaten
Wireframe





Op basis van de wireframe heb ik de UI ontwikkeld die hieronder getoond wordt. Je kunt de complete broncode downloaden. De downloadlink staat aan het einde van het artikel.














Dus, de UI is al ontwikkeld. Hoop dat je het kunt aanpassen aan je behoeften. Voel je vrij om commentaar te geven voor hulp.
Hoe te configureren?
Ik heb geprobeerd de software zo makkelijk mogelijk te maken. Met kleine configuratie kun je apparaten direct bedienen met deze Raspberry Pi 2. Stap-voor-stap configuratie wordt hieronder getoond:








Hoe bedien ik waterpomp en geiser met deze app?
Je kunt waterpomp en geiser op dezelfde manier toevoegen als een apparaat. Maar je kunt waterpomp of geiser niet direct aan het relaisbord koppelen om ze te voeden. Dat zou het relaisbord laten exploderen en is gevaarlijk.
Om waterpomp of geiser te bedienen, verbind ze met een contactor en verbind de spoel van de contactor met het relaisbord. Nu, wanneer je het apparaat bedient, activeert het relais de spoel van de contactor en start/stopt de pomp of geiser. Voordat je een contactor koopt, controleer de spoelrating en de contactor-rating. Contactoren zijn in veel variaties verkrijgbaar. Controleer het met de rating van je waterpomp. Het is raadzaam een iets hoger gerate contactor te kopen dan de rating van je waterpomp.
Hoe implementeer ik deze oplossing op Raspberry Pi 2?
Je kunt deze link raadplegen om het implementatieproces te begrijpen.
Hoe registreer ik deze app als opstart-app?
Veel hobbyisten willen dat hun applicatie direct na het opstarten van de Raspberry Pi 2 start. Lees mijn artikel: Windows 10 IoT Core: Setting Startup App.
Bekende problemen
Arduino Opstarten
Wanneer Arduino opstart, knippert de D13-pin. Het is goed om geen relaispin op D13 aan te sluiten, want wanneer Arduino opstart of herstart, knippert D13 een keer en als er een apparaat op een relais zit (bestuurd via D13), zal dat ook knipperen.
Oplossing: Twee opties: een, sluit gewoon geen relais aan op D13. Twee, herschrijf de OptiBoot-firmware van Arduino zodat D13 niet gebruikt wordt tijdens het opstarten en brand die bootloader op de Arduino.
Klokprobleem
Raspberry Pi 2 heeft geen on-board Real Time Clock-chip. Daarom is het niet mogelijk om de tijd na een stroomstoring of koude start te behouden. Een externe RTC moet worden aangesloten en geprogrammeerd om datum/tijd te behouden.
Oplossing: NTP kan worden gebruikt, maar vereist internetverbinding of zelfs Arduino kan omgaan met RTC en Raspberry Pi vraagt datum/tijd op bij opstart. Het is ook goed om een externe RTC direct met de RPi 2 te verbinden.

Debug-probleem
Ik heb veel problemen ondervonden tijdens het ontwikkelen van de Universal App in C#. Universal app is een superset van WinRT en vereist veel asynchrone operaties. Als er een fout optreedt in een asynchrone operatie, wordt het een hoofdpijn om op te lossen. Wanneer een uitzondering of fout optrad, kwam ik meestal het volgende scherm tegen:

Geen wijzing naar de foutieve regel, geen programmeervriendelijk bericht, niets. Ik moest veel breakpoints plaatsen om de oorzaak te vinden. Soms sluit de universal app plotseling af zonder voorafgaande waarschuwing en wordt mijn watch-venster onbruikbaar. De oorzaak van dit gedrag wordt beschreven hier.
Oplossing: Plaats breakpoint vóór de verwachte foutgevoelige regel.
Kortom, op dit moment (terwijl dit artikel gepubliceerd werd) is universal app geweldig, maar mist debugfuncties die conventionele Windows-applicaties wel hebben.
Toekomst
Er is geen limiet wat betreft functies, nieuwe ideeën of zelfs het overwinnen van bestaande beperkingen. Maar het is niet haalbaar om elke functie tegelijk toe te voegen. Bij deze release laat dit artikel je de echte kracht van Raspberry Pi 2 en Windows IoT zien. Windows Universal XAML is een geweldig GUI-framework voor Windows 10 IoT & Raspberry Pi 2 heeft een goede grafische processor aan boord. Door deze twee te combineren, kan een buitengewone GUI-oplossing worden gecreëerd. Bovendien heeft Raspberry Pi 2 een 900MHz quad-core CPU, wat prima is voor multi-threaded (in UWP, Task) oplossingen. Dit is een basaal tot intermediair project voor wie de fundamentals van embedded en softwaresystemen wil leren (I2C-buscommunicatie, hoe apparaten te bedienen, aangepast protocolontwerp, OOP-ontwerp voor real-world applicaties en wireframing).
In de toekomst kunnen we de mogelijkheid toevoegen om te communiceren via externe apparaten met RadioFrequentie of Infrarood in plaats van I2C-bus. Web-beheerportal met Azure kan geïntegreerd worden voor mobiele apparaten. Verder zal echte automatisering geïntegreerd worden zoals gebeurtenisgebaseerde operaties, tijdgebaseerde operaties met RTC-chip. Bijvoorbeeld: schakel achtertuinverlichting in om 19:00 en uit om 22:00; een goed voorbeeld van gebeurtenisgebaseerd is het inschakelen van tuinverlichting wanneer de omgevingslichtintensiteit onder een bepaalde drempel daalt, enz. Er is geen limiet voor dit nieuwe Windows 10 IoT Core-platform voor Raspberry Pi 2.
Succes & Veiligheid.
Voel je vrij om om hulp te vragen of vragen te stellen.
Code
Arduino Sketch
/* Arduino Sketch v0.4
Deze sketch is geschreven voor "Home Automation using Raspberry Pi 2 and Window 10 IoT"
Raadpleeg deze link: https://www.hackster.io/AnuragVasanwala/home-automation
Deze sketch is getest op Atmega328p alleen.
Deze sketch bereidt een Arduino-apparaat voor als slave-apparaat op I2C-bus bediend door Raspberry Pi 2 met Windows 10 IoT Core.
Doelstellingen:
+ Periodiek sensordata verzamelen (Functie: loop)
+ OnReceive, verzamel 3-bytes modusinstructie en voer operatie uit op basis daarvan. (Functie: ReceiveData)
+ OnRequest, stuur 14-bytes responsarray gebaseerd op geselecteerde modus door OnReceive. (Functie: SendData)
Deze sketch wordt geleverd zoals het is zonder enige GARANTIE. Je kunt het gebruiken voor persoonlijk en commercieel gebruik. Ik ben niet aansprakelijk voor gegevensverlies of letsel veroorzaakt door deze sketch. */
#include <Wire.h>
#define _DEBUG_
/* Arduino's I2C Slave Adres */
#define SLAVE_ADDRESS 0x40
/* PIN DECLARATIE */
int Pin_AmbientLight_LDR = A0;
int Pin_PassiveIR = 2;
int Pin_Temperature = A1;
/* Globale Variabele */
volatile short Value_AmbientLight_LDR, Value_Temperature;
volatile bool Value_PassiveIR;
/* Protocol Variabele */
byte Mode, Pin, Value;
byte Response[14];
void setup() {
// Initialiseer pinnen
pinMode(Pin_AmbientLight_LDR, INPUT);
pinMode(Pin_PassiveIR, INPUT);
pinMode(Pin_Temperature, INPUT);
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
#ifdef _DEBUG_
Serial.begin(9600);
#endif
// Initialiseer I2C Slave op adres 'SLAVE_ADDRESS'
Wire.begin(SLAVE_ADDRESS);
Wire.onRequest(SendData);
Wire.onReceive(ReceiveData);
}
void loop() {
// Lees LDR
// Arduino ondersteunt 10-bit Analog Read.
// Dus we moeten het omzetten naar 8-bit.
Value_AmbientLight_LDR = analogRead(Pin_AmbientLight_LDR);
Value_AmbientLight_LDR = map(Value_AmbientLight_LDR, 0, 1023, 0, 255);
// Lees PassiveIR waarde
Value_PassiveIR = (digitalRead(Pin_PassiveIR) == HIGH) ? true : false;
// Lees Temperatuursensor en Converteer Spanning naar Celsius
Value_Temperature = (short)((float)(analogRead(Pin_Temperature) * 0.48828125));
// Wacht 100 ms
delay(100);
}
// Callback voor I2C Ontvangen Data
void ReceiveData(int byteCount) {
// Lees eerste byte wat Protocol Mode is
Mode = Wire.read();
// Lees tweede byte wat Pin is. Alleen geldig voor Modus 2
Pin = Wire.read();
// Lees derde byte wat Pin-Waarde is. Alleen geldig voor Modus 2
Value = Wire.read();
// Signaal gespecificeerde pin als Modus 2 ontvangen wordt
if (Mode == 2) {
digitalWrite(Pin, Value);
}
#ifdef _DEBUG_
Serial.print(Mode);
Serial.print(" ");
Serial.print(Pin);
Serial.print(" ");
Serial.println(Value);
#endif
}
void SendData() {
switch (Mode) {
case 0: // Modus: Lees Sensor
Response[0] = (byte)Value_AmbientLight_LDR;
// Value_PassiveIR is boolean dus converteren naar byte
Response[1] = (byte)((Value_PassiveIR == true) ? 1 : 0);
// Response[2] byte is Tekenbyte voor Temperatuur
// 0 - negatieve Temperatuur
// 1 - positieve Temperatuur
Response[2] = (byte)((Value_Temperature < 0) ? 0 : 1);
Serial.println(Value_Temperature);
// Negatieve temperatuur kan niet in byte verstuurd. Converteer naar positief equivalent
Response[3] = (byte)((Value_Temperature < 0) ? (Value_Temperature*(-1)) : Value_Temperature);
break;
case 1: // Modus: Lees Apparaten Status
Response[0] = (digitalRead(0) == HIGH) ? 1 : 0;
Response[1] = (digitalRead(1) == HIGH) ? 1 : 0;
Response[2] = (digitalRead(3) == HIGH) ? 1 : 0;
Response[3] = (digitalRead(4) == HIGH) ? 1 : 0;
Response[4] = (digitalRead(5) == HIGH) ? 1 : 0;
Response[5] = (digitalRead(6) == HIGH) ? 1 : 0;
Response[6] = (digitalRead(7) == HIGH) ? 1 : 0;
Response[7] = (digitalRead(8) == HIGH) ? 1 : 0;
Response[8] = (digitalRead(9) == HIGH) ? 1 : 0;
Response[9] = (digitalRead(10) == HIGH) ? 1 : 0;
Response[10] = (digitalRead(11) == HIGH) ? 1 : 0;
Response[11] = (digitalRead(12) == HIGH) ? 1 : 0;
Response[12] = (digitalRead(A2) == HIGH) ? 1 : 0;
Response[13] = (digitalRead(A3) == HIGH) ? 1 : 0;
break;
case 2: // Modus: Stel Apparaatstatus in
Response[0] = (digitalRead(Pin) == HIGH) ? 1 : 0;
break;
default:
break;
}
// Schrijf respons terug
Wire.write(Response, 14);
}
Raspberry Pi 2 (Windows Headed App) Software
https://github.com/AnuragVasanwala/Home-Automation--RPi2-WinIoT-
Schema's
Je kunt meerdere kamers toevoegen door individuele Arduino's met unieke I2C-slave-adressen op de bus te koppelen.
Home%20Automation%20Schematic%20-%20Anurag%20S%20Vasanwala.fzz
Productieproces
- Een externe temperatuursensor bouwen met Raspberry Pi en Python – Stap-voor-stap handleiding
- Een 433 MHz Slimme Huiscounter Bouwen met Sensorflare en Raspberry Pi
- Raspberry Pi-gebaseerde badkamerbezet-sensor met spraak- en SMS-waarschuwingen via Twilio
- Je huis temperatuur monitoren met een Raspberry Pi-dashboard
- Een Raspberry Pi-thuisautomatiseringssysteem bouwen voor afstandsbediening
- Adafruit 10DOF IMU-data van Raspberry Pi 2 naar Azure Event Hubs Sturen met Windows 10 IoT Core
- Nauwkeurige Temperatuur- & Vochtigheidsmonitoring met SHT15 op Windows 10 IoT Core
- Windows 10 IoT Core Installeren op Raspberry Pi 3 Model B+: Stap-voor-stap Handleiding
- Microsoft Kinect Integreren met Raspberry Pi voor Realtime Mensendetectie op de Sonbi-robot
- Automatisering & IoT: De toekomst van supply chain management vormgeven
- IoT & Home Automation: De slimme leefomgeving van morgen vormgeven