#  Сигнализация для меломана на Arduino
vit01 (mira, 1) → All  –  13:56:28 2017-02-18

Когда у меня появилась ардуинка, я хотел приспособить её для какого-нибудь действительно полезного дела. В домашних условиях такая задача всё-таки нашлась :)

Вот представь себе: ты сидишь за столом и слушаешь громкую музыку в наушниках. Может быть, делаешь какие-то другие дела попутно по работе или учёбе. А тут подходит к тебе кто-то из домашних и хочет что-то сказать. Во-первых, этот внешний раздражитель сначала надо заметить (ты ведь под кайфом от громкой музыки, да?). Во-вторых, надо переключиться на плеер и остановить воспроизведение.

Цель: сделать установку на ардуине, которая будет ставить плеер на паузу, когда подходят к твоему "рабочему месту".

Приобрёл на али инфракрасный датчик движения за 100 рублей.
Перемычек нормальных не было, поэтому пришлось криво припаять контакты к уже имеющимся.
Подсоединил один из контактов к цифровому порту, а другой - к подпитке 5V на плате.
Решил прицепить на ардуину ещё и лишний светодиод, который будет мигать при срабатывании датчика.

Нашёл в сети образцы скетчей для использования датчика движения, но они мне не очень понравились, и я решил взять один из них и максимально упростить:

====
#define pirPin 2 // наш датчик
#define ledPin 13 // светодиод

int wasMotion = false;

void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);

delay(2000); // не активируем цикл сразу, а чуть-чуть подождём
}

void loop() {
int pirVal = digitalRead(pirPin);

//Если обнаружили движение
if (pirVal == HIGH)
{
if (wasMotion == false) {
digitalWrite(ledPin, HIGH);
Serial.print("Motion detected\n");
wasMotion = true;
}
delay(500); // пауза для прогорания светодиода и для следующей проверки
} else if (wasMotion == true) {
wasMotion = false;
digitalWrite(ledPin, LOW);
}
}
====


После заливки скетча надо добавить вашего пользователя в группу uucp, которая позволит считывать данные из виртуального USB-COM порта ардуины без root-прав.

# usermod -a -G uucp youruser

Далее надо было написать программу, которая будет отслеживать сигнал, поступающий с девайса, и подавать сигнал плееру. Питон ради такой мелочи расчехлять не хотелось (будет память жрать), поэтому выбрал C.

====
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>

int fd;
int should_exit = 0;

static void signal_handler(int sig) {
// Обрабатываем нажатие Ctrl-C, чтобы корректно выходить

switch (sig) {
case SIGINT:
close(fd);
printf("Exiting\n");
should_exit = 1;
break;
default:
break;
}
}

void stop_player() {
// Главная вещь, ради которой всё затевалось
// Для плеера Audacious, которым пользуюсь

system("if [ \"`audtool playback-status`\" = \"playing\" ]; then audtool playback-pause; fi");
}

void main(int argc, char** argv) {
char buf[15];
int r;

signal(SIGINT, signal_handler);

// Открываем виртуальный USB COM-port девайса
fd = open("/dev/ttyUSB0", O_RDONLY | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_port: Unable to open /dev/ttyUSB0 - ");
should_exit = 1;
} else {
fcntl(fd, F_SETFL, FNDELAY);
}

while(!should_exit) {
r = read(fd, buf, 20);
if (r > 0 && strncmp(buf, "Motion detected", 15) == 0) {
puts("Works!");
stop_player();
}
sleep(1);
}
}
====


Всё, можно добавлять в автозагрузку и пользоваться!
И да, как это выглядит на фоточках:

https://ii-net.tk/ii/files/arduino-pir1.jpg
https://ii-net.tk/ii/files/arduino-pir2.jpg