Энкодер

Тема в разделе "ESP8266, ESP32", создана пользователем TebEnkov2222, 15 авг 2018.

  1. TebEnkov2222

    TebEnkov2222 Нерд

    Господа.. Добрый вечер.. Пробелма с подключением энкодером на еспиху.. На уне вся программа великолепно работает.. А на есп (esp32) ну никак не хочет работать...
    Скину только программу распознавания энкодера..
    Код (C++):
    int pinA = 19; // Пины прерываний
    int pinB = 23; // Пины прерываний

    volatile long pause    = 50;  // Пауза для борьбы с дребезгом
    volatile long lastTurn = 0;   // Переменная для хранения времени последнего изменения

    volatile int count = 0;       // Счетчик оборотов
    int actualcount    = 0;       // Временная переменная определяющая изменение основного счетчика

    volatile int state = 0;       // Статус одного шага - от 0 до 4 в одну сторону, от 0 до -4 - в другую

    volatile int pinAValue = 0;   // Переменные хранящие состояние пина, для экономии времени
    volatile int pinBValue = 0;   // Переменные хранящие состояние пина, для экономии времени


    void setup()
    {
      pinMode(pinA, INPUT);           // Пины в режим приема INPUT
      pinMode(pinB, INPUT);           // Пины в режим приема INPUT

      attachInterrupt(0, A, CHANGE);  // Настраиваем обработчик прерываний по изменению сигнала
      attachInterrupt(1, B, CHANGE);  // Настраиваем обработчик прерываний по изменению сигнала

      Serial.begin(115200);             // Включаем Serial
      Serial.println("Начало");
    }

    void loop()
    {
      if (actualcount != count) {     // Чтобы не загружать ненужным выводом в Serial, выводим состояние
        actualcount = count;          // счетчика только в момент изменения
        Serial.println(actualcount);
      }
    }

    void A()
    {
      if (micros() - lastTurn < pause) return;  // Если с момента последнего изменения состояния не прошло
      // достаточно времени - выходим из прерывания
      pinAValue = digitalRead(pinA);            // Получаем состояние пинов A и B
      pinBValue = digitalRead(pinB);

      cli();    // Запрещаем обработку прерываний, чтобы не отвлекаться
      if (state == 0  && !pinAValue &&  pinBValue || state == 2  && pinAValue && !pinBValue) {
        state += 1; // Если выполняется условие, наращиваем переменную state
        lastTurn = micros();
      }
      if (state == -1 && !pinAValue && !pinBValue || state == -3 && pinAValue &&  pinBValue) {
        state -= 1; // Если выполняется условие, наращиваем в минус переменную state
        lastTurn = micros();
      }
      setCount(state); // Проверяем не было ли полного шага из 4 изменений сигналов (2 импульсов)
      sei(); // Разрешаем обработку прерываний

      if (pinAValue && pinBValue && state != 0) state = 0; // Если что-то пошло не так, возвращаем статус в исходное состояние
    }
    void B()
    {
      if (micros() - lastTurn < pause) return;
      pinAValue = digitalRead(pinA);
      pinBValue = digitalRead(pinB);

      cli();
      if (state == 1 && !pinAValue && !pinBValue || state == 3 && pinAValue && pinBValue) {
        state += 1; // Если выполняется условие, наращиваем переменную state
        lastTurn = micros();
      }
      if (state == 0 && pinAValue && !pinBValue || state == -2 && !pinAValue && pinBValue) {
        state -= 1; // Если выполняется условие, наращиваем в минус переменную state
        lastTurn = micros();
      }
      setCount(state); // Проверяем не было ли полного шага из 4 изменений сигналов (2 импульсов)
      sei();
     
      if (pinAValue && pinBValue && state != 0) state = 0; // Если что-то пошло не так, возвращаем статус в исходное состояние
    }

    void setCount(int state) {          // Устанавливаем значение счетчика
      if (state == 4 || state == -4) {  // Если переменная state приняла заданное значение приращения
        count += (int)(state / 4);      // Увеличиваем/уменьшаем счетчик
        lastTurn = micros();            // Запоминаем последнее изменение
      }
    }
    Спасибо заранее за помощь))
     
  2. parovoZZ

    parovoZZ Гуру

    С пинами замута сто пудофф
     
  3. TebEnkov2222

    TebEnkov2222 Нерд

    Все бы ничего.. НО я половину пинов перепробовал... Кто нибудь знает, как можно еще подключить этот энкодер?? Библиотека, или код другой, главное что бы работало..
     
  4. ostrov

    ostrov Гуру

    attachInterrupt для ЕSP работает?
     
  5. DIYMan

    DIYMan Гуру

    Работает (http://esp8266.github.io/Arduino/versions/2.1.0-rc2/doc/reference.html):
    Другое дело, что в документации к attachInterrupt недвусмысленно показан ПРАВИЛЬНЫЙ вариант использования:
    Код (C++):
    attachInterrupt( digitalPinToInterrupt(PIN_NUMBER), func, MODE );
    В то время как у ТС:
    Код (C++):
    attachInterrupt(0,...
    attachInterrupt(1,...
    Оно, конечно, работать-то на Uno будет, однако - никто не гарантирует, что в поддержке других плат под Wiring прерывание с номером 0 будет привязано к пину 2, а с номером 1 - к пину 3 ;)

    Для ТС: читаем тут - https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

    Там, в частности, сказано:
    Так что стоит попробовать таки поправить код.
     
  6. TebEnkov2222

    TebEnkov2222 Нерд

    Ухты!! Просвятили прям!! Попробую)))
     
  7. TebEnkov2222

    TebEnkov2222 Нерд

    Мне то есть нужно просто поставить эти две строчки заместо тех?

    attachInterrupt(digitalPinToInterrupt(pinA), A, CHANGE); // Настраиваем обработчик прерываний по изменению сигнала
    attachInterrupt(digitalPinToInterrupt(pinB), B, CHANGE); // Настраиваем обработчик прерываний по изменению сигнала
     
  8. DIYMan

    DIYMan Гуру

  9. TebEnkov2222

    TebEnkov2222 Нерд

    Че то как то ничего не поменялось..
     
  10. TebEnkov2222

    TebEnkov2222 Нерд

    Я в void loop вызывал функции A(); и B();... Все равно не работает.. Или это излишне?
     
  11. TebEnkov2222

    TebEnkov2222 Нерд

    Попробую конечно же на уне сделать.. Если будет работать, то я тогда уже не знаю, что делать..
     
  12. DIYMan

    DIYMan Гуру

    Надо смотреть, что с ESP происходит. Строго говоря, там внутри ещё стек Wi-Fi чухается, поэтому надо быть ооочень осторожным со всякими cli(), например. Я бы для начала проверил - не зависает ли ESP вообще ;) Например, вставил бы моргание светодиодом, и смотрел. Ну а далее - в зависимости от результатов.
     
  13. parovoZZ

    parovoZZ Гуру

    ESP зависнуть не может - её через 8 секунд вачдог сбросит.
     
  14. Mitrandir

    Mitrandir Гуру

    ну и что, сбросит, она опять зависнет после сброса и так по кругу
     
  15. DIYMan

    DIYMan Гуру

    Ага, ага, и вообще мир так устроен, что всё вокруг - чистый изумруд. Если бы оно не висло иногда наглухо - не было бы и потребности контролировать это дело.
     
  16. parovoZZ

    parovoZZ Гуру

    Да, ты прав.
    Надо дебажить.
     
  17. TebEnkov2222

    TebEnkov2222 Нерд

    Господа.. Короче все работает, кроме энкодера.. attachInterrupt работает великолепно.. Ноо, вот энкодер не работает...
     
  18. TebEnkov2222

    TebEnkov2222 Нерд

    ничего не глючит, так как я ставил олед экран, с гифкой.. Все хорошо работало...
     
  19. TebEnkov2222

    TebEnkov2222 Нерд

    И еще, я заметил, что когда начинаешь крутить энкодер, есп перезагружается...
     
  20. Mitrandir

    Mitrandir Гуру

    Можно схему?