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() никогда не завершается.