Добрый день! Пытаюсь подключить энкодер по статье: https://bigdanzblog.wordpress.com/2014/08/16/using-a-ky040-rotary-encoder-with-arduino/ Заливаю код на УНО- все работает, подключаю к НАНО с тем же кодом- начинает сильно глючить (особенно кнопка). В чем может быть причина? Спасибо! Код (немного измененный): Код (C++): volatile boolean TurnDetected; volatile boolean up; const int PinCLK=2; // Used for generating interrupts using CLK signal const int PinSW=3; // Used for the push button switch const int PinDT=4; // Used for reading DT signal void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK if (digitalRead(PinCLK)) up = digitalRead(PinDT); else up = !digitalRead(PinDT); TurnDetected = true; } void setup () { pinMode(PinCLK,INPUT); pinMode(PinDT,INPUT); pinMode(PinSW,INPUT); attachInterrupt (0,isr,FALLING); // interrupt 0 is always connected to pin 2 on Arduino UNO Serial.begin (9600); Serial.println("Start"); } void loop () { static long virtualPosition=0; // without STATIC it does not count correctly!!! if (!digitalRead(PinSW)&&virtualPosition) { // check if pushbutton is pressed virtualPosition=0; // if YES, then reset counter to ZERO Serial.print ("Reset = "); // Using the word RESET instead of COUNT here to find out a buggy encoder Serial.println (virtualPosition); } if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected Serial.print ("Count = "); Serial.println (virtualPosition); } }
Да, конечно же при правильном подключении к пинам 2, 3, 4 все работает. Я на самом деле пытался подключить PinSW к А7 и там уже была проблема. но я ее исправил. Спасибо, тема закрыта.
Я бы не сказал, что тема закрыта. Срабатывание прерывания по спаду ведет к пропуску одного поворотного "клика" колеса прокрутки. Посему прерывание должно срабатывать на изменение уровня, т.е. attachInterrupt (0,isr,CHANGE); Но у меня проблема с таким энкодером, в одну сторону вращение без ошибок, а в другую на определенном месте происходит "шаг назад", один или два раза.
Промой спиртом. У вас наверно флюс во внутрь попал.Вот контакт и пропадает. Китайцы иногда шлют отбраковку по нижней цене.
Разобрал энкодер, промыл спиртом, смазал SW-92SA смазкой для пластиковых механизмов. Результат - 0. Думаю, что должно быть решение на программном уровне (аля дребезг контактов). Пока проблему решил (шаг назад не наблюдаю) установкой задержки с числом 10 перед каждым чтением с пина даты. Главное, что подобное наблюдаю и на китайских поделках (например - RK8512), бывает что ошибка не зависит от направления вращения.
Ну мой вариант .Полный скетч здесь.https://yadi.sk/d/aeYxE17v3Dhusf А головной файл Спойлер: Головной файл Код (C++): /* class_do_Encoder_KY_040.ino https://yadi.sk/d/aeYxE17v3Dhusf #1 энкодер CLK->2 (CLK_PIN) DT->3 (DT_PIN) SW->4 (SW_PIN) Принцип кода:В сериал отправляется действие на энкодере. */ //#1 энкодер #include "Cl_do_Encoder_KY_040.h" const byte CLK_pin = 2; const byte DT_pin = 3; const byte SW_pin = 4; Cl_do_Encoder_KY_040 Encoder; // ( CLK,DT,SW )создать энкодер на пинах 2,3,4 void func_SW(void) { Serial.println("Press SW"); } void func_plus(void) { Serial.println("Turn +"); } void func_minus(void) { Serial.println("Turn -"); } void setup() { Serial.begin(9600); //#1 энкодер Encoder.setup(CLK_pin, DT_pin, SW_pin); } void loop() { //#1 энкодер Encoder.loop(& func_SW , & func_plus, & func_minus ); }
Тут проблема глубже - а именно в качестве энкодера. Эти имеют конструктивный дефект - при вращении в одну сторону проскакивают импульсы "обратного" вращения. Лечится 2 способами - покупкой качественного энкодера (ну, тут жаба резко против - они на порядок дороже) или программно - учитываем направление предыдущего вращения - если совпадает - Ок, если противоположное - ничего не делаем, ждем еще одного отсчета - дальше наверное все понятно. Так с минимальными затратами все хорошо работает, без сбоев.