Распознать взмахи рукой
- Войдите на сайт для отправки комментариев
Добрый день!
Прошу помочь в таком вопросе - хочу управлять устройством не прикасаясь, пусть это будет плеер - типа один раз махнуть рукой = play, 2 раза = перемотка, 3 раза=... и т.д. Кроме того по длинному приближению руки пусть включается регулировка громкости как функции расстояния до руки, т.е. подержали, а дальше ближе=тише, дальше=громче.
1.Как изящнее написать функцию, возвращающую кол-во взмахов, или 255, если это "длинное" удержание?
2. Какой датчик лучше использовать? Ультразвуковой иногда сбоит, видимо у него "луч" очень узкий, т.е. стоит руку чуть в сторону отвести, и расстояние сразу неправильно показывается. От руки видимо, плохо отражается, т.к. если водить чем-то плоским, типа книжки, расстояние мереется идеально. И вдогонку, чем можно закрыть датчик, чтобы было красиво и пропускало ультразвук?
Я на кухне жестами управляю светом, вентилятором, клапаном водяного фильтра с помощью Adjustable Infrared Sensor Switch (с Алиэкспресса), вот такого: http://www.dfrobot.com/index.php?route=product/product&product_id=114. Отслеживаю взмахи руки. Могу поделиться куском скетча. Но лучше почитайте отличную статью на Хабре, там датчик Sharp GP2Y0A21YK и куча наворотов с взмахами, удалением-приближением. Схема, скетч, все здесь: http://habrahabr.ru/post/243037/
Спасибо большое,, почитал, обдумал, много понял :)
а ваш датчик именно дистанцию определяет или как триггер работает - поднесли=замкнулось, убрали=разомкнулось? И скетч, тоже посмотреть хотелось бы, я ж не настоящий сварщик, я только очки нашел :)
Датчик работает как триггер с регулируемой чувствительностью (слово Switch какбы намекает)). В данном [простейшем] случае распознавание жестов в программе сводится к классической задаче - подсчету количества импульсов за промежуток времени. Здесь на форуме, кстати, есть немало тем, где она обсуждалась.
Итак, на словах алгоритм такой: 1-циклически опрашиваем датчик; 2-если датчик сработал, то увеличиваем значение счетчика импульсов и запускаем отсчет времени; 3-пока идет отсчет времени, считаем импульсы; 4-по окончании отсчета времени анализируем счетчик импульсов и что-то делаем.
Если импульс был один и он продолжался весь период отсчета времени, то это "длинный" жест, можем как-то на него прореагировать. На одно срабатывание датчика я не реагирую, считая его случайным (датчик стоит над кухонной мойкой, место достаточно посещаемое).
Теперь конкретика, даже с комментами )) :
#define IR_SWITCH_PIN 11 int IRSwitchCounter = 0; // счетчик срабатываний свитча unsigned long IRSwitchOldTime = 0; // начало отсчета времени boolean IRSWitchState = true; // текущее состояние свитча boolean IRSWitchStateOld = false; // предыдущее состояние свитча boolean IRSWitchLongTapState = false; // "длинный" жест unsigned long IRSwitchDelay = 1500; // период отсчета времени void setup() { pinMode(IR_SWITCH_PIN, INPUT); } void loop() { IRSWitchState = digitalRead(IR_SWITCH_PIN); IRSWitchLongTapState = !IRSWitchState; if ( IRSWitchState != IRSWitchStateOld ) // состояние свитча изменилось { if ( IRSwitchOldTime == 0 ) { IRSwitchOldTime = millis(); } // начинаем отсчет времени if ( !IRSWitchState ) { IRSwitchCounter++; } // свитч инвертированный, поэтому !IRSWitchState IRSWitchStateOld = IRSWitchState; delay(30); // debounce } if ( ( IRSwitchOldTime > 0 ) && ((millis() - IRSwitchOldTime) > IRSwitchDelay) ) // если отсчет времени происходит && период закончился { switch (IRSwitchCounter) { case 1: // был один жест if (IRSWitchLongTapState) // но нас интересует только "длинный" жест { // Start/stop fan } break; case 2: // было два жеста // Start/stop lights break; case 3: // было три жеста // Start/stop water break; default: } IRSwitchCounter = 0; IRSwitchOldTime = 0; // ноль как признак того, что отсчет времени не происходит } }