Когда у меня появилась ардуинка, я хотел приспособить её для какого-нибудь действительно полезного дела. В домашних условиях такая задача всё-таки нашлась :)
Вот представь себе: ты сидишь за столом и слушаешь громкую музыку в наушниках. Может быть, делаешь какие-то другие дела попутно по работе или учёбе. А тут подходит к тебе кто-то из домашних и хочет что-то сказать. Во-первых, этот внешний раздражитель сначала надо заметить (ты ведь под кайфом от громкой музыки, да?). Во-вторых, надо переключиться на плеер и остановить воспроизведение.
Цель: сделать установку на ардуине, которая будет ставить плеер на паузу, когда подходят к твоему "рабочему месту".
Приобрёл на али инфракрасный датчик движения за 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