Тахометр
- Войдите на сайт для отправки комментариев
Подскажите, пожалуйста, как реализовать тахометр с использованием геркона?
Мне кажется, что нужно:
1. считать срабатывания геркона в течение какого-то времени (например, одной секунды),
2. поделить количество срабатываний на прошедшее время в миллисекундах, умножить результат на 60, чтобы получить количество оборотов в минуту
3. вывести значение количества оборотов в последовательный порт.
С пунктом 3 проблем нет, а вот со всем остальным - не ясно, какие именно функции как применять.
Мне кажется, что я использую не те операции для циклов и неправильно считаю нажатия:
unsigned long time;
unsigned long Rotation=0;
unsigned long RPM=0;
#define GERK_PIN 3
void setup()
{
Serial.begin(9600);
pinMode(GERK_PIN, INPUT PULLUP);
}
void loop()
//считаем срабатывания геркона в течение какого-то времени (например, одной секунды),
{
time = millis();
while(millis<1000)
{
if (digitalRead(GERK_PIN=true)
Rotation=+Rotation;
}
// поделить количество срабатываний на прошедшее время в миллисекундах
// умножить результат на 1000 и ещё на 60, чтобы получить количество оборотов в минуту
RPM=Rotation/time*60;
// вывод значения количества оборотов в последовательный порт.
Serial.print("RPM: ");
//выводит количество миллисекунд с момента начала выполнения программы
Serial.println(RPM);
// ждет секунду перед следующей итерацией цикла.
delay(1000);
}
Заранее спасибо за помощь!
1. http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
while(millis<1000) { if (digitalRead(GERK_PIN=true) Rotation=+Rotation; }вообще никогда не закончится. millis то в нём не меняется и с какого перепугу ему заканчиваться?
Но, даже если бы Вы его правильно написали, всё равно, так не пойдёт. Вы получите "цену на пролшогодний овёс".
while(millis()-start_millis < 1000) { if (digitalRead(GERK_PIN)) Rotation++; }Как Вы думаете, сколько раз этот цикл успеет сработать за время одного единственного замыкания геркона? Раз 100!. Ну, если очень быстро крутится, то 10.
Вам надо ловить последовательно замыкание - размыкание и только тогда засчитывать срабатывание.
Ну и не забывайте про дребезг контакта. Нужен либо ртутный геркон, либо надо как-то позаботиться о дребезге.
И, кстати, то, что Вы написали, элементарно не скомпилируется. Почему Вы не попробуете сами хотя бы раз запустить, а сразу постите вопрос? Ну, почему сначала не посробовать самому?
Спасибо за быстрый ответ!
Насчёт цикла более-менее понял, наверное, надо считать секунды внутри цикла, верно?
Т.е сняли значение секунд, если оно меньше 1000 - прокрутили цикл ещё раз.
Да, со скоростью срабатывания тоже ясно - я добавил задержку внутри цикла.
Про ловлю замыкания-размыкания непонятно вообще. Нужно ждать замыкания, потом размыкания
и только если эти два события произошли - увеличивать на единицу счётчик?
Дребезг контактов сейчас не так важен, либо переделаю схему на униполярный датчик Холла, либо триггер Шмитта использую.
Мне главное принцип понять, как организовать подсчёт замыканий.
Я пробовал разные варианты, конечно загружал их на Ардуино.
Сюда обратился только когда понял, что самому не разобраться.
unsigned long time; unsigned long Rotation=0; unsigned long RPM=0; #define GERK_PIN 3 int GERK_STATE=0; void setup() { Serial.begin(9600); pinMode(GERK_PIN, INPUT); } void loop() { // Цикл, подсчитывающий нажатия do { time = millis(); GERK_STATE = digitalRead(GERK_PIN); if (GERK_STATE=HIGH) Rotation=+Rotation; delay(10); } while (time < 1000); // поделить количество срабатываний на прошедшее время в миллисекундах // умножить результат на 1000 и ещё на 60, чтобы получить количество оборотов в минуту RPM=Rotation/time*60; // вывод значения количества оборотов в последовательный порт. Serial.print("RPM: "); //выводит количество миллисекунд с момента начала выполнения программы Serial.println(RPM); // ждет секунду перед следующей итерацией цикла. delay(1000); }Нужно ждать замыкания, потом размыкания
и только если эти два события произошли - увеличивать на единицу счётчик?
Конечно.
Подскажите, пожалуйста, как реализовать тахометр с использованием геркона?
Мне кажется, что нужно:
1. считать срабатывания геркона в течение какого-то времени (например, одной секунды),
2. поделить количество срабатываний на прошедшее время в миллисекундах, умножить результат на 60, чтобы получить количество оборотов в минуту
Теоретически измерения частоты и периода эквивалентны, но на практике каждый из вариантов имеет свои плюсы и минусы.
Обычно для высоких частот удобнее измерять количество импульсов, а для низких - период.
Но по-хорошему следует замерять как количество импульсов за _примерно_ заданный промежуток времени, так и точную величину этого промежутка, отсчитывая его от и до фронтов (передних или задних) поступающих импульсов.
Например:
1. Ждем переднего фронта импульса.
2. Импульс пришел - запоминаем время его прихода, например, 32431 мс.
3. Вычисляем, когда _примерно_ заканчивать отсчет времени, например, 32431 + 1000 = 33431 мс.
4. Подсчитывая поступающие импульсы, дожидаемся наступления 33431 мс. Пусть насчитали 3 штуки.
5. Ждем переднего фронта очередного импульса - 4-го по счету.
6. Импульс пришел - запоминаем время его прихода, скажем, 33653 мс.
Частота: 4/(33653 - 32431) = 0,0032733 оборота за мс = 3,2733 об/с = 196,4 об/мин.
Спасибо вам за советы, учёл их в коде. Сейчас измерение проводится подсчётом числа импульсов в секунду, попробую и другие варианты, спасибо за предложение!
Эта версия кода действительно считает нажатия, проблема в том, что она не перестаёт считать их по прошествии одной секунды. Что можно исправить, подскажите?
#define LED_PIN 3 #define GERK_PIN 7 #define TIME 1000 // время, в течение которого будет производится подсчёт оборотов - 1 секунда boolean gerk = false; //состояние геркона boolean previous = false; //предыдущее состояние геркона unsigned long prev_time = 0; // время с момента прошлой проверки unsigned long curr_time = 0; // текущее время long rotation = 0; // счётчик срабатываний геркона long RPS = 0; // количество оборотов в секунду void setup() { pinMode(LED_PIN,OUTPUT); // режим работы пина диода pinMode(GERK_PIN,INPUT); // режим работы пина геркона Serial.begin(9600); // инициализация последовательного порта } void loop() { prev_time = millis(); // считываем значение текущего времени do { //подсчёт оборотов boolean current = digitalRead(GERK_PIN); //проверка геркона if(current && !previous) //если текущее состояние - 1 и прошлое - 0, то { prev_time = curr_time; // сохранить время последнего переключения gerk = !gerk; // переключить геркон в противоположное состояние rotation==rotation++; // увеличение счётчика оборотов на 1 } previous = current; // записать в ячейку прошлого состояния текущее curr_time = millis(); // считываем значение времени, прошедшего с прошлого измерения } while (curr_time - prev_time < TIME); //проверяем, прошла ли секунда // и если прошла, передаём количество оборотов по последовательному порту Serial.println(rotation); rotation=0; //обнуляем счётчик оборотов }Стандартно - вести переменную состояния: считать/не считать.
Идёт сравнение вместо присвоения.
Заметил через 4-ре года :)
Получилось ли довести до рабочего состояния?
Это бессмысленная конструкция и увеличение все равно там происходит на один (конструкция ++).