Датчик стука

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

Здравствуйте!
Перед нами поставили задание сделать датчик стука. Есть пьезо диск и три светодиода. Если стучишь 1 раз за 3 секунды, загорается первый светодиод, если стучишь 2 раза - второй, 3 раза - третий. Помогите пожалуйста с алгоритмом, как считывать количество ударов?

Modular
Offline
Зарегистрирован: 05.03.2011

Думаю, что для подсчета ударов, надо объявить три глобальные(вне 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;
  }
}

Как-то так.

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

 Спасибо огромное!! Сейчас буду проверять!

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

Получилось так, что все происходит ооочень быстро, и когда мы стучим по пьезо к примеру один раз, то счетчик увеличивается не на 1, а , как мы подобрали, на 1000 или даже больше в соответствии с тем, с какой силой мы стукнем и какой параметр будет в программе сравниваться со значением с датчика. Мы пробовали подбирать эти величины, для двух лампочек хорошо, а вот для трех уже проблемы..(  Как бы это обойти? 

Zaliv
Offline
Зарегистрирован: 05.03.2011

А если попробовать delay() в теле loop, параметр подобрать так, чтобы работало.

Modular
Offline
Зарегистрирован: 05.03.2011

 Если датчик после удара непрерывно передает значение в течение какого-то времени, то  просто вставь цикл, который ожидает окончания удара, сразу после его обнаружения.
// если зафиксирован удар, то
{
   knockCount++; 
   if (timeFirstKnock==0) {timeFirstKnock = millis();}
   while (ПРОВЕРЯЕШЬ, ЧТО ЗНАЧЕНИЕ С ДАТЧИКА ВСЕ ЕЩЕ КАК ПРИ УДАРЕ) 
  {
    //этот цикл вообще можно пустым оставить, нам нужно чтобы программы дальше не пошла до окончания удара
    // а можно маленький delay(10); вставить
  }
}
далее все тоже, что и было
Т.е. ход программы будет тормозиться после начала удара, до его окончания, она просто будет застревать в цикле

Starpom
Offline
Зарегистрирован: 06.03.2011

Saint_Bernard пишет:

Перед нами поставили задание сделать датчик стука. 

Можно полюбопытствовать, такое задание поставили где-то в учебном заведении? Просто интересно используют ли arduino в учебном процессе?

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

Starpom пишет:

Saint_Bernard пишет:

Перед нами поставили задание сделать датчик стука. 

Можно полюбопытствовать, такое задание поставили где-то в учебном заведении? Просто интересно используют ли arduino в учебном процессе?

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

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

Все равно не работает. Посмотрите пожалуйста весь код. Может мы что-то где-то не так делаем.
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;
     }  
   }
}
 

Modular
Offline
Зарегистрирован: 05.03.2011

 Пардон, это я ступил, конечно он повисает в цикле, т.к. новому значению sensorValue неоткуда взяться правильней так
while(sensorValue >= threshold){
  sensorValue = analogRead(piezoPin);
  delay(10);
}

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

агааа! дошло и до меня... спасибо большое.

Zaliv
Offline
Зарегистрирован: 05.03.2011

Saint_Bernard пишет:

у нас в университете хотят ввести экспериментальный курс по микроконтроллерам

Arduino на мой взгляд прекрасно для обучения, тут и схемотехника и электроника и программирование. И все на доступном уровне. А что за универ, если не секрет?

Saint_Bernard
Offline
Зарегистрирован: 25.03.2011

Цитата:

Arduino на мой взгляд прекрасно для обучения, тут и схемотехника и электроника и программирование. И все на доступном уровне. А что за универ, если не секрет?

Да нет, думаю не секрет. Мы из харьковского университета радиоэлектроники. 
Да, нам тоже нравится работать с ардуино. Практика отвечает на все наши вопросы) Потому что, как показало, чистая теория не дала никаких результатов. Только сложновато сперва, мы привыкли к чистому программированию, а тут нужно еще учитывать физические процессы.
 

icms
Offline
Зарегистрирован: 22.03.2011

сорри оффтоп. Привет ХИРЭ!! я тоже родом оттуда, правда 13 лет уж прошло.