Home Automation Project Based on 1-wire Devices

24,597

37

6

Posted

Introduction: Home Automation Project Based on 1-wire Devices

Home automation project using the following components

Arduino Mega 2560 http://arduino.cc/en/Main/arduinoBoardMega2560
Integrated circuits:
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 cabling with RJ11 connectors (star topology with serial buses, multiple devices on each bus)

Capable of handling:
8 1-wire buses (using dynamic class instances for the library)
256 switches
256 relays
128 temperature sensors (non-parasite mode for faster bus)

* Switch-to-relay associations are freely programmable

* No high voltage and power wires at wall switches, only 12V DC over UTP cable

* Lower surge current and electromagnetic radiation since SSRs turn on and off at zero crossing

* Switches are continuously scanned by the Arduino - as a result switching of relays/lamps work immediately just like for normal lamp switches (many home automation systems are a bit slow, with recognizable delay)

* Single 3.9 k pull-up resistors on the Arduino pins (passive pull-up solution)

* PIR movement sensors, light sensors etc. could be used as switch devices as well (monostable mode with adjustable timer)

* Relays are AC (SSR) or DC (MOSFET) for LED lighting etc.

* Current limitation: SSR maximum current is 1.2A therefore load should be less than 250W (at 220V AC)

* Temperature sensors readable anytime - they are "hidden" in wall switches

* Device data and settings are stored in the EEPROM of the Arduino board - system works even after power outage

* Changes are programmed by serial commands from PC, however it works standalone as well without a PC connected

* By design complex functions which are not time critical should be handled on the PC level instead of the micro controller - e.g activation of heating based on averaged temperature values

Command examples:

R4>1 Turn on lamp connected to Relay4
R4:1 (response)

Scan Scan for new connected devices
New devices added(list with IDs)

T8? Temperature measured by temperature sensor
T8:18.7

R14? State of relay
R14:1

S9>R6 Switch9 bound to Relay6
S9>R7 Switch9 also bound to Relay7 (wall switch 9 will control lamps (or other loads) 6 and 7 from now on)

Status message example:
R2:0 Lamp connected to Relay2 has been turned off by one of the associated switches or by command

---

Code sections (simplified)

Reading temperature sensor:

#include OneWire.h
#include EEPROM.h

OneWire *ow;; // class value initialization

byte addr[8]; // array to store 1-wire device address
float celsius;
byte m; // temperature sensor number (each sensor address uses 4 bytes in the EEPROM)
bus byte; // Arduino pin to use (pin=bus+1)

void MeasureTemp()
{
addr[0]=40; // hex28
addr[1]=EEPROM.read(m*4); // address bytes 1-4 (significant bytes) stored at these positions
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; // bytes 5 ad 6 of the 1-wire device address are always 0
addr[6]=0;
addr[7]=addrOneWire::crc8(addr,7); // byte 7 (CRC) is generated from the previous 7 bytes

ow=new OneWire(bus+1); // creation of class instance
ow->.reset();
ow->select(addr); // select temperature sensor
ow->write(68); // start conversion, with zener (bus can be used during the conversion)
delete(ow); // delete of class instance
}

{ 800 ms delay (with timer routine) allowing the DS18B20 calculating the 12 bit temperature value }

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)

ow=new OneWire(bus+1);
ow->reset();
ow->select(addr);
ow->write(190); // command to read the sensor
datalow=ow->read(); // reading bytes 1 and 2 only, the actual temperature value
datahigh=ow->read();
delete(ow);
unsigned int raw = (datahigh << 8) | datalow; // shifting bits up to form a 12 bit value
celsius = int(((float)raw / 16.0)*10);
}

Serial.println (celsius/10); // result is in Celsius with 0.1 degree accuracy

---

Reading switch status:

