Периодичность опроса энкодера?

Lictor
Offline
Зарегистрирован: 01.10.2015

Доброго времени суток.

Есть такая проблема

/*
Функция декодирования кода Грея, взятая с Википедии.
Принимает число в коде Грея, возвращает обычное его представление.
*/
unsigned graydecode(unsigned gray)  //
{
  unsigned bin;
  for (bin = 0; gray; gray >>= 1)
    bin ^= gray;
  return bin;
}   //конец декодирования кода Грея

unsigned graydecode1(unsigned gray1)  //
{
  unsigned bin1;
  for (bin1 = 0; gray1; gray1 >>= 1)
    bin1 ^= gray1;
  return bin1;
}   //конец декодирования кода Грея

void loop() {
  /////////////////////////////////////////////////////////////////////////////////////////////
  //                            энкодер                                                      //
  /////////////////////////////////////////////////////////////////////////////////////////////
  static uint8_t previous_code = 0;  // предыдущий считанный код энкодера
  static uint8_t previous_code1 = 0; // предыдущий считанный код энкодера
  /* gray_code - считанное с энкодера значение
  code - декодированное значение  */
  uint8_t gray_code = digitalRead(A0) | (digitalRead(A1) << 1),
          code = graydecode(gray_code);
  /* Если считался нуль, значит был произведён щелчок ручкой энкодера */
  if (code == 0) {
    switch (previous_code) {
      case 1:
        x += 3;
        fl0 = 1;
        ms1 = ms;
        if (x > 320)
          x = 0;
        break;
      case 3:
        x -= 3;
        fl0 = 1;
        ms1 = ms;
        if (x < 1)
          x = 320;
        break;
    }
  }
  uint8_t gray_code1 = digitalRead(2) | (digitalRead(3) << 1),
          code1 = graydecode1(gray_code1);
  // Если считался нуль, значит был произведён щелчок ручкой энкодера
  if (code1 == 0) {
    switch (previous_code1) {
      case 1:
        y += 3;
        fl0 = 1;
        ms1 = ms;
        if (y > 240)
          y = 0;
        break;
      case 3:
        y -= 3;
        fl0 = 1;
        ms1 = ms;
        if (y < 1)
          y = 240;
        break;
    }
  }
  previous_code1 = code1;
  previous_code = code; //как то связано с энкодером, не трогать!
  /* Если переход к нулю был из состояния 3 - ручка вращалась
   * по часовой стрелке, если из 1 - против. */
  /////////////////////////////////////////////////////////////////////////////////////////////
  //                            курсор                                                       //
  /////////////////////////////////////////////////////////////////////////////////////////////
  if (fl0 == 1) {
    myGLCD.setColor(155, 155, 255);
    myGLCD.drawCircle(x, y, 12);
  }
  /////////////////////////////////////////////////////////////////////////////////////////////
  //                           обновление экрана после перемещения курсора                   //
  /////////////////////////////////////////////////////////////////////////////////////////////
  ms = millis();
  if (fl0 == 1 && ms - ms1 > 1000) {
    ms1 = ms;
    fl0 = 0;
    myGLCD.clrScr();
    myFiles.loadBitmap(0, 0, 320, 240, files[0]);
    myGLCD.setColor(155, 155, 255);
    myGLCD.drawCircle(x, y, 12);
  }

При вращении ручки энкодера курсор перемещается примерно раз в секунду, в то же время если вставить функцию курсора в блок энкодера в switch (previous_code), то курсор перемещается мгновенно, по повороту энкодера, с чем связана задержка смещения?

vde69
Offline
Зарегистрирован: 10.01.2016

у тебя обновление экрана 1 раз в секунду, сделай его не по времени а при изменении данных, тогда будет мгновенно...

Lictor
Offline
Зарегистрирован: 01.10.2015

vde69 пишет:

у тебя обновление экрана 1 раз в секунду, сделай его не по времени а при изменении данных, тогда будет мгновенно...

обновление экрана обновляет картинку, убирая след, в блоке Курсор рисование происходит мгновенно же?

Lictor
Offline
Зарегистрирован: 01.10.2015
Может если выложить весь код, станет понятней? В коде указано куда можно вставить код курсора для быстрого перемещения.
#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h> //библиотеки
byte fl0; // флаг обновления экрана
extern uint8_t SmallFont[]; //шрифт по умолчанию
UTFT myGLCD(TFT01_22SP, 8, 9, 10, 5, 6);   //  инициализация дисплея
UTFT_tinyFAT myFiles(&myGLCD); //создание класса объекта
unsigned long ms; //счетчик времени
unsigned long ms1; //счетчик времени обновления экрана
unsigned long ms2; //счетчик времени кнопки 1
char* files[] = {"PIC302.RAW", "PIC303.RAW", "mash.raw", "tank.raw"}; // 320x240
volatile  int x = 160; //положение курсора по оси х
volatile  int y = 120; //положение курсора по оси у

void setup() {
//  Serial.begin(9600); //тестовая строка
  pinMode(A2, INPUT_PULLUP); // подключение кнопоки 1
  pinMode(A0, INPUT_PULLUP); // подключение энкодера 1
  pinMode(A1, INPUT_PULLUP); // подключение энкодера 1
  pinMode(2, INPUT_PULLUP); // подключение энкодера 2
  pinMode(3, INPUT_PULLUP); // подключение энкодера 2
  myGLCD.InitLCD(LANDSCAPE); //задание горизонтальной ориентации экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT(); //хз зачем, но нужно для экрана
  myGLCD.setFont(SmallFont); //задание шрифта надписей
  myFiles.loadBitmap(0, 0, 320, 240, files[0]); //вывод начального изображения
}
/*
Функция декодирования кода Грея, взятая с Википедии.
Принимает число в коде Грея, возвращает обычное его представление.
*/
unsigned graydecode(unsigned gray)  //
{
  unsigned bin;
  for (bin = 0; gray; gray >>= 1)
    bin ^= gray;
  return bin;
}   //конец декодирования кода Грея

unsigned graydecode1(unsigned gray1)  //
{
  unsigned bin1;
  for (bin1 = 0; gray1; gray1 >>= 1)
    bin1 ^= gray1;
  return bin1;
}   //конец декодирования кода Грея

void loop() {
  /////////////////////////////////////////////////////////////////////////////////////////////
  //                            энкодер                                                      //
  /////////////////////////////////////////////////////////////////////////////////////////////
  static uint8_t previous_code = 0;  // предыдущий считанный код энкодера
  static uint8_t previous_code1 = 0; // предыдущий считанный код энкодера
  /* gray_code - считанное с энкодера значение
  code - декодированное значение  */
  uint8_t gray_code = digitalRead(A0) | (digitalRead(A1) << 1),
          code = graydecode(gray_code);
  /* Если считался нуль, значит был произведён щелчок ручкой энкодера */
  if (code == 0) {
    switch (previous_code) {
      case 1:
        x += 3;
        fl0 = 1;
        ms1 = ms;
        if (x > 320)
          x = 0;
        break;
      case 3:
        x -= 3;
        fl0 = 1;
        ms1 = ms;
        if (x < 1)
          x = 320;
        break;
    }
//если блок курсора вставить сюда, то курсор перемещается мгновенно по оси х, сразу как повернуть энкодер
  }
  uint8_t gray_code1 = digitalRead(2) | (digitalRead(3) << 1),
          code1 = graydecode1(gray_code1);
  // Если считался нуль, значит был произведён щелчок ручкой энкодера
  if (code1 == 0) {
    switch (previous_code1) {
      case 1:
        y += 3;
        fl0 = 1;
        ms1 = ms;
        if (y > 240)
          y = 0;
        break;
      case 3:
        y -= 3;
        fl0 = 1;
        ms1 = ms;
        if (y < 1)
          y = 240;
        break;
    }
//если блок курсора вставить сюда, то курсор перемещается мгновенно по оси y, сразу как повернуть энкодер
}
previous_code1 = code1;
previous_code = code; //как то связано с энкодером, не трогать!
/* Если переход к нулю был из состояния 3 - ручка вращалась
по часовой стрелке, если из 1 - против. */
/////////////////////////////////////////////////////////////////////////////////////////////
// курсор //
/////////////////////////////////////////////////////////////////////////////////////////////
if (fl0 == 1) {
myGLCD.setColor(155, 155, 255);
myGLCD.drawCircle(x, y, 12);
}
/////////////////////////////////////////////////////////////////////////////////////////////
// обновление экрана после перемещения курсора //
/////////////////////////////////////////////////////////////////////////////////////////////
ms = millis(); //общий счетчик времени
if (fl0 == 1 && ms - ms1 > 1000) {
ms1 = ms;
fl0 = 0;
myGLCD.clrScr();
myFiles.loadBitmap(0, 0, 320, 240, files[0]);
myGLCD.setColor(155, 155, 255);
myGLCD.drawCircle(x, y, 12);
}
/////////////////////////////////////////////////////////////////////////////////////////////
// кнопка //
/////////////////////////////////////////////////////////////////////////////////////////////
if (digitalRead(A2) == HIGH)
ms2 = ms;
if (digitalRead(A2) == LOW && ms - ms2 > 50) {
myFiles.loadBitmap(100, 100, 80, 80, files[2]);
}
// Serial.println(x);
// Serial.println(y);
} //конец цикла void loop