Не регистрируется полный входной сигнал поворотного энкодера

Я работаю над проектом с использованием вращающегося энкодера и пытаюсь получить выходные данные от энкодера. В нынешнем виде я могу подсчитать степень изменения и направление вращения, однако в зависимости от скорости вращения энкодера я получаю различные выходные данные вращения. Например, если я поверну его медленно, я могу получить сотни отсчетов при повороте на 180 градусов, но если я сделаю это быстро, я смогу получить около 10 отсчетов.

Я считаю, что мой Arduino работает слишком медленно, чтобы считать каждый сигнал от энкодера. Я измерил длину волны сигнала, составившую ~25 мкс при быстром вращении, но с помощью следующего кода я обнаружил, что мой Arduino работает со скоростью скорость цикла 200 циклов в секунду.

void loop() {
  if(counter <= 1000){
    counter++;
    Serial.println(counter);
  }
}

Код поворотного энкодера: Выводы Dt и Clk обозначают два сигнальных провода, оба подтянуты.

void loop(){

  // принимаем состояние контакта clk
  clkState = digitalRead(clkPin);

  //если состояние clk изменилось, то колесо вращается, реагируем на нарастающий фронт, чтобы избежать двойного счета
  if(clkState != preClkState && clkState == HIGH){
    Serial.write(digitalRead(dtPin));
    //проверяем направление вращения по dtpin
    if(digitalRead(dtPin)== HIGH){
      counter++;

      clockwiseDirection = true;
    }else{
      counter--;

      clockwiseDirection = false;
    }

    //выходные значения
    Serial.write("Direction: ");
    if(clockwiseDirection){
      Serial.write("Clockwise | Counter: ");
    }else{
      Serial.write("Counter Clockwise | Counter: ");
    }

    Serial.print((int)counter);
    Serial.print("\n");

  }

  //обновляем предварительную позицию
  preClkState = clkState;

}

Заранее спасибо.

, 👍0

Обсуждение

Возможно ли, что все данные, выводимые на последовательный монитор, немного замедляют работу?, @VE7JRO

вам следует использовать прерывания вместо digitalRead, чтобы обеспечить быструю прокрутку. и да, не печатайте каждый фиксатор., @dandavis


1 ответ


0

Последовательная передача требует времени. Предположим, вы настроили Serial на скорость 9600 бод. Это означает 9600 бит в секунду. Передача одного байта обычно состоит из стартового бита, битов данных и одного стопового бита. Это дает в общей сложности 10 бит на байт. Следовательно, ваша скорость передачи составляет 9600 бит/с / 10 бит/байт = 960 байт/с.

При быстром просмотре исходного кода каждый цикл вашего эскиза отправляет около 40 символов, обычно кодируемых как байт на символ. И вы утверждаете, что он достигает 200 циклов в секунду, поэтому скорость передачи составляет 40 байт/цикл * 200 циклов/с = 8000 байт/с.

В результате обратного расчета в битах/с скорость передачи данных составит примерно 80 000 бит/с. Итак, предположительно вы настроили свой Serial на скорость 57600 или 115200 бод.


Как решить проблему?

Отдельно получение данных кодера от передачи значения счетчика. Вы можете использовать прерывания, например, по тактовому сигналу. Однако это занятие не для слабонервных.

Serial использует буфер передачи неопределенного размера. См. последний абзац его документации:

Начиная с Arduino IDE 1.0, последовательная передача является асинхронной. Если в буфере передачи достаточно пустого места, Serial.write() вернется до того, как какие-либо символы будут переданы по последовательному порту. Если буфер передачи заполнен, Serial.write() будет блокироваться до тех пор, пока в буфере не будет достаточно места. Чтобы избежать блокировки вызовов Serial.write(), вы можете сначала проверить объем свободного места в буфере передачи с помощью availableForWrite().

Вы можете проверить, достаточно ли места в буфере передачи для вашего сообщения. Отправляйте только при наличии достаточного места.

,