Виникла в мене ідея автоматизувати квартиру. В інтернеті є безліч готових варіантівю Дуже гарний перелік ви можете знайти за цим посиланням.
У тестовому варіанті ми зробимо вмикання вимикання світлодіода, та отримання рівня температури та вологості. У якості ядра розумної хатинки будемо використовувати OpenHAB, протокол обміну – ModBus. Повна схема буде виглядати так:
Для повторення всього, про що піде мова далі вам необхідно мати:
Програмне забезпечення
- AtmelStudio, WinAVR чи щось інше, що надає можливість компілювати с код для мікроконтролерів Atmel (я використовував WinAVR-20100110)
- OpenHAB
Апаратне забезпечення
- Будь-що з підтримкою java
- USB to RS2485 converter
- AVR програматор
- AT90S8515 (ви можете використовувати будь який інший, в мене просто є купа таких)
- кілька резисторів 4К7
- кнопка
- світлодіод
- монтажна плата
-
Встановлення та конфігурація OpenHAB
Для встановлення OpenHAB його треба скачати та розпакувати. На цьому інсталяція завершена та можна починати його конфігурувати.
Конфігурування розширення Modbus
Для цього треба створити файл conf/services/modbus.cfg
#LEDS on Device 2 modbus:serial.slave5.connection=COM3:115200:8:none:1:rtu:35:2000:none:none modbus:serial.slave5.id=2 modbus:serial.slave5.start=0 modbus:serial.slave5.length=8 modbus:serial.slave5.type=coil #BUTTONS on Device 2 modbus:serial.slave6.connection=COM3:115200:8:none:1:rtu:35:2000:none:none modbus:serial.slave6.id=2 modbus:serial.slave6.start=0 modbus:serial.slave6.length=8 modbus:serial.slave6.type=discrete
У моєму випадку AVR було підключено до порта COM3
Створюємо items.
Для цього треба створити файл conf/items/modbus.items
Group ROOM1
Contact ROOM1_SW_LIGHT_BTN_2 "Light Button 2" (ROOM1) {modbus="slave6:1"}
Switch ROOM1_SW_LIGHT_LAMP_2 "Світло 2" <light> (ROOM1) {modbus="slave5:2"}
Створюємо sitemap
sitemap test label="Мій дім" {
Frame label="Комната 1" {
Switch item=ROOM1_SW_LIGHT_LAMP_2
}
}
Після цього треба сконфігорувати Classic-UI
Створюємо правило щоб обробляти команди від кнопки
rule "Light room 2 ON"
when
Item ROOM1_SW_LIGHT_BTN_2 changed from OPEN to CLOSED
then
if (ROOM2_SW_LIGHT_LAMP_2.state!=ON)
ROOM1_SW_LIGHT_LAMP_2.sendCommand(ON)
else
ROOM2_SW_LIGHT_LAMP_2.sendCommand(OFF)
end
2. Створюємо апаратну частину.
Принципова схема
Повинно вийти щось таке:
3. Компілюємо програму
#define clientAddress 0x02
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "yaMBSiavr.h"
#define LIGHLCD PC7
#define LIGHLCDDDR DDRC
#define LIGHLCDPORT PORTC
volatile uint8_t instate = 0;
volatile uint8_t outstate = 0;
volatile uint16_t inputRegisters[4];
volatile uint16_t holdingRegisters[4];
void timer0100us_start(void) {
TCCR0|=(1<<CS01); //prescaler 8
TIMSK|=(1<<TOIE0);
}
/*
* Modify the following 3 functions to implement your own pin configurations...
*/
void SetOuts(volatile uint8_t in) {
PORTD|= (((in & (1<<3))<<4) | ((in & (1<<4))<<1) | ((in & (1<<5))<<1));
PORTB|= (((in & (1<<0))<<2) | ((in & (1<<1))) | ((in & (1<<2))>>2));
in=~in;
PORTB&= ~(((in & (1<<0))<<2) | ((in & (1<<1))) | ((in & (1<<2))>>2));
PORTD&= ~(((in & (1<<3))<<4) | ((in & (1<<4))<<1) | ((in & (1<<5))<<1));
}
uint8_t ReadIns(void) {
uint8_t ins=0x00;
ins|=(PINC&((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
ins|=(((PIND&(1<<4))<<2)|((PIND&(1<<3))<<4));
return ins;
}
void io_conf(void) {
/*
Outputs: PB2,PB1,PB0,PD7,PD5,PD6
Inputs: PC0, PC1, PC2, PC3, PC4, PC6, PD4, PD3
*/
DDRD=0x00;
DDRB=0x00;
DDRC=0x00;
PORTD=0x00;
PORTB=0x00;
PORTC=0x00;
PORTD|=(1<<0);
DDRD |= (1<<2)|(1<<5)|(1<<6)|(1<<7);
DDRB |= (1<<0)|(1<<1)|(1<<2)|(1<<3);
// set ports as output
LIGHLCDDDR |= (1<<LIGHLCD);
}
ISR(SIG_OVERFLOW0) { //this ISR is called 9765.625 times per second
modbusTickTimer();
}
void modbusGet(void) {
if (modbusGetBusState() & (1<<ReceiveCompleted))
{
LIGHLCDPORT |= _BV(LIGHLCD);
//PUMPPORT &= ~_BV(PUMP);
switch(rxbuffer[1]) {
case fcReadCoilStatus: {
modbusExchangeBits(&outstate,0,8);
}
break;
case fcReadInputStatus: {
volatile uint8_t inps = ReadIns();
modbusExchangeBits(&inps,0,8);
}
break;
case fcReadHoldingRegisters: {
modbusExchangeRegisters(holdingRegisters,0,4);
}
break;
case fcReadInputRegisters: {
modbusExchangeRegisters(inputRegisters,0,4);
}
break;
case fcForceSingleCoil: {
modbusExchangeBits(&outstate,0,8);
SetOuts(outstate);
}
break;
case fcPresetSingleRegister: {
modbusExchangeRegisters(holdingRegisters,0,4);
}
break;
case fcForceMultipleCoils: {
modbusExchangeBits(&outstate,0,8);
SetOuts(outstate);
}
break;
case fcPresetMultipleRegisters: {
modbusExchangeRegisters(holdingRegisters,0,4);
}
break;
default: {
modbusSendException(ecIllegalFunction);
}
break;
}
}
}
int main(void)
{
io_conf();
sei();
modbusSetAddress(clientAddress);
modbusInit();
wdt_enable(7);
timer0100us_start();
holdingRegisters[0] = 0x0A;
holdingRegisters[1] = 0x0B;
holdingRegisters[2] = 0x0C;
holdingRegisters[3] = 0x0D;
while(1)
{
wdt_reset();
modbusGet();
}
}
Для компілювання вам буде потрібна бібліотека ModBus.
Після компіляції прошиваємо мікроконтролер, та запускаємо усе. Повинно вийти щось таке:
Якщо щось не працює вам може допомогти
QModBus – додаток для тестування роботи шини. Дозволяє надсилати команди пристроям та дивитись відповіді.
Після міграції всього на Raspberry Pi можна отримати таку конфігурацію:
2 пристроя на шині ModBus, OpenHAB на Rasbrerry Pi.
Один має датчик температури та вологості, лампу та кнопку. Інший має тільки кнопку та лампу.




