В статье описывается устройство для голосового управления розетками UNIEL на базе контроллера Arduino, трансмиттера 433 МГц и модуля распознавания голоса Voice Recognition Module V2 фирмы elechouse (сайт — http://www.elechouse.com).
Розетки UNIEL
Непосредственно устанавливаются в любую розетку и к ним уже подключается электроприбор, включением и выключением которого можно управлять с дистанционного пульта. Радиус действия на открытой местности до 25м, частота приемо-передачи команд 433.9 Мгц. В ассортименте есть разные для нагрузок 300Вт, 1000Вт, 3600 Вт. Весь ассортимент можно посмотреть на странице официального сайта http://www.uniel.ru/ru/catalog/1235.
В пульте устанавливается код группы. В каждой розетке код группы = код группы пульта и код розетки
Радиомодули
Наша задача — заменить пульт для управления розетками UNIEL. Нужны радиомодули, работающие на частоте 433 МГц. Я приобретал FS1000A
В комплекте ресивер и трансмиттер. Цена на ebay меньше 100 руб.
Для Arduino имеются библиотеки для работы с разными управляемыми по 433/315 МГц исполнительными устройствами. Я использовал такую:
rc-switch — Arduino library to operate low cost 315 MHz / 433 MHz remote control devices — http://code.google.com/p/rc-switch/
Скачиваем, распаковываем в папку libraries
Для начала подключим приемник
Arduino—— модуль
+5V ———-VCC
GND ———-GND
DATA (любой)————2
запустим пример из библиотеки RCswitch пример ReceiveDemo_Advanced
Нажимаем на пульт и смотрим что выдает скетч в последовательный порт
Запомним параметры 24Bit, PulseLength — 309 microseconds, Protocol 1
Они нам понадобятся при написании скетча. Коды запоминать НЕОБЯЗАТЕЛЬНО!!! Для отправки кодов достаточно знать код группы и код устройства!!!
Подключаем к Arduino проверки работы розеток
Arduino—— модуль
+5V ———-VCC
GND ———-GND
DATA ————10
Пишем скетч следующего содержания
include "RCSwitch.h" RCSwitch mySwitch = RCSwitch(); void setup() { Serial.begin(9600); mySwitch.enableTransmit(10); mySwitch.setPulseLength(309); mySwitch.setProtocol(1); // mySwitch.setRepeatTransmit(15); } void loop() { // включение // группа 11000 код розетки A mySwitch.switchOn("11000", "10000"); Serial.print("A - on"); delay(5000); // группа 11000 код розетки B mySwitch.switchOn("11000", "01000"); Serial.print("B - on"); delay(5000); // группа 11000 код розетки B mySwitch.switchOn("11000", "00100"); Serial.print("C - on"); delay(5000); // выключение mySwitch.switchOff("11000", "10000"); Serial.print("A - off"); delay(5000); mySwitch.switchOff("11000", "01000"); Serial.print("В - off"); delay(5000); mySwitch.switchOff("11000", "00100"); Serial.print("C - off"); delay(5000); }
Запускаем, и смотрим как розетки по кругу включаются, а затем выключаются.
Из контроллера при желание можно управлять 32×32 розетками
Модуль распознавания голоса Voice Recognition Module V2
Модуль распознавания голоса Voice Recognition Module V2 был куплен на ebay по очень приемлемой цене. При заказе не смотрел даташит и напрасно. Модуль не совсем оправдал ожидания:
1) Объявленная работа с 15 заранее записанными голосовыми командами одновременно невозможна (модуль распознает только по 5 команд каждого блока (блоков 3)).Можно подгрузить только 1 блок, затем другой и т.д. Поэтому было решено использовать цепочки слов (2-3) с паузами, необходимыми для загрузки следующего блока, например
Кафе — лампа — выключить
Фонтан — включить
2) Модуль не реагирует на голос другого человека, для двух человек придется дублировать команды
Сначала расскажу как работать с модулем, а потом как была решена задача
Вид модуля
Для обучения модуля необходимо посылать модулю по последовательному порту команды и произносить фразы. Скачиваем на компьютер (Windows) рекомендуемую производителем программe работы с com-портом (AccessPort — страница загрузки), подключаем модуль к Arduino
Arduino—— модуль
+5V ———-VCC
GND ———-GND
TX ————3
RX ————2
Arduino подключаем к компьютеру. В Arduino загружаем скетч
#include "SoftwareSerial.h" SoftwareSerial mySerial(2, 3); // RX, TX void setup() { Serial.begin(9600); mySerial.begin(9600); } void loop() { if (mySerial.available()) Serial.write(mySerial.read()); if (Serial.available()) mySerial.write(Serial.read()); }
В программе AccessPort выставляем следующие настройки
Теперь все команды и ответы идут от компа к модулю
Смотрим даташит — прикреплен в конце
и посылаем команды
AABB — информация о модуле
V2.0
By ELECHOUSE
www.elechouse.com
Далее — обучение первого блока — AA11
После команды START в окне терминала произносим в микрофон ПЕРВУЮ фразу, появляется надпись Again, ждем, молчим, снова появляется команда START. Второй раз произносим в микрофон ПЕРВУЮ фразу для подтверждения. В случае удачной записи появляется надпись Finish one, говорящая о том , что первая команда успешно записана. Надпись Different говорит о том, что вторая команда звучала не так, как первая и модуль ее не распознал. Надпись Too loud говорит о том, что вы слишком громко говорите в микрофон (> 1300 мс).
Аналогично записываем 4 оставшихся фразы. Надпись Group1 finished ! говорит о том, что первый блок успешно записан.
Для проверки распознавания вызываем блок 1 — командой AA21 и произносим фразы в микрофон. При распознавании выводится подтверждение в терминал
Затем обучаем блоки 2 и 3 посылая команды AA12, AA13 соответственно. Для вызова из памяти блоков 2 и 3 команда в терминал AA22 и AA23 соответственно.
Еще один момент — если мы хотим получать ответ от голосового модуля в кратком виде (не «Result:15» а 15) необходимо отправить модулю команду AA37
В блоки заносим следующие команды (участвуют 2 человека) для посиделок на кухне — чайник(электрический) + освещение (огни RGB, лампа возле кухонного стола, ночник)
блок 1 | блок 2 | блок 3 | |
1 | «Кафе» (1 голос) | «Огни» (1 голос) | «Включить» (1 голос) |
2 | «Фонтан» (1 голос) | «Лента» (1 голос) | «Выключить» (1 голос) |
3 | «Тест» (1 голос) | «Ночник» (1 голос) | «Огни» (2 голос) |
4 | «Кафе» (2 голос) | «Включить» (2 голос) | «Лента» (2 голос) |
5 | «Фонтан» (2 голос) | «Выключить» (2 голос) | «Ночник» (2 голос) |
В соответствии с обученным командам и будем строим цепочки в программе
Вот примеры правильных цепочек
«Кафе» (1 голос) — «Ночник» (1 голос) — «Выключить» (1 голос)
«Фонтан» (2 голос) — «Включить» (2 голос)
«Кафе» (2 голос) — «Огни» (2 голос) — «Включить» (2 голос)
и т.д.
Для наглядности добавим индикацию 3 светодиода к пинам 7,8,9
(красный — загружен 1 блок
желтый — загружен 2 блок
зеленый — загружен 3 блок
горят 3 светодиода (1 сек) — комбинация слов верная)
Вот схема устройства
А устройство выглядит так (будет позже украшено искусственными цветами)
И скетч для Arduino. К сказанному выше еще добавлю, что если
после загрузки второго или третьего блоков в течении FRAZA_TIME=2000 мс нет опознанного слова —
подгружается банк 1.
И весь скетч
#include "RCSwitch.h" #include "SoftwareSerial.h" SoftwareSerial mySerial(2, 3); // RX, TX RCSwitch mySwitch = RCSwitch(); byte com = 0; char* kod_group="11000"; unsigned long FRAZA_TIME=2000; unsigned long millis1=0; int fraza_poz=1; int var1; int offset[4]={0,1,10,100}; unsigned int kod=0; int id_do=0; // фразы // 1 банк // 11,12,13,14,15 // кафе(1),фонтан(1),тест(1),кафе(2),фонтан(2) // 21,22,23,24,25 // огни(1),лента(1),ночник(1),включить(2),выключить(2) // 31,32,33,34,35 // включить(1),выключить(1),огни(2),лента(2),ночник(2), // все возможные комбинации // 1,2,3 - выбор банка // 4 - ok end unsigned int var_ok[29][4]={ // 1 голос {1,2,0,0},{2,2,0,0}, {11,3,0,0},{21,3,0,0},{31,3,0,0},{42,4,1,1},{52,4,2,2}, {111,4,3,1},{121,4,4,1},{131,4,5,1},{211,4,6,2},{221,4,7,2},{231,4,8,2}, // тест {3,2,0,0},{43,3,0,0},{243,4,9,3}, // 2 голос {4,3,0,0},{5,3,0,0}, {304,2,0,0},{404,2,0,0},{504,2,0,0},{105,4,10,1},{205,4,11,2}, {344,4,12,1},{354,4,13,1},{444,4,14,1},{454,4,15,2},{544,4,16,2},{554,4,17,2} }; // коды отправки по RF char kodModule[][6] = {"00000", "00010","00010", // чайник вкл-выкл 1 голос "10000","01000","00100","10000","01000","00100", // огни,лампа,ночник вкл-выкл 1 голос "00000", // тест "00010","00010", // чайник вкл-выкл 2 голос "10000","01000","00100","10000","01000","00100" // огни,лампа,ночник вкл-выкл 2 голос }; void setup() { Serial.begin(9600); mySerial.begin(9600); pinMode(13, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(9,HIGH); // радиомодуль mySwitch.enableTransmit(10); mySwitch.setPulseLength(309); mySwitch.setProtocol(1); // mySwitch.setRepeatTransmit(15); // Voice Recognition Module V2 delay(2000); mySerial.write(0xAA);//избавляемся от текста mySerial.write(0x37);// и оставляем байты delay(1000); mySerial.write(0xAA); // вызываем из памяти mySerial.write(0x21);// команды 1-ой группы delay(2000); digitalWrite(7,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); Serial.println("okey"); } void loop() { var1=fraza_poz; if(get_word(fraza_poz)!=var1) { switch(fraza_poz) { case 0: Serial.print("false=");Serial.println(kod); kod=0;fraza_poz=1; break; case 4: Serial.print("ok=");Serial.println(kod); ledOn(7);ledOn(8);ledOn(9); command_UNIEL(id_do); kod=0;fraza_poz=1;id_do=0; delay(1000);ledsOff(); break; case 1: Serial.print("wait=");Serial.println(kod); kod=0; break; default: Serial.print("wait=");Serial.println(kod); break; } new_bank(fraza_poz); } if(millis()-millis1>FRAZA_TIME && fraza_poz>1) {kod=0;fraza_poz=1;new_bank(fraza_poz);} digitalWrite(13, LOW); //Serial.print("fraza_poz====");Serial.println(fraza_poz); } // получить id слова из банка int get_word(int bank) { while(mySerial.available()) { com = mySerial.read();// читаем входящие байты и присваиваем значение переменной com digitalWrite(13, HIGH); Serial.print("word_id=");Serial.println(com,HEX); if(com>0x10*bank && com<0x16*bank) { kod=kod+offset[bank]*(int(com & 7)); fraza_poz=0; for(int i=0;i<29;i++) {if(kod==var_ok[i][0]) {fraza_poz=var_ok[i][1]; if(fraza_poz==4) id_do=i+1; } } Serial.print("fraza_poz=");Serial.println(fraza_poz); } } return fraza_poz; } // выбор нового банка Voice Recognition Module V2 int new_bank(int bank) { Serial.print("NEW=");Serial.println(fraza_poz); mySerial.write(0xAA); // вызываем из памяти byte bank1=0x20+bank; mySerial.write(0x20+bank);// команды 1-ой группы delay(1000); mySerial.flush(); ledsOff(); ledOn(6+bank); millis1=millis(); } // отправка команды розетке UNIEL по rf void command_UNIEL(int id) { Serial.print("id=");Serial.print(id-1); Serial.print(" id[3]=");Serial.println(var_ok[id-1][3]); Serial.print(" kod=");Serial.println(var_ok[id-1][2]); if(var_ok[id-1][3]==1) mySwitch.switchOn(kod_group, kodModule[var_ok[id-1][2]]); else if(var_ok[id-1][3]==2) mySwitch.switchOff(kod_group, kodModule[var_ok[id-1][2]]); else if(var_ok[id-1][3]==3) { for(int i=3;i<6;i++) {mySwitch.switchOn(kod_group, kodModule[3]); delay(1000);} for(int i=3;i<6;i++) {mySwitch.switchOff(kod_group, kodModule[3]); delay(1000);} } else ; } // включить светодиод void ledOn(int pin) { digitalWrite(pin,HIGH); } // выключить светодиоды void ledsOff() { digitalWrite(7,LOW); digitalWrite(8,LOW); digitalWrite(9,LOW); }
Список радиоэлементов
Обозначение | Тип | Номинал | Количество | Примечание | Магазин | Мой блокнот |
---|---|---|---|---|---|---|
Arduino | Контроллер | Arduino mini pro | 1 | |||
Voice Module | Контроллер | Voice Recognition Module V2 | 1 | |||
R1-R3 | Резистор | 220 Ом | 3 | |||
HL1 | Светодиод | красный | 1 | |||
HL2 | Светодиод | желтый | 1 | |||
HL3 | Светодиод | зеленый | 1 | |||
RF | Трансивер 433 Мгц | FS1000A | 1 | |||
Розетка радиоуправляемая | UNIEL | 4 | ||||