Здравствуйте! Хочу сделать простой тахометр, который считал бы замыкания геркона и выводил показания в оборотах в секунду через последовательный порт. Проблема в том, что сейчас программа считает замыкания до тех пор, пока они не прекратятся, а должны считаться только на протяжении секунды. Подскажите, пожалуйста, что можно исправить? Код: Код (C++): #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; //обнуляем счётчик оборотов }
Она у вас сейчас ждет секунду с момента последнего переключения геркона. Так и должно быть? Если нужно просто раз в секунду выдать кол-во оборотов, то цикл должен быть примерно таким: Код (C++): prev_time = millis() + 1000; while (millis < prev_time) { // тут считаем сработки } Serial.println(rotation) rotation=0;
А разве это будет работать? У Вас цикл работает, пока количество миллисекунд со старта меньше prev_time. А так как prev_time = millis() + 1000; то цикл никогда не закончится.
Понятно, она будет крутить цикл до достижения 1000. У Вас более изящное решение, попробовал его - всё работает. Огромное спасибо! А вот мой вариант, теперь тоже работоспособный: Код (C++): #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, то { gerk = !gerk; // переключить геркон в противоположное состояние rotation==rotation++; // увеличение счётчика оборотов на 1 curr_time = millis(); // считать текущее время } previous = current; // записать в ячейку прошлого состояния текущее } while (curr_time - prev_time < TIME); //проверяем, прошла ли секунда // и если прошла, передаём количество оборотов по последовательному порту Serial.println(rotation); rotation=0; //обнуляем счётчик оборотов }