Тахометр

Тема в разделе "Arduino & Shields", создана пользователем mattias, 10 янв 2016.

  1. mattias

    mattias Нуб

    Здравствуйте!
    Хочу сделать простой тахометр, который считал бы замыкания геркона и выводил показания в оборотах в секунду через последовательный порт.

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

    Код (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; //обнуляем счётчик оборотов

    }
     
  2. DrProg

    DrProg Вечный нерд

    Она у вас сейчас ждет секунду с момента последнего переключения геркона. Так и должно быть? Если нужно просто раз в секунду выдать кол-во оборотов, то цикл должен быть примерно таким:
    Код (C++):
    prev_time = millis() + 1000;

    while (millis < prev_time) {
    // тут считаем сработки
    }

    Serial.println(rotation)
    rotation=0;
     
    ИгорьК нравится это.
  3. mattias

    mattias Нуб

    А разве это будет работать? У Вас цикл работает, пока количество миллисекунд со старта меньше
    prev_time. А так как prev_time = millis() + 1000; то цикл никогда не закончится.
     
  4. DrProg

    DrProg Вечный нерд

    Закончится через 1000 миллисекунд.
     
    ИгорьК нравится это.
  5. mattias

    mattias Нуб

    Понятно, она будет крутить цикл до достижения 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; //обнуляем счётчик оборотов

    }