Не корректная работа энкодера
- Войдите на сайт для отправки комментариев
Вс, 06/11/2016 - 11:42
Есть энкодер на основе датчика Холла. Подключен ко второму входу и обрабатывается прерываниями. Суть проблемы в некорректной передаче переменной из прерывания (я так думаю). Пробовал менять датчик, даже поменял на оптический, не помогает. В момент перехода цикла loop переменная сбивается, при обратном счете происходит тоже самое. Есть идеи.
Это зачения с монитора:
2
2
2
Up
14
New
14
14
1
14
14
14
14
14
#define RPMpin 2 // датчик Холла
volatile unsigned int rp = 0; // счетчик оборотов
volatile bool reverce = true;
void setup()
{
Serial.begin(9600);
pinMode(RPMpin, INPUT_PULLUP);
digitalWrite(RPMpin, 1);
attachInterrupt(0, RPM, FALLING);
pinMode(10, OUTPUT); // Тормоз
pinMode(12, OUTPUT); // Прямое вращение
pinMode(11, OUTPUT); // обратное вращение
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
}
void loop()
{
Serial.println(rp, DEC);
Serial.println("New");
Serial.println(rp, DEC); // об/мин
// rpm = 1;
digitalWrite(10, LOW);
digitalWrite(12, LOW);
Serial.println(rp, DEC);
// rpm = 1;
Serial.println(reverce);
// delay (5000);
while (rp < 80)
{ Serial.println(rp, DEC);
// Serial.println("OK");
// delay (5000);
}
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
reverce = false;
delay(5000);
Serial.println("Down");
Serial.println(rp, DEC);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
Serial.println(rp, DEC);
// rpm = 199;
while (rp > 0)
{ Serial.println(rp, DEC); }
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
reverce= true;
delay(5000);
Serial.println("Up");
}
void RPM () // Это счетчик оборотов
{
if (reverce) {++rp;} else {--rp;}
}
А зачем делей? Тем более такой аццкий. Как ваша система определяет направление вращения?
if (reverce) {++rp;} else {--rp;}И вот эта строка не ясна. Может
if(reverce == 1) {++rp;}else{--rp;}?
Блин. Ну названия темы дают. Энкодер он работает нормально. А вот программист Andrey_vlz не корректно работает. Хрень пишет и хрень получается. Энкодер это не только датчик Холла, но и много много чего-то. Может у вас счетчик оборотов с реверсом.
Здесь проверяется внешнее условие направление вращения. В соответствии с этим счетчик либо прибавляется либо отнимается. Ваше написание тойже строки аналогично.
В этом и вопрос - ГДЕ ОШИБКА?
Вот если у вас счетчик оборотов с реверсом, и если вперед вы считаете по фронту. То при обратном вращении надо считать по спаду.
В этом и вопрос - ГДЕ ОШИБКА?
Ошибка как не странно в непонимании процессов, а программа и ее работа это следствие. "Лечить
"надо причины, а не следствия.
Датчик Холла по спаду и работает. Нужно убрать слово энкодер из темы вообще
Я менял способы считывания прерываний. Ничего не меняется. ВОПРОС - почему происходит скачек в значения переменной, причем он всегда разный. Може парамую с ячейкой памяти работать?
У оптического датчика таже проблема.
Потому что в момент прохода магнита через датчик импульс выдается не один, а целая серия. Как друбезг у кнопки. Попробуйте использовать класс для кнопки
Megawollt, не буду говорить за все датчики, но тот датчик холла что я однажды тестил не давал дребезга вообще.
Andrey_vlz, схем вы не рисовали, фотографий не давали, так что предположение будет таким же неконкретным -у вас откуда то приползают помехи.
Цифровой да, не даёт, но счёт получается все равно нестабильным. Сам сталкивался, но у меня направление не менялось :)
вот ваша программа. Просто добавил комментарии для остальных
/* датчик Холла питание ->2 (RPMpin) сигнал ->1 тормоз -> 10 (brake_pin) 1 вкл / 0 нет прямо -> 11 (direct_pin) 0 вкл / 1 нет обратно -> 12 (back_pin) 0 вкл / 1 нет */ #define RPMpin 2 // датчик Холла const int brake_pin = 10; const int direct_pin = 11; const int back_pin = 12; volatile unsigned int rp = 0; // счетчик оборотов volatile bool reverce = 1; // направление счета 1 вперед / 0 назад void RPM () { // Это счетчик оборотов обрабатыв прерыванием if (reverce) ++rp; else --rp; } void setup() { Serial.begin(9600); pinMode(RPMpin, INPUT_PULLUP); digitalWrite(RPMpin, 1); // подключить датчик Холла attachInterrupt(0, RPM, FALLING); pinMode(brake_pin, OUTPUT); // Тормоз digitalWrite(brake_pin, 1); pinMode(back_pin, OUTPUT); // Прямое вращение digitalWrite(back_pin, 1); pinMode(direct_pin, OUTPUT); // обратное вращение digitalWrite(direct_pin, 1); } void loop() { Serial.println(rp, DEC); Serial.println("New"); Serial.println(rp, DEC); // об/мин // rpm = 1; digitalWrite(brake_pin, LOW); // отк тормоз digitalWrite(back_pin, LOW); // вкл обр вращение Serial.println(rp, DEC); // rpm = 1; Serial.println(reverce); // delay (5000); while (rp < 80) { Serial.println(rp, DEC); // Serial.println("OK"); // delay (5000); } digitalWrite(brake_pin, HIGH); // вкл тормоз digitalWrite(back_pin, HIGH); // откл обр вращение reverce = 0; // счет обратно delay(5000); Serial.println("Down"); Serial.println(rp, DEC); digitalWrite(brake_pin, LOW); // отк тормоз digitalWrite(direct_pin, LOW); // вкл прям вращение Serial.println(rp, DEC); // rpm = 199; while (rp > 0) { Serial.println(rp, DEC); } digitalWrite(brake_pin, HIGH); // вкл тормоз digitalWrite(direct_pin, HIGH); // откл обр вращение reverce = 1; // счет вперед delay(5000); Serial.println("Up"); }Megawollt, не буду говорить за все датчики, но тот датчик холла что я однажды тестил не давал дребезга вообще.
Andrey_vlz, схем вы не рисовали, фотографий не давали, так что предположение будет таким же неконкретным -у вас откуда то приползают помехи.
Сейчас она упрощена до предела. Есть плата MEGA 2560, к ней на 2 pin подключен оптический датчик (стандартный щелевой из набора) и все. Он впринципе не дребежит. При медленом тесте обнаруживается, что показания счетчика при каждом прохождении меняются не всегда на 1.
Немного изменил код. Стал отслеживать переменную прямо в прерывании. Стало немного понятнее. Из-за высого приоритета прерывания основной код не получает управление и значения ухлдат далеко за пределы допустимого.
/* датчик Холла питание ->2 (RPMpin) сигнал ->1 тормоз -> 10 (brake_pin) 1 вкл / 0 нет прямо -> 11 (direct_pin) 0 вкл / 1 нет обратно -> 12 (back_pin) 0 вкл / 1 нет */ #define RPMpin 2 // датчик Холла const int brake_pin = 10; const int direct_pin = 11; const int back_pin = 12; volatile int rp = 0; // счетчик оборотов volatile bool reverce = 1; // направление счета 1 вперед / 0 назад void RPM () { // Это счетчик оборотов обрабатыв прерыванием if (reverce) ++rp; else --rp; Serial.println(rp, DEC); } void setup() { Serial.begin(9600); pinMode(RPMpin, INPUT_PULLUP); digitalWrite(RPMpin, 1); // подключить датчик Холла attachInterrupt(0, RPM, FALLING); pinMode(brake_pin, OUTPUT); // Тормоз digitalWrite(brake_pin, 1); pinMode(back_pin, OUTPUT); // Прямое вращение digitalWrite(back_pin, 1); pinMode(direct_pin, OUTPUT); // обратное вращение digitalWrite(direct_pin, 1); } void loop() { Serial.println("New"); digitalWrite(brake_pin, LOW); // отк тормоз digitalWrite(back_pin, LOW); // вкл обр вращение while (rp < 80) { } digitalWrite(brake_pin, HIGH); // вкл тормоз digitalWrite(back_pin, HIGH); // откл обр вращение reverce = 0; // счет обратно delay(5000); Serial.println("Down"); digitalWrite(brake_pin, LOW); // отк тормоз digitalWrite(direct_pin, LOW); // вкл прям вращение while (rp > 0) { } digitalWrite(brake_pin, HIGH); // вкл тормоз digitalWrite(direct_pin, HIGH); // откл обр вращение reverce = 1; // счет вперед delay(5000); Serial.println("Up"); }