Один вариант кода работает, второй - не работает. Где я ошибся?
- Войдите на сайт для отправки комментариев
Втр, 26/05/2015 - 16:02
Всем привет.
Имею вот такой очень короткий кода, который отрабатывает исправно:
//********************************************************************
volatile unsigned long micros_sp = 0;
volatile byte sz = 0; //счетчик обнуления
volatile unsigned int sp = 0; //скорость
volatile boolean st = false; //триггер
long previousMillis = 0;
long interval = 1000; //1000 - 1 секунда
//********************************************************************
void setup() {
pinMode(2, INPUT_PULLUP);
Serial.begin(115200); //инициализация ком порта
attachInterrupt(0, speedometr, FALLING); //прерывание спидометра по фронту импульса
}
//********************************************************************
void loop() {
Serial.println (sp);
if (sz != 0) {
sz--;
} else {
sp = 0;
};
delay(500);
}
//********************************************************************
void speedometr() { //измеряем частоту на входе спидометра по прерыванию
if (!st) {
micros_sp = micros();
}
else {
sp = 1.6 * (1000000 / (micros() - micros_sp));
}
st = !st;
sz = 30;
}
А вот тот же самый код, но с попыткой избавиться от delay:
//********************************************************************
volatile unsigned long micros_sp = 0;
volatile byte sz = 0; //счетчик обнуления
volatile unsigned int sp = 0; //скорость
volatile boolean st = false; //триггер
long previousMillis = 0;
long interval = 1000; //1000 - 1 секунда
//********************************************************************
void setup() {
pinMode(2, INPUT_PULLUP);
Serial.begin(115200); //инициализация ком порта
attachInterrupt(0, speedometr, FALLING); //прерывание спидометра по фронту импульса
}
//********************************************************************
void loop() {
//Serial.println (sp);
if (sz != 0) {
sz--;
} else {
sp = 0;
};
//delay(500);
unsigned long currentMillis = millis();
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
Serial.println(sp);
}
}
//********************************************************************
void speedometr() { //измеряем частоту на входе спидометра по прерыванию
if (!st) {
micros_sp = micros();
}
else {
sp = 1.6 * (1000000 / (micros() - micros_sp));
}
st = !st;
sz = 30;
}
Первый код отрабатывает правильно (выводит в консоль скорость авто), второй - выводит нули. Где я накосячил?
Вы уменьшаете sz ДО проверки "прошел ли нужный интервал", - при каждом вызове loop.
Пока там интервал пройдёт, sz давно уже успеет обнулиться.
Все, спасибо - дошло. Вот так должно работать.
//******************************************************************** volatile unsigned long micros_sp = 0; volatile byte sz = 0; //счетчик обнуления volatile unsigned int sp = 0; //скорость volatile boolean st = false; //триггер long previousMillis = 0; // храним время последнего переключения светодиода long interval = 1000; //1000 - 1 секунда //******************************************************************** void setup() { pinMode(2, INPUT_PULLUP); Serial.begin(115200); //инициализация ком порта attachInterrupt(0, speedometr, FALLING); //прерывание спидометра по фронту импульса } //******************************************************************** void loop() { unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if (currentMillis - previousMillis > interval) { // сохраняем время последнего переключения previousMillis = currentMillis; Serial.println(sp); if (sz != 0) { sz--; } else { sp = 0; }; } } //******************************************************************** void speedometr() { //измеряем частоту на входе спидометра по прерыванию if (!st) { micros_sp = micros(); } else { sp = 1.6 * (1000000 / (micros() - micros_sp)); } st = !st; sz = 30; }Пошел до машины - проверю.
Не за что.