byte PIOdata;
byte k; // switch 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); // address byte is always less than 15
addr[5]=0;
addr[6]=0;
addr[7]=OneWire::crc8(addr,7);
ow->select(addr); // select switch
ow->write(245); // PIO read command
PIOdata=ow->read();
if (PIOdata==30) // switch A is closed*
{
ToggleLamp(); // relay state inverted and short delay added to prevent flapping
}
}

* if both contacts are open the result is 15

bit 0 DS2413 pin 6 (PIO A) input level
bit 1 DS2413 pin 6 (PIO A) inverted (!) output level (controls output transistor) , 0 = transistor pulls pin to ground
bit 2 DS2413 pin 4 (PIO B) input level
bit 3 DS2413 pin 4 (PIO B) inverted output level
bit 4-7 inverted values of bits 0-3

as a result 15 (0000 1111) means both input levels are HIGH (bits 0 and 2) due to the 22 kohm pullup resistors and both output transistors are open (bits 1 and 3) they allow the output to "float"

when switch A is closed pin 6 is shorted to ground resulting bit 0 to change to LOW:
input value will change from 15 (0000 1111) to 30( 0001 1110)

when switch B is closed (while switch A is released) the input is 75 (0100 1011)

---

Inverting Relay state:

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); // select relay,
ow->write(245); // PIO read command
PIOdata=dv.read();

if (PIOdata==15) // Transistors are open (=relay is open)
{
ow->reset();
ow->select(addr);
ow->write(90); // PIO write command
ow->write(254); // turn on transistor A*
ow->write(1); // inverted byte must be written as well for verification (!)
Serial.print("R");
Serial.print (m);
Serial.println (":1");
}

if (PIOdata==120) // relay is closed
{
ow->reset();
ow->select(addr);
ow->write(90); // PIO write command
ow->write(255); // turn off transistor A*
ow->write(0); // inverted byte must be written as well for verification (!)
Serial.print("R");
Serial.print (m);
Serial.println (":0");
}
}

* The SSR's internal LED is driven by transistor A (PIO A output) of the 1-wire switch, pin 6. When bit 0 is set to 0 (111111 10) the transistor pulls the output level to GND - activating the LED and the SSR. By setting bit 0 to 1 (111111 11) the SSR is deactivated.
Output B is not in use in my circuit, however of course it could activated similarly with bit 1 (111111 01). The remaing six bits must be high all the time.

Since both switches and relay use DS2413 chips they are differentiated when a new device is added. A routine activates transistor A for a short period. In case the remote device is a relay logical LOW will be detected on the PIO B input since the two pins are connected.

In progress:

*Test of PIR sensors and addition of adjustable delay function in the software

*Developing pressure sensor

*Modifying the OneWire library to allow parallel operation on all buses (currently all 1-wire commands are sequential)

*Testing 1-wire Overdrive mode

*Web based remote management (PHP+UDP)

> Further development is planned in 2018 since there seems to be an interest in this project.

Share

Recommendations

  • Epilog Challenge 9

    Epilog Challenge 9
  • Sew Warm Contest 2018

    Sew Warm Contest 2018
  • Gluten Free Challenge

    Gluten Free Challenge
user

We have a be nice policy.
Please be positive and constructive.

Tips

Questions

6 Comments

Woowww, I'm very interested of this 1 wire arduino project !!!

Hope you can update it soon !!!

Hi! I'm very surprise to find this brilliant idea here!

Did you implement this project and can you share the experience?

Thank you

Hi, nice project! Onewire is very easy to implement and use, but
should'nt be used for long distances as it is one high impedance wire.
Did you use this with long distances? Do the one-wire bus pass near AC line cables? Did you experience problems? Thank you!

Hi Thx !

Maxim gives 200 meters when using normal phone cables. With the UTP cables I used it should be even more. Accordingly I experienced no problems related to distances.
Yes the 1-wire cables run in the same tubes as the 220 and 380 V power cables, no issues experienced with interference.
The only problem I found is a damaged SSR due to a failing 100W incandescent bulb. To prevent this a surge protection element is added.

I will update this project with further details in a few months.

user

How do I get the OneWire.h? Thank you