Виникла в мене ідея автоматизувати квартиру. В інтернеті є безліч готових варіантівю Дуже гарний перелік ви можете знайти за цим посиланням.
У тестовому варіанті ми зробимо вмикання вимикання світлодіода, та отримання рівня температури та вологості. У якості ядра розумної хатинки будемо використовувати 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.
Один має датчик температури та вологості, лампу та кнопку. Інший має тільки кнопку та лампу.