Господа.. Добрый вечер.. Пробелма с подключением энкодером на еспиху.. На уне вся программа великолепно работает.. А на есп (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(); // Запоминаем последнее изменение } } Спасибо заранее за помощь))
Все бы ничего.. НО я половину пинов перепробовал... Кто нибудь знает, как можно еще подключить этот энкодер?? Библиотека, или код другой, главное что бы работало..
Работает (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/ Там, в частности, сказано: Так что стоит попробовать таки поправить код.
Мне то есть нужно просто поставить эти две строчки заместо тех? attachInterrupt(digitalPinToInterrupt(pinA), A, CHANGE); // Настраиваем обработчик прерываний по изменению сигнала attachInterrupt(digitalPinToInterrupt(pinB), B, CHANGE); // Настраиваем обработчик прерываний по изменению сигнала
Надо смотреть, что с ESP происходит. Строго говоря, там внутри ещё стек Wi-Fi чухается, поэтому надо быть ооочень осторожным со всякими cli(), например. Я бы для начала проверил - не зависает ли ESP вообще Например, вставил бы моргание светодиодом, и смотрел. Ну а далее - в зависимости от результатов.
Ага, ага, и вообще мир так устроен, что всё вокруг - чистый изумруд. Если бы оно не висло иногда наглухо - не было бы и потребности контролировать это дело.
Господа.. Короче все работает, кроме энкодера.. attachInterrupt работает великолепно.. Ноо, вот энкодер не работает...