Помогите найти ошибку в коде

s1981
Offline
Зарегистрирован: 22.12.2013

Уважаемые! помогите найти ошибку.

#include <TimerOne.h>
 
boolean state = LOW;
boolean prevState = LOW;
const int sensorPin = 10;   // порт для датчика
long timer = 0;   // для замера времи одного оборота (в миллисекундах)
long measuredTimer = 100000;   // время одного оборота (в миллисекундах)
const int debounce = 10; // защита от дребезга контактов
const int timeout = 250; // (миллисекунд) масимальное время ожидания
long counter = 0; // счетчик оборотов
int km = 0; // скорость на выходе
const float radius = .1;
const float circumference = TWO_PI*radius;
const float RPMtoKMH = circumference * 0.06 / 1;

float rpm = 0.0;  // оборотов в минуту
void setup() 
{
  pinMode(sensorPin, INPUT);
  Serial.begin(9600);
  Timer1.initialize(100000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second)
  Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
 
void loop()
{
  // Main code loop
  // TODO: Put your regular (non-ISR) logic here
rpm = digitalLowPass(rpm, 60000.0 /measuredTimer, 0.75); 
km=rpm * RPMtoKMH, 1;
Serial.println(km);
}
 
/// --------------------------
/// Custom ISR Timer Routine
/// --------------------------
float digitalLowPass(float last_smoothed, float new_value, float filterVal)
{
  return (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
}
void timerIsr()
{
  prevState = state;
  state = digitalRead(sensorPin);// считываем датчик
  if (state == HIGH && prevState == LOW && timer > debounce){//если датчик сработал
    measuredTimer = timer; //фиксируем результат замера
    timer = 0; //обнуляем счетчик времени
    counter++; //увеличиваем счетчик оборотов на единицу
  }

  timer++;  
  if (timer > timeout){// если импульсов долго нет, значит стоим
    measuredTimer = measuredTimer + 100; 
  }
}

В принципе все работает, но последние показания не сбрасываюся на 0, даже когда датчик не замкнут. А при таком коде все работает


// данные пользователя - вводятся индивидуально
const int ledPin =  13; 
int ledState = LOW;
unsigned long previousMillis = 0;
const int sensorPin = 10;   // порт для датчика
const float radius = .1; // радиус колеса в метрах ВАШЕГО велосипеда
const float magnets = 1; // количество магнитов для датчика на колесе
const int timeout = 500; // (миллисекунд) масимальное время ожидания
const int debounce = 10; // защита от дребезга контактов
int km = 0; // скорость на выходе
const float circumference = TWO_PI*radius; // расстояние одного оборота колеса
const float RPMtoKMH = circumference * 0.06 / magnets; // коэф перевода (об/мин) в (км/ч)

long timer = 0;   // для замера времи одного оборота (в миллисекундах)
long measuredTimer = 100000;   // время одного оборота (в миллисекундах)
float rpm = 0.0;  // оборотов в минуту
long counter = 0; // счетчик оборотов

boolean state = LOW;
boolean prevState = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
 
  // Print a message to the LCD.
 
  Serial.begin(9600); // включаем вывод в последовательный порт
  pinMode(sensorPin, INPUT);
  // TIMER - выставляем таймер с частотой прерывания в 1 кГц
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1999;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  // END
}

ISR(TIMER1_COMPA_vect) {//Функция прерывания с частотой в 1кГц для считывания датчика
  prevState = state;
  state = digitalRead(sensorPin);// считываем датчик
  if (state == HIGH && prevState == LOW && timer > debounce){//если датчик сработал
    measuredTimer = timer; //фиксируем результат замера
    timer = 0; //обнуляем счетчик времени
    counter++; //увеличиваем счетчик оборотов на единицу
  }

  timer++;  
  if (timer > timeout){// если импульсов долго нет, значит стоим
    measuredTimer = measuredTimer + 100; 
  }
}

void loop(){
    // рассчитываем обороты в секунду и сглаживаем низкочастотным фильтром
    //  (чем больше коэф (к единице) тем плавнее значения)
rpm = digitalLowPass(rpm, 60000.0 /measuredTimer, 0.75); 
km=rpm * RPMtoKMH, 1;
Serial.println(km);

}

//Digital low pass filter - цифровой низкочастотный фильтр, коэф фильтра до единицы (чем ближе к единице тем выше фильтрация)
float digitalLowPass(float last_smoothed, float new_value, float filterVal)
{
  return (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
}

Но мне нужно именно со сторонней библиотекой.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Уберите антидребезг.

s1981
Offline
Зарегистрирован: 22.12.2013

Gippopotam пишет:

Уберите антидребезг.

К сожалению не помогло (

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

совсем убрали?

какая именно переменная должна сброситься?

s1981
Offline
Зарегистрирован: 22.12.2013

Да разобрался сам. Время срабатывания таймера нужно было уменьшить