Ошибка расчета с оптическим энкодером
Я исправил свой код для чтения индекса оптического энкодера, но теперь получаю другую ошибку расчета. По индексу энкодер сбрасывается на ноль, но теперь мои показания следующие: Индексная точка – сбрасывается на ноль. - На отметке поворота 90 градусов у меня показания 180 градусов. - На отметке поворота на 180 градусов у меня отображается 0, потому что код сбрасывает его на ноль после 359 градусов. - На отметке поворота 270 градусов у меня показания 180 градусов. - На отметке 0 градусов он снова равен нулю, и именно этого я и ожидал от индекса. Если я перезапущу Arduino Mega на отметке 270 градусов, индекс обнулится, как и должно быть. Будучи новичком в этом, до того, как у меня работал индекс, он работал правильно, за исключением индексной функции, теперь, похоже, происходит двойной подсчет. Есть идеи?
// Проводные соединения для моего кодера:
// Коричневый: VCC = 5 В
// Синий + Экран: 0 В = GND
// Черный: ENCODER0PINA, контакт 20
// Белый: ENCODER0PINB, контакт 17
// Оранжевый: ENCODER0PINI, контакт 19
#define ENCODER0PINA 20 // этот вывод должен поддерживать прерывания
#define ENCODER0PINB 17 // прерывание не требуется
#define ENCODER0PINI 19 // этот вывод должен поддерживать прерывания
// переменные, измененные обработчиком прерывания, должны быть объявлены как изменчивые
volatile long encoder0Position = 0;
volatile long interruptsReceived = 0;
volatile byte INTFLAG1 = 0;
// отслеживаем последнюю позицию, чтобы знать, стоит ли печатать новый вывод
long previousPosition = 0;
void setup()
{
// входы
pinMode(ENCODER0PINA, INPUT);
digitalWrite(ENCODER0PINA, HIGH); // включаем подтягивающий резистор
pinMode(ENCODER0PINB, INPUT);
digitalWrite(ENCODER0PINB, HIGH); // включаем подтягивающий резистор
pinMode(ENCODER0PINI, INPUT);
digitalWrite(ENCODER0PINI, HIGH); // включаем подтягивающий резистор
// прерывания
attachInterrupt(3, onInterrupt, CHANGE); // энкодер дорожки A на прерывании 3 - вывод 20
attachInterrupt(4, onReset, CHANGE); // Индексная дорожка энкодера на прерывании 4 - контакт 19
// включаем диагностический вывод
Serial.begin (115200);
Serial.println("Ready.");
}
void loop()
{
// отображаем информацию о позиции только в том случае, если она изменилась
if (encoder0Position != previousPosition )
{
Serial.println(encoder0Position, DEC);
previousPosition = encoder0Position;
}
}
// функция прерывания должна делать как можно меньше
void onReset()
{
// читаем ввод индекса
int i = digitalRead(ENCODER0PINI);
if (i == 1)
{
encoder0Position = INTFLAG1;
}
}
void onInterrupt()
{
// читаем оба направленных ввода
int a = digitalRead(ENCODER0PINA);
int b = digitalRead(ENCODER0PINB);
if (a == b)
{
// b опережает a (против часовой стрелки)
encoder0Position--;
if (encoder0Position < 0)
{
encoder0Position = (encoder0Position + 360);
}
}
else
{
// a опережает b (по часовой стрелке)
encoder0Position++;
if (encoder0Position >= 360)
{
encoder0Position = (encoder0Position - 360);
}
}
}
@Bkukuk62, 👍0
Обсуждение1 ответ
Я разобрался со своей проблемой, по крайней мере, получаю хорошие результаты. С помощью этого кода мне пришлось изменить прерывания с CHANGE на RISING. Я хочу поблагодарить всех, кто прокомментировал этот вопрос. –
- Считывание нескольких поворотных энкодеров
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
- Взаимодействие с датчиком SSI?
- Как выбрать входной контакт 600 кГц, разделить его на 4 и сгенерировать низкочастотный сигнал на выходном контакте Arduino
- Мотор-редуктор BLDC с энкодером - Как подключить энкодер? (6 проводов)
- Проблема с индексом оптического поворотного энкодера
- Сохранение значения одним кликом
- От Uno до Mega, и где ошибка необъявленного прерывания?
пожалуйста, отформатируйте свой код как «код» .... выделите весь текст кода и нажмите кнопку
{}
, @jsotolaЯ сделал это для него/нее., @Delta_G
Спасибо, мне было интересно, как отформатировать код как «код». (ему)., @Bkukuk62
Какой кодер вы используете? Есть ли приращение 0,5 градуса?, @evolutionizer
Это инкрементальный поворотный энкодер Omron E6B2-CWZ6C с индексом (360P/R)., @Bkukuk62
Еще один комментарий к приведенному выше коду. До введения Индекса он работал правильно. Я протестировал индекс, и он срабатывает только один раз за оборот., @Bkukuk62
Я провел дополнительное тестирование кода и заметил, что когда энкодер поворачивается по часовой стрелке мимо индекса, показания становятся следующими: 359, 0, 1, 2, 0, 1, 2, 3, после этого он читается правильно. При повороте энкодера против часовой стрелки происходит следующее: 1, 0, 359, 358, 0, 359, 358, 357, а затем работает правильно. Кто-нибудь понимает, почему кодер делает это, а также первоначальную проблему?, @Bkukuk62
Я разобрался со своей проблемой, по крайней мере, получаю хорошие результаты. С помощью этого кода мне пришлось изменить прерывания с CHANGE на RISING. Я хочу поблагодарить всех, кто прокомментировал этот вопрос., @Bkukuk62