Датчик стука
- Войдите на сайт для отправки комментариев
Пт, 25/03/2011 - 21:23
Здравствуйте!
Перед нами поставили задание сделать датчик стука. Есть пьезо диск и три светодиода. Если стучишь 1 раз за 3 секунды, загорается первый светодиод, если стучишь 2 раза - второй, 3 раза - третий. Помогите пожалуйста с алгоритмом, как считывать количество ударов?
Думаю, что для подсчета ударов, надо объявить три глобальные(вне loop) переменные
int knockCount = 0; //кол-во ударов
unsigned long timeFirstKnock = 0; //время первого стука
unsigned long timePast; // время с первого стука, объявляем здесь, чтобы не объявлять его много раз в цикле
Далее ты в теле loop, в каждом цикле проверяешь, значение с датчика, если оно превысило некую величину, то считаем это стуком и
{
knockCount++; //увеличиваем количество ударов на 1
// если отсчет 3 секунд не пошел, то устанавливаем время первого удара
if (timeFirstKnock==0) {timeFirstKnock = millis();}
}
А ниже мы проверяем не прошли ли 3 секунды
if (timeFirstKnock !=0) { //если уже идет отсчет
timePast = millis()-timeFirstKnock; // время с первого удара
if (timePast>3000) { //если время прошло
...... //тут ты зажигаешь светодиоды
timeFirstKnock = 0; //обнуляем т.к. прошло 3 секунды
knockCount = 0;
}
}
Как-то так.
Спасибо огромное!! Сейчас буду проверять!
Получилось так, что все происходит ооочень быстро, и когда мы стучим по пьезо к примеру один раз, то счетчик увеличивается не на 1, а , как мы подобрали, на 1000 или даже больше в соответствии с тем, с какой силой мы стукнем и какой параметр будет в программе сравниваться со значением с датчика. Мы пробовали подбирать эти величины, для двух лампочек хорошо, а вот для трех уже проблемы..( Как бы это обойти?
А если попробовать delay() в теле loop, параметр подобрать так, чтобы работало.
Если датчик после удара непрерывно передает значение в течение какого-то времени, то просто вставь цикл, который ожидает окончания удара, сразу после его обнаружения.
// если зафиксирован удар, то
{
knockCount++;
if (timeFirstKnock==0) {timeFirstKnock = millis();}
while (ПРОВЕРЯЕШЬ, ЧТО ЗНАЧЕНИЕ С ДАТЧИКА ВСЕ ЕЩЕ КАК ПРИ УДАРЕ)
{
//этот цикл вообще можно пустым оставить, нам нужно чтобы программы дальше не пошла до окончания удара
// а можно маленький delay(10); вставить
}
}
далее все тоже, что и было
Т.е. ход программы будет тормозиться после начала удара, до его окончания, она просто будет застревать в цикле
Перед нами поставили задание сделать датчик стука.
Можно полюбопытствовать, такое задание поставили где-то в учебном заведении? Просто интересно используют ли arduino в учебном процессе?
Перед нами поставили задание сделать датчик стука.
Можно полюбопытствовать, такое задание поставили где-то в учебном заведении? Просто интересно используют ли arduino в учебном процессе?
Да, у нас в университете хотят ввести экспериментальный курс по микроконтроллерам, потому что старый курс уже не соответствует реальным технологиям. И попросили инициативных студентов поковыряться с ардуино, чтобы посмотреть, как вообще, справимся мы или нет.
Все равно не работает. Посмотрите пожалуйста весь код. Может мы что-то где-то не так делаем.
int knockCount = 0; //кол-во ударов
int ledPin[3] = {9,10,11};
int piezoPin = 5;
int threshold = 120;
int sensorValue = 0;
unsigned long timeFirstKnock = 0; //время первого стука
unsigned long timePast; // время с первого стука, объявляем здесь, чтобы не объявлять его много раз в цикле
void setup() {
for(int i = 0; i<=2; i++){ pinMode(ledPin[i], OUTPUT);}
digitalWrite(ledPin[0], HIGH); digitalWrite(ledPin[1], HIGH); digitalWrite(ledPin[2], HIGH);
delay(300);
digitalWrite(ledPin[0], LOW); digitalWrite(ledPin[1], LOW); digitalWrite(ledPin[2], LOW) ;
}
//Далее в теле loop в каждом цикле проверяем значение с датчика, если оно превысило некую величину, то считаем это стуком и
void loop()
{
sensorValue = analogRead(piezoPin); // Читаем величину с датчика
if (sensorValue >=threshold)
{
knockCount++; //увеличиваем количество ударов на 1
// если отсчет 3 секунд не пошел, то устанавливаем время первого удара
if (timeFirstKnock==0) {timeFirstKnock = millis();}
while(sensorValue >= threshold){delay(10);}
}
//А ниже мы проверяем не прошли ли 3 секунды
if (timeFirstKnock !=0) { //если уже идет отсчет
timePast = millis()-timeFirstKnock; // время с первого удара
if (timePast>3000) { //если время прошло
// зажигаем светодиоды
if (knockCount == 1) {analogWrite(ledPin[0], 255); delay (2000); analogWrite(ledPin[0], 0);}
else if (knockCount == 2) {analogWrite(ledPin[1], 255); delay (2000); analogWrite(ledPin[1], 0);}
else if (knockCount == 3) {analogWrite(ledPin[2], 255); delay (2000); analogWrite(ledPin[2], 0);}
timeFirstKnock = 0; //обнуляем т.к. прошло 3 секунды
knockCount = 0;
}
}
}
Пардон, это я ступил, конечно он повисает в цикле, т.к. новому значению sensorValue неоткуда взяться правильней так
while(sensorValue >= threshold){
sensorValue = analogRead(piezoPin);
delay(10);
}
агааа! дошло и до меня... спасибо большое.
у нас в университете хотят ввести экспериментальный курс по микроконтроллерам
Arduino на мой взгляд прекрасно для обучения, тут и схемотехника и электроника и программирование. И все на доступном уровне. А что за универ, если не секрет?
Arduino на мой взгляд прекрасно для обучения, тут и схемотехника и электроника и программирование. И все на доступном уровне. А что за универ, если не секрет?
Да нет, думаю не секрет. Мы из харьковского университета радиоэлектроники.
Да, нам тоже нравится работать с ардуино. Практика отвечает на все наши вопросы) Потому что, как показало, чистая теория не дала никаких результатов. Только сложновато сперва, мы привыкли к чистому программированию, а тут нужно еще учитывать физические процессы.
сорри оффтоп. Привет ХИРЭ!! я тоже родом оттуда, правда 13 лет уж прошло.