Предисловие
В детстве, смотря многие американские фильмы, был в восторге от того, как актеры выключали свет в помещении «хлопнув в ладоши», всегда хотелось такую же штуку у себя дома. В последние годы ПК стал неотъемлемой частью моей жизни: приходя домой и разувшись, первым делом идешь включать своего «железного коня» и ждать его загрузки. Конечно в последние годы с появлением SSD это ожидание свелось к минимуму, но тем не менее вместе с самим подходом к компьютеру все же какое-то время теряется. Да и собственно зачем вообще идти в комнату, бить с ноги по кнопке, если можно сделать какой-то дистанционный способ включения «моей прелести».
Собственно так со временем и слились две «мечты»: включать ПК по хлопку. На данный момент я учусь в университете и как раз пришло время делать курсовой по схемотехнике, причем преподаватель заявил о том, что можно сделать его в железе, а не на бумаге, что на мой взгляд интереснее. Таким образом подвернулся шанс «убить сразу двух зайцев» — реализовать старую идею и сдать курсовой проект. Первоначальной идеей было сделать некое устройство, которое можно будет разместить на корпусе, запитать его от блока питания, подключить через реле к кнопке и по хлопку замыкать цепь. Как итог решили немного отойти от этой идеи немного расширив ее: система теперь будет состоять из двух блоков, соединенных посредством Bluetooth. Один блок будет улавливать хлопок и посылать специальный сигнал на второй блок, второй же блок будет принимать этот сигнал и замыкать реле.
С чего начать
Первым делом надо было решить на каком железе реализовать мою затею. Выбор пал на платформу Arduino. Почему именно Arduino? В этой статье я не буду перечислять технические характеристики данной платформы как минимум потому что речь идет не об этом. Собственно ответ на этот вопрос кроется в трёх причинах:
- Дешевизна — в Китае микроконтроллеры с этой платформой можно найти за 5$, а то и меньше
- Простота использования — в интернете множество гайдов по данной платформе и разобраться в них не составляет труда
- Огромное количество всевозможных датчиков
Последнее кстати важно для тех, кто хочет сделать еще что-нибудь со своим микроконтроллером. Ведь на следующий день вы можете прикрутить к плате еще что-нибудь, перепрошить ее и она будет выполнять совершенно другие задачи. Вообщем вернемся к нашей теме.
Собственно составим список того, что нам для этого понадобится:
- 2x Arduino Uno R3 — по одной на каждый блок
- 2x Bluetooth HC-05 — Опять же по одной на каждый блок, и главное именно HC-05, потому что только они поддерживают режимы Master и Slave
- Микрофон — простой электретный микрофон, стоит он вообще копейки
- Реле
- 2x светодиода — красный и зеленый
- Всякие проводки, резисторы и т.п.
- И конечно же паяльник
Начинаем
Рассмотрим наш микроконтроллер
Как видим он имеет аналоговые пины, подписанные с буквой А (например А0), входы для внешнего питания, выходы для питания +5В и +3.3В, цифровые пины, выходы на землю и др.
Подключить ее к компьютеру можно по USB, благо в комплекте имеется кабель. А даже если у вас и не будет, то купить его можно в любом магазине электроники. Для работы непосредственно c Arduino имеется их собственная очень удобная IDE, которую можно взять с официального сайта.
Для того, чтобы далее работать с Ардуино, надо все же хоть чуть-чуть про нее рассказать
Микроконтроллеры для Arduino отличаются наличием предварительно прошитого в них загрузчика (bootloader). С помощью этого загрузчика пользователь загружает свою программу в микроконтроллер без использования традиционных отдельных аппаратных программаторов. Загрузчик соединяется с компьютером через интерфейс USB (если он есть на плате) или с помощью отдельного переходника UART-USB. Поддержка загрузчика встроена в Arduino IDE и выполняется в один щелчок мыши.
На случай затирания загрузчика или покупки микроконтроллера без загрузчика разработчики предоставляют возможность прошить загрузчик в микроконтроллер самостоятельно. Для этого в Arduino IDE встроена поддержка нескольких популярных дешевых программаторов, а большинство плат Arduino имеет штыревой разъем для внутрисхемного программирования (ICSP для AVR, JTAG для ARM).
Язык программирования Ардуино является стандартным C++ (используется компилятор AVR-GCC) с некоторыми особенностями.
Программы, написанные программистом Ардуино называются наброски (или иногда скетчи — варваризм от англ. sketch) и сохраняются в файлах с расширением ino. Эти файлы перед компиляцией обрабатываются препроцессором Ардуино. Также существует возможность создавать и подключать к проекту стандартные файлы C++.
Итак, скачав Arduino IDE с официального сайта и установив, открываем его и видим это:
Наш скетч разделен как бы на 2 блока — setup() и loop(). В первый блок пишется то, что должно быть изначально проинициализировано при включении контроллера в сеть. Во второй — собственно сам исполняемый код, который будет выполняться постоянно. Собственно все это следует и из названий данных блоков.
Первый блок
Первым делом надо было собрать и подключить микрофон. По сути электретный микрофон, который мы купили, является своего рода конденсатором с двумя ножками:
Ножка с характерными тремя полосочками, как на изображении выше, — это «минус» микрофона, соответственно вторая ножка — «плюс», главное не перепутать, а иначе микрофон не будет работать. Собственно хорошенько погуглив, выяснилось, что во-первых микрофон так просто не подключишь, а во-вторых сигнал будет очень слабым, то есть скорее всего понадобится операционный усилитель. На сайте продавца, где покупался микрофон, была вот такая схема:
Без усилителей, просто RC-цепь, подумал была не была, соберу и посмотрю, работает или нет. Благо дома валялись нужные резисторы и конденсатор. Также для надежности соединения, чтобы это не болталось на проводах в воздухе, возьмем текстолит, который также продается в любом магазине радиодеталей. Получилось что-то вроде этого:
Может быть не очень аккуратно, но главное чтобы работало, остается проверить. У нашего микрофона теперь 3 ноги: +5В, GND(земля) и аналоговый выход. Подключим эти ноги соответственно на 5В, GND и вход A0 контроллера. Иии после множества проб и ошибок все получилось! Микрофон действительно работает. АЦП Arduino выдает значения от 0 до 1024. Осталось подключить два светодиода для хоть какого-то визуального взаимодействия с системой. Подключать светодиод к питанию напрямую светодиод нельзя, иначе спалим его. Чтобы этого избежать вешаем на "+" светодиода резистор 220 ОМ.Обычно короткая ножка это минус, а длинная — плюс. Итак "-" светодиода подсоединяем к выходу GND на плате, а "+" на цифровой выход. Так как у нас 2 светодиода, то землю для них сделаем общую, красный подключим к 13 пину, а зеленый к 12ому. При регистрации хоть какого-то звука будет загораться красный светодиод. Если же сначала регистрируем звук, затем в течение некоторого времени тишину, а потом снова звук — то зажигаем зеленый светодиод. На деле все просто. И на практике оказалось тоже.Собственно скетч получился таким:
#define MIC A0 //Аналоговый порт, куда подключен микрофон
int ClapMargin = 9; //порог хлопка (определяется экспериментально)
int mic_prev = 0;
int SilenceLen=1500; //время тишины
int NextClapLen = 2500; //время, в течение которого ждем след. хлопок
int SkipLen = 800; //время защитной паузы
void setup()
{
analogReference(INTERNAL);//снижаем опорное опорное напряжение до 1.1В для большей чувствительности микрофона
Serial.begin(9600);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
int ReadNext() {
int result;
int d;
d = analogRead(MIC); //читаем
result = abs(mic_prev-d); //считаем модуль разницы
mic_prev = d; //сохраняем текущее значение
return result; //возвращаем результат
}
int WaitForClap(int WaitLen)
{
int d, i;
i = 0; //счетчик циклов
do {
d = ReadNext(); //читаем вход
i++; //увеличиваем счетчик
if (d > ClapMargin) { //если есть хлопок
Serial.println(d);
return d; //возвращаем силу хлопка
}
if ( (WaitLen != -1) && (i >= WaitLen) ) { //если счетчик досчитал до WaitLen и WaitLen не равен -1
return 0; //возвращаем 0
}
} while (1);
}
//ф-ия просто ждет SkipLen циклов
void Skip(int SkipLen) {
int i;
for (i=0; i<SkipLen; i++) {
ReadNext();
}
}
void loop()
{
int d1, d2;
if(WaitForClap(-1)> ClapMargin)//ждем хлопок
{
digitalWrite(12, HIGH);//зажигаем красный светодиод
Serial.println("raz");
Skip(SkipLen);
d1 = WaitForClap(SilenceLen); //слушаем тишину
Serial.println(d1);
if (d1 == 0)
{
digitalWrite(12, HIGH);
Skip(500);
d2 = WaitForClap(NextClapLen); //ждем 2го хлопка
if (d2 > ClapMargin)
{
digitalWrite(12, LOW);//погасим красный светодиод
digitalWrite(13, HIGH);//зажжем зеленый светодиод
delay(1000);
}
}
}
digitalWrite(12, LOW);//гасим оба светодиода
digitalWrite(13, LOW);
Skip(SkipLen);
}
Итак отлавливать нужный сигнал мы научились, осталось при наличии хлопка как-то сообщить об этом второму блоку. Для этого нам нужны Bluetooth-модули. Я взял Bluetooth hc-05 shield, который выглядит следующим образом:
Просто присоединяем его к нашей Uno пин к пину, таким образом подключаем сам модуль и дублируем выходы нашей платы. Должно получится примерно так(Shieldы могут быть в несколько разных вариациях, суть та же):
Так же на Bluetooth Shield можете увидеть рычажок, имеющий два положения: H и L. H-режим Ведущего(Master), L-режим Ведомого(Slave). В данном случае выставим рычажок на Master. Итак, подключив модуль блютуз, можем сверху подсоединить к тем же пинам наши светодиоды и микрофон. Вообщем с этим блоком закончили, переходим к следующему.
Второй блок
Во втором блоке нам понадобится электромагнитное реле, двойная розетка внешней установки, провод для подключения к электрической сети 220 В и еще один Bluetooth Shield HC-05.
Shield подключаем к плате точно таким же образом, единственное отличие будет в том, что рычажок надо выставить на L — режим SLave.
Одна розетка будет постоянно под напряжением для питания блока, вторая будет замкнута на реле, таким образом можно будет, то подавать на нее напряжение электрической сети, то снимать.
Итак подключим реле. Принцип действия его прост и заключается в следующем: 2 из ножек реле заведены на катушку индуктивности, подавая на нее напряжение создается электромагнитное поле, которое притягивает так называемый якорь внутри реле, тем самым замыкая цепь. Убрав напряжение с катушки якорь возвращается в свое первоначальное состояние, размыкая цепь. Таким образом реле — своего рода ключ.
Итак нам нужно реле, которое при подаче на катушку 5В, будет замыкать нам цепь. При этом нужна выбрать такое реле, которое сможет пропускать токи, необходимые для включения ПК. Учитывая, что большинство современных ПК потребляют от 450 Вт до 1000 Вт, нам с лихвой хватит реле пропускающее через себя ток силой в 6 Ампер. В ближайшем магазине радиоэлектроники был приобретен этот китаец tianbo hjr-3ff-s-z:
Как видим у него имеется 5 ног, 2 из которых заведены на катушку, осталось только узнать какие. Для этого гуглим и находим вот такую схему:
Подключим 2ую ногу на GND платы, а 5ую на 13 цифровой выход. Саму розетку подключим к 1ой и 3ей ноге электромагнитного реле, чтобы первоначальное состояние розетки было выключенным. Блок готов, осталось только загрузить скетч. Код для данного блока:
#include <SoftwareSerial.h>//библиотеки для работы с Bluetooth
#include <Wire.h>
#define rxPin 2
#define txPin 3
SoftwareSerial btSerial(rxPin, txPin);
void setup() {
// put your setup code here, to run once:
//Инициализация Bluetooth
Serial.begin(9600);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
btSerial.begin(38400);
pinMode(13, OUTPUT);//выставляем 13 цифровой пин на выход
}
void loop() {
// put your main code here, to run repeatedly:
if(btSerial.available())
{
char c=(char)btSerial.read();
Serial.println(c);
digitalWrite(13, !digitalRead(13));//переключаем реле, подавая то высокий сигнал, то низкий на 13 выход
}
}
Так же модернизируем код для первого блока, добавив сопряжение блютузов между собой:
#include <SoftwareSerial.h>
#include <Wire.h>
#define MIC A0 //Аналоговый порт, куда подключен микрофон
int ClapMargin = 9; //порог хлопка (определяется экспериментально)
int mic_prev = 0;
int SilenceLen=1500; //время тишины
int NextClapLen = 2500; //время, в течение которого ждем след. хлопок
int SkipLen = 800; //время защитной паузы
#define rxPin 2
#define txPin 3
SoftwareSerial btSerial(rxPin, txPin);
void setup()
{
// put your setup code here, to run once:
analogReference(INTERNAL);//снижаем опорное опорное напряжение до 1.1В для большей чувствительности микрофона
Serial.begin(9600);
pinMode(12, OUTPUT);//выставляем 12 и 13 пины на выход
pinMode(13, OUTPUT);
// define pin modes for tx, rx pins:
//Инициализация Bluetooth и подсоединение его к другому bluetooth модулю
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
btSerial.begin(38400);
Serial.println("Serial started");
digitalWrite(12, HIGH);//зажигаем красный светодиод
btSerial.println("AT");
while (!btSerial.available());
while (btSerial.available() > 0)
char c = btSerial.read();
btSerial.println("AT+INIT");
while (!btSerial.available());
while (btSerial.available() > 0)
char c = btSerial.read();
btSerial.println("AT+INQ");
while (!btSerial.available());
while (btSerial.available() > 0)
char c = btSerial.read();
btSerial.println("AT+LINK=2014,5,191146");//2014,5,191146 - имя второго модуля
while (!btSerial.available());
while (btSerial.available() > 0)
char c = btSerial.read();
digitalWrite(12, LOW);//
}
int ReadNext() {
int result;
int d;
d = analogRead(MIC); //читаем
result = abs(mic_prev-d); //считаем модуль разницы
mic_prev = d; //сохраняем текущее значение
return result; //возвращаем результат
}
int WaitForClap(int WaitLen)
{
int d, i;
i = 0; //счетчик циклов
do {
d = ReadNext(); //читаем вход
i++; //увеличиваем счетчик
if (d > ClapMargin) { //если есть хлопок
Serial.println(d);
return d; //возвращаем силу хлопка
}
if ( (WaitLen != -1) && (i >= WaitLen) ) { //если счетчик досчитал до WaitLen и WaitLen не равен -1
return 0; //возвращаем 0
}
} while (1);
}
//ф-ия просто ждет SkipLen циклов
void Skip(int SkipLen) {
int i;
for (i=0; i<SkipLen; i++) {
ReadNext();
}
}
void loop()
{
int d1, d2;
if(WaitForClap(-1)> ClapMargin)//ждем хлопок
{
digitalWrite(12, HIGH);
Serial.println("raz");
Skip(SkipLen);
d1 = WaitForClap(SilenceLen); //слушаем тишину
Serial.println(d1);
if (d1 == 0)
{
digitalWrite(12, HIGH);
Skip(500);
d2 = WaitForClap(NextClapLen); //ждем 2го хлопка
if (d2 > ClapMargin)
{
digitalWrite(12, LOW);//погасим красный диод
digitalWrite(13, HIGH);//зажжем зеленый диод
btSerial.print('1');//посылаем на второй блок специальный сигнал по Bluetooth
delay(1000);
}
}
}
digitalWrite(12, LOW);//гасим оба светодиода
digitalWrite(13, LOW);
Skip(SkipLen);
}
Результат
Итак блютузы подключены, микрофон работает, светодиоды работают, хлопок идентифицируется, сигнал на второй блок передается, осталось только все это аккуратно собрать в корпуса и настроить BIOS на включение по подаче питания.
Вот что получилось:
1-ый блок (питание выведено сбоку корпуса, на верху видны зеленый и красный светодиоды и микрофон).
2-ой блок (питание также выведено сбоку корпуса, сверху 2 розетки, одна постоянно запитана, чтобы питать микроконтроллер через адаптер для телефона, вторая собственно для подключения ПК).
Смотрим на результат:
Итоги
- Arduino — это круто. Дешевые микроконтроллеры, множество датчиков, много всевозможных гайдов в интернете, а также язык C++
- Такую вещь действительно можно сделать самому за вечер, главное заранее все купить
- Данное устройство можно применять не только для включения ПК, но и для включения других электроприборов, например лампы. А это большой плюс
- Данную идею можно расширить, например создав множество таких устройств, соединив их в единую сеть, и управлять ею по блютуз при помощи смартфона, ну это так, на будущее
Автор: GeorgeMoiseenko