Вопрос по ESP8266 и энкодеру
- Войдите на сайт для отправки комментариев
Я только постигаю ардуино и esp8266, поэтому не кидайтесь тапками(
В чем суть вопроса:
Имею энкодер https://belchip.by/product/?selected_product=42210
И плату NodeMCU v3.0.
Подключил к пенам D4,D5,D6 у esp8266
Нашел статью https://habr.com/ru/post/586576/
Переделал код, добавив прерывания в соответствии с esp, заменив
PCICR = 0b00000010; // PCICR |= (1<<PCIE1); Включить прерывание PCINT1 PCMSK1 = 0b00001110; // Разрешить прерывание для A1, A2, A3
на
attachInterrupt(digitalPinToInterrupt(D5), Qqy, CHANGE); attachInterrupt(digitalPinToInterrupt(D6), Qqy, CHANGE); attachInterrupt(digitalPinToInterrupt(D7), Qqy, CHANGE);
В "ICACHE_RAM_ATTR void Qqy() {" находится обработчик прерываний из статьи, однако ардуино Иде ругается на
uint8_t comb = bitRead(PINC, 3) << 2 | bitRead( PINC, 2)<<1 | bitRead(PINC, 1);
а именно на PINC
Я так понял, что считываются значения регистров для панов gpio
Однако...при замене bitRead на digitalRead с соответствующим пином получаю на выходе пусть и результат, но бессмысленный до крайности
Помогите заставить ЭТО работать, пожаааааалуйста
Регистро-ориентированный код для AVR на ESP работать не будет.
Читайте пины через digitalRead, потом складывайте бинарно.
А можно более развернутый ответ?)
А зачем 3(три) пина? Если сопротивление больше килоОма, то один край на + 3.3 второй на - и со среднего снимаем сигнал.
На хабр меня не пускает. Опишите для чего необходимо устройство.
+ 3.3 второй на - и
ловим КЗ
Делаю регулируемый блок питания, энкодер необходим для точной настройки выходного напряжения(один щелчок это + или - 0.1В на выходе) + реализация долгого нажатия и поворота с нажатием
знаю, что кнопки было бы проще использовать, но размер устройства не позволяет)
Меня всё ещё не пускает на хабр. Если вольтметр НЕ завязан на дуину - всё делается легко.
Меня всё ещё не пускает на хабр. Если вольтметр НЕ завязан на дуину - всё делается легко.
я понимаю, мне всего то и нужно отлавливать, что с энкодером происходит (количество щелчков, направление и прочее)
Три пина. Это лево право и нажатие?
Три пина. Это лево право и нажатие?
именно
выходы А и Б от энкодера и кнопка в энкодере
if (A == 0 && B == 1) { I++; B = 0; } if (A == 1 && B == 0) { I--; A = 0; }Логика простая. Чего по кнопке?
if (A == 0 && B == 1) { I++; B = 0; } if (A == 1 && B == 0) { I--; A = 0; }Логика простая. Чего по кнопке?
Т.е. при повороте на одном из выходов в зависимости от направления возникает прямоугольный импульс?
в таком случае вопрос про подключение (куда питание пихать, в статье что я кидал он просто подключён к земле и трём пинам) и как считать время для длинного нажатия
По прерываниям у Гайвера хорошо и понятно написано. Для начинающих.
По прерываниям у Гайвера хорошо и понятно написано. Для начинающих.
в прерывания лез уже, работает, но криво
конкретно в статье на хабре что я кидал проблема только в обработке сигнала с энкодера (обработка была по регистрам пинов, с digital read не пашет
сейчас приведу код программы
/* При публичном размещении кода ссылка на первоисточник обязательна. */ #define btn_long_push 1000 // Длительность долинного нажатия кнопки volatile uint8_t lastcomb=7, enc_state, btn_push=0; volatile int enc_rotation=0, btn_enc_rotate=0; volatile boolean btn_press=0; volatile uint32_t timer; //******************************** void setup() { pinMode(A1,INPUT_PULLUP); // ENC-A pinMode(A2,INPUT_PULLUP); // ENC-B pinMode(A3,INPUT_PULLUP); // BUTTON PCICR = 0b00000010; // PCICR |= (1<<PCIE1); Включить прерывание PCINT1 PCMSK1 = 0b00001110; // Разрешить прерывание для A1, A2, A3 Serial.begin(115200); } //**************************************** void loop() { switch (enc_state) { case 1: { Serial.print("Вращение без нажатия "); Serial.println(enc_rotation); } break; case 2: { Serial.print("Вращение с нажатием "); Serial.println(btn_enc_rotate); } break; case 3: Serial.println("Нажатие кнопки "); break; case 4: Serial.println("Длинное нажатие кнопки "); break; } enc_state=0; //обнуляем статус энкодера } //**************************************** ISR (PCINT1_vect) //Обработчик прерывания от пинов A1, A2, A3 { uint8_t comb = bitRead(PINC, 3) << 2 | bitRead( PINC, 2)<<1 | bitRead(PINC, 1); //считываем состояние пинов энкодера и кнопки if (comb == 3 && lastcomb == 7) btn_press=1; //Если было нажатие кнопки, то меняем статус if (comb == 4) //Если было промежуточное положение энкодера, то проверяем его предыдущее состояние { if (lastcomb == 5) --enc_rotation; //вращение по часовой стрелке if (lastcomb == 6) ++enc_rotation; //вращение против часовой enc_state=1; // был поворот энкодера btn_enc_rotate=0; //обнулить показания вращения с нажатием } if (comb == 0) //Если было промежуточное положение энкодера и нажатие, то проверяем его предыдущее состояние { if (lastcomb == 1) --btn_enc_rotate; //вращение по часовой стрелке if (lastcomb == 2) ++btn_enc_rotate; //вращение против частовой enc_state=2; // был поворот энкодера с нажатием enc_rotation=0; //обнулить показания вращения без нажатия btn_press=0; //обнулить показания кнопки } if (comb == 7 && lastcomb == 3 && btn_press) //Если было отпускание кнопки, то проверяем ее предыдущее состояние { if (millis() - timer > btn_long_push) // проверяем сколько прошло миллисекунд { enc_state=4; // было длинное нажатие } else { enc_state=3; // было нажатие } btn_press=0; //обнулить статус кнопки } timer = millis(); //сброс таймера lastcomb = comb; //сохраняем текущее состояние энкодера }ИУ этого энкодера есть общая нога на которую замыкются А и Б. Эту ногу на +3,3. Выходы через резистор 1к-10к на корпус. Кнопку аналогично.
Прерывание возвращает A или B единицу.
Переменную I на параметр ШИМ. В дуине это значение не должно превышать 255, и не должно быть ниже нуля.
В дуине прерывания пишутся по другому. Ищите примеры у гугля.
И ищите именно под ESP.
В дуине прерывания пишутся по другому. Ищите примеры у гугля.
И ищите именно под ESP.
дк переписать прерывания я переписал, вопрос в строчке, где считываются состояния входов
прерывания работают
но ведут себя архинеадекватно(т.е. результат на выходе в мониторе порта есть, но не отвечает реальности) и мой вопрос вопрос заключался в том, как правильно считывать состояния входов без этого вонючего bitRead(), ибо если заменить его на digitalRead получается неадекват
Проблему решил, все решилось корректным подключением энкодера, переписыванием прерываний под esp8266,изменением bitRead на digitalRead и программным устранением дребезга, всем спасибо(если кому надо-выложу код)
А можно код то глянуть?