Hemautomation projekt baserat på 1-wire enheter
Arduino Mega 2560 http://arduino.cc/en/Main/arduinoBoardMega2560
Integrerade kretsar:
Maxim DS18B20 http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
Maxim DS2413 http://datasheets.maximintegrated.com/en/ds/DS2413.pdf
Panasonic AQH3213 http://www.panasonic-electric-works.com/peweu/en/downloads/ds_61613_en_aqh.pdf
UTP kablage med RJ11-kontakter (stjärnatopologi med seriella bussar, flera enheter på varje buss)
Skicklig av hantering:
8 1-wire bussar (med dynamisk klassinstanser för biblioteket)
256 växlar
256 reläer
128 temperaturgivare (icke-parasit läge för snabbare buss)
* Switch-till-relay sammanslutningar är fritt programmerbara
* Ingen hög spänning och ström kablar på väggströmbrytare, bara 12V DC över UTP-kabel
* Lägre surge nuvarande och elektromagnetisk strålning eftersom SSRs slå på och av vid noll korsning
* Växlar skannas kontinuerligt Arduino - följden växling av reläer/lampor arbete omedelbart precis som för normala lampa växlar (många hemautomation system är lite långsam, med igenkännbara fördröjning)
* Enda 3.9 k pull-up motstånd på Arduino stiften (passiv pull-up lösning)
* PIR rörelsesensorer, ljussensorer etc. kan användas som växla anordningar samt (monostable läge med justerbar timer)
* Reläer är AC (SSR) eller DC (MOSFET) för LED-belysning etc.
* Nuvarande begränsning: SSR maximal ström är 1.2a belastning bör därför mindre än 250W (på 220V AC)
* Temperaturgivare läsbar när som helst - de är "dolda" i väggströmbrytare
* Enheten data och inställningar lagras i EEPROM av Arduino styrelsen - systemet fungerar även efter strömavbrott
* Förändringar är programmerade av seriell kommandon från datorn, men det fungerar fristående också utan en PC ansluten
* Av design komplexa funktioner som inte ska tiden kritiska hanteras på PC nivå istället för micro controller - e.g aktivering av uppvärmning baserad på genomsnitt temperatur värden
Kommandot exempel:
R4 > 1 slå på lampan ansluten till Relay4
R4:1 (svar)
Scan Scan för nya anslutna enheter
Nya enheter läggs (lista med ID: N)
T8? Temperatur mäts av temperaturgivare
T8:18.7
R14? Tillstånd av relay
R14:1
S9 > R6 Switch9 bunden till Relay6
S9 > R7 Switch9 också bunden till Relay7 (vägg switch 9 kommer att styra lampor (eller andra laster) 6 och 7 från nu på)
Status meddelande exempel:
R2:0 Lampa är ansluten till Relay2 har inaktiverats av en av de associerade växlarna eller kommandot
---
Kodavsnitt (förenklad)
Behandlingen temperaturgivare:
#include OneWire.h
#include EEPROM.h
OneWire * ow; klass värde initiering
byte addr [8]. matrisen att lagra 1-wire enhetsadress
flyta celsius;
byte m; temperatur sensor nummer (varje sensor adress använder 4 byte i EEPROM)
buss byte; Arduino stift att använda (pin = buss + 1)
void MeasureTemp()
{
addr [0] = 40; hex28
addr[1]=EEPROM.Read(m*4); Adress byte 1-4 (betydande byte) lagras på dessa positioner
addr[2]=EEPROM.Read(1+m*4);
addr[3]=EEPROM.Read(2+m*4);
addr[4]=(EEPROM.Read(3+m*4)) & 15.
addr [5] = 0; byte 5 ad 6 av 1-wire enheten adressen är alltid 0
addr [6] = 0;
addr[7]=addrOneWire::crc8(addr,7); byte 7 (CRC) genereras från de föregående 7 byte
AJ = nya OneWire(bus+1); skapandet av klassförekomst
ow -> .reset();
ow -> select(addr); Välj temperatursensor
ow -> write(68); Starta konvertering, med zener (buss kan användas under konverteringen)
Delete(ow); borttagning av klassförekomst
}
{800 ms fördröjning (med timer rutin) så att DS18B20 beräkna 12 bit temperatur}
void ReadTemp()
{
addr [0] = 40;
addr[1]=EEPROM.Read(m*4);
addr[2]=EEPROM.Read(1+m*4);
addr[3]=EEPROM.Read(2+m*4);
addr[4]=(EEPROM.Read(3+m*4)) & 15.
addr [5] = 0;
addr [6] = 0;
addr[7]=addrOneWire::crc8(addr,7)
AJ = nya OneWire(bus+1);
ow -> reset();
ow -> select(addr);
ow -> write(190); kommandot för att läsa sensorn
datalow = ow -> read(); läsa byte 1 och 2 bara, faktisk temperatur värdet
datahigh = ow -> read();
Delete(ow);
unsigned int rå = (datahigh << 8) | datalow; skiftande bitar upp till form en 12 bitars värde
Celsius = int (((float) raw / 16,0) * 10);
}
Serial.println (celsius/10). Resultatet är i Celsius med 0.1 grad noggrannhet
---
Behandlingen switch status:
byte PIOdata;
byte k; växel-ID
void ReadPIO()
{
ow -> reset();
addr [0] = 58.
addr[1]=(EEPROM.Read(2048+k*8));
addr[2]=(EEPROM.Read(2049+k*8));
addr[3]=(EEPROM.Read(2050+k*8));
addr[4]=(EEPROM.Read(2051+k*8) & 15); Adress byte är alltid mindre än 15
addr [5] = 0;
addr [6] = 0;
addr[7]=OneWire::crc8(addr,7);
ow -> select(addr); Välj Byt
ow -> write(245); PIO läsa kommando
PIOdata = ow -> read();
om (PIOdata == 30) / / Apå stängs *
{
ToggleLamp(); Relay staten inverterad och kort fördröjning lagt till att förhindra att flaxa
}
}
* om båda kontakterna är öppna är resultatet 15
bit 0 DS2413 stift 6 (PIO A) ingång nivå
bit 1 DS2413 stift 6 (PIO A) inverterad (!) output nivå (styr output transistor), 0 = transistor drar pinnen till jord
bit 2 DS2413 pin 4 PIO B input nivå
bit 3 DS2413 pin 4 PIO B inverterad utgångsnivån
bit 4-7 inverterade värden BITS 0-3
som ett resultat 15 (0000 1111) betyder både innivåer är hög (bitarna 0 och 2) på grund av 22 kohm pullup motstånd och båda utdata transistorer är öppna (bitar 1 och 3) de tillåter utdata till "flyta"
när växeln är slutet är stift 6 kortsluten till marken resulterande bit 0 att ändra till låg:
indatavärdet ändras från 15 (0000 1111) till 30 (0001 1110)
När switch B är stängd (medan Apå släpps) är input 75 (0100 1011)
---
Inverterade Relay tillstånd:
void ToggleLamp()
{
addr [0] = 58.
addr[1]=(EEPROM.Read(1020+m*4));
addr[2]=(EEPROM.Read(1021+m*4));
addr[3]=(EEPROM.Read(1022+m*4));
addr[4]=(EEPROM.Read(1023+m*4) & 15);
addr [5] = 0;
addr [6] = 0;
addr[7]=OneWire::crc8(addr,7);
ow -> reset();
ow -> select(addr); Välj relä,
ow -> write(245); PIO läsa kommando
PIOdata=dv.read();
om (PIOdata == 15) / / transistorer är öppen (= relä är öppen)
{
ow -> reset();
ow -> select(addr);
ow -> write(90); PIO skriva kommandot
ow -> write(254); slå på transistorn A *
ow -> write(1); inverterad byte måste skrivas samt för kontroll (!)
Serial.Print("R");
Serial.Print (m).
Serial.println (": 1");
}
om (PIOdata == 120) / / relä stängs
{
ow -> reset();
ow -> select(addr);
ow -> write(90); PIO skriva kommandot
ow -> write(255); stänga av transistorn A *
ow -> write(0); inverterad byte måste skrivas samt för kontroll (!)
Serial.Print("R");
Serial.Print (m).
Serial.println (": 0");
}
}
* I SSR inre LED drivs av transistorn A (PIO A produktionen) av växeln 1-wire pin 6. När bit 0 är 0 (111111 10) handtag transistorn utgångsnivån till GND - aktiverande LED och i SSR. Av inställningen bit 0 till 1 (111111 11) inaktiveras i SSR.
Output B används inte i min krets, men naturligtvis kunde det aktiveras på samma sätt med bit 1 (111111 01). De återstående sex bitarna måste vara hög hela tiden.
Eftersom både växlar och relay använder DS2413 marker de göras åtskillnad mellan när en ny enhet läggs. En rutin aktiverar transistor A under en kort period. Om fjärrenheten är ett relä logiska detekteras låg på PIO B input eftersom de två stiften är anslutna.
Pågår:
-Test av PIR-sensorer och tillägg av justerbar fördröjning funktion i programvaran
* Utveckla tryckgivare
* Ändra OneWire biblioteket om du vill tillåta parallell drift på alla bussar (för närvarande allt 1-wire kommandon är sekventiella)
* Testa 1-wire Overdrive läge
* Webbaserat fjärrhantering (PHP + UDP)