Arduino зависает при использовании прерываний на энкодер
- Войдите на сайт для отправки комментариев
Чт, 10/01/2019 - 10:54
Это стоит в Loop:
//Обработка энкодера
rotating = true; // reset the debouncer
// Print changes
if (lastReportedPos != encoderPos) { // verify if encoder position has changed
Serial.print(F("Position: "));
int tem = (encoderPos % 16);
//Serial.println(encoderPos % 16, DEC); // print counter for the dial (values 0..15)
Serial.println(tem);
lastReportedPos = encoderPos; // update new position
if(tem>1 and tem <17)
{Speed_of_rotation = Speed_of_rotation - tem;}
}
if (millis() - timing > Speed_of_rotation){ // Вместо 10000 подставьте нужное вам значение паузы
timing = millis();
// ----- has the display asked for data
//if (Serial.available() > 0)
//{
// Char = Serial.read(); // read character
// ----- send data to display whenever a send character ('S') is received
//if (Char == 'S')
//{
// ----- measure distances
measure();
// ----- rotate beam to next ping position
rotate();
// ----- send the results to the display
//Serial.print(Azimuth);
//Serial.print(',');
//Serial.print(Distance1);
//Serial.print(',');
//Serial.print(Distance2);
//Serial.print(',');
//Serial.println(Direction);
softSerial.print("a:");
softSerial.print(Azimuth);
softSerial.print(";");
softSerial.print(Distance1);
softSerial.print(";");
softSerial.print(Distance2);
softSerial.print(";");
softSerial.println(Direction);
//Вывод расстояния на светодиоды
leds(Distance1);
}
Использую порты 2 и 3 и библиотеку для энкодера KY-40
pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); pinMode(clearButton, INPUT_PULLUP); // Encoder pins on interrupt attachInterrupt(digitalPinToInterrupt(encoderPinA), doEncoderA, CHANGE); attachInterrupt(digitalPinToInterrupt(encoderPinB), doEncoderB, CHANGE);
Программа исправно работает, пока не начинаешь вращать энкодер. Начал - программа зависла. С чем может быть связано? Я читал, что с Delay или millis могут быть проблемы, но не понял, все же, что мешает программе выполняться и как это исправляется.
Сделайте миниманьльный скетч воспроизводящий вашу проблему. И приведите его целиком. Что бы можно было откомпилировать и попробовать.
А вообще, я не исповедую учение гласящее "никогда не используйте delay()", иногда его использование вполне допустимо. Но delay() в прерывании.... Это очень, очень плохая идея.
1) delay() использует для подсчета времени micros().
2) micros() читает значение системной переменной timer0_overflow_count.
3) timer0_overflow_count изменяется по прерыванию таймера #0
4) при выполнении обработчика прерывания другие прерывания не обслуживаются.
В Interrupt handler doEncoderA или doEncoderB timer0_overflow_count - не меняется, micros() возвращает одно и то же значение, delay() никогда не завершается.