спам-выход поворотного энкодера
Я создаю свой второй проект на Arduino. Я новичок во всем этом, поэтому мне наверняка понадобится помощь, чтобы все исправить.
Я пытаюсь сделать контроллер для ПК-версии аркадной игры. Он использует два поворотных энкодера, о чем я никогда не слышал, прежде чем приступить к этому проекту.
На github я нашел код, который отлично работает в моем случае, но в этом коде поворотные энкодеры перемещают мышь. что-то, что, к сожалению, не работает для управления играми (я пробовал)
поэтому я попытался изменить их, и теперь они выдают текст, как будто они мне нужны, но когда я их поворачиваю, вместо того, чтобы получить необходимый результат
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
я получаю нечто большее в духе
babababababababababababababababbabb
например, если я поворачиваю ручку в обе стороны одновременно, когда я просто поворачиваю ее в одну сторону.
вот код, над которым я работаю
/*
* By Daniel Tam ([email protected])
============ NOTES ============
This will create a SDVX Controller using an Arduino Leonardo.
You will hook up one wire of the button to the Arduino pin and the other to Arduino's ground. When pushed, the button should go to ground.
You will need to download the encoder library and use it in your project for this to work (ww.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino)
===============================
*/
// кнопки
#include <Mouse.h>
#include <Keyboard.h>
#define BT_A 2
#define BT_B 3
#define BT_C 4
#define BT_D 5
#define FX_L 6
#define FX_R 7
#define BT_ST 8
// кодеры
#include <Encoder.h>
Encoder enc1(15, 14);
Encoder enc2(16, 10);
float knob1 = 0;
float knob2 = 0;
float old_knob1 = 0;
float old_knob2 = 0;
void setup()
{
// устанавливаем контакты для чтения и выводим высокий уровень
// когда на выводах низкий уровень, мы знаем, что кнопки заземлились (то есть, нажаты вниз)
pinMode(BT_A, INPUT);
pinMode(BT_B, INPUT);
pinMode(BT_C, INPUT);
pinMode(BT_D, INPUT);
pinMode(FX_L, INPUT);
pinMode(FX_R, INPUT);
pinMode(BT_ST, INPUT);
digitalWrite(BT_A, HIGH);
digitalWrite(BT_B, HIGH);
digitalWrite(BT_C, HIGH);
digitalWrite(BT_D, HIGH);
digitalWrite(FX_L, HIGH);
digitalWrite(FX_R, HIGH);
digitalWrite(BT_ST, HIGH);
Mouse.begin();
Keyboard.begin();
}
void loop()
{
// читаем кодеры
knob1 = (float)(enc1.read());
knob2 = (float)enc2.read();
if(knob1 != old_knob1)
{
// если есть разница в движении энкодера по сравнению с последним проходом, переместите мышь
if(knob1 < old_knob1)
{
// Mouse.move(0, -5);
Keyboard.press('a');
delay(100);
Keyboard.release('a');
}
else
{
// Mouse.move(0, 5);
Keyboard.press('b');
delay(100);
Keyboard.release('b');
}
// мы считаем разницу в энкодерах, но не должны превышать предел int ардуино
if(knob1 < -255)
{
enc1.write(0);
old_knob1 = 0;
}
else if (knob1 > 255)
{
enc1.write(0);
old_knob1 = 0;
}
else
{
old_knob1 = knob1;
}
}
if(knob2 != old_knob2)
{
if(knob2 > old_knob2)
{
// Mouse.move(-5, 0);
Keyboard.press('c');
}
else
{
// Mouse.move(5, 0);
Keyboard.press('d');
}
if(knob2 < -255)
{
enc2.write(0);
old_knob2 = 0;
}
else if(knob2 > 255)
{
enc2.write(0);
old_knob2 = 0;
}
else
{
old_knob2 = knob2;
}
}
// читаем кнопки для низкого уровня, если он низкий, выводим нажатие клавиатуры
if(digitalRead(BT_A) == LOW)
{
Keyboard.press('f');
}
else
{
Keyboard.release('f');
}
if(digitalRead(BT_B) == LOW)
{
Keyboard.press('b');
}
else
{
Keyboard.release('b');
}
if(digitalRead(BT_C) == LOW)
{
Keyboard.press('c');
}
else
{
Keyboard.release('c');
}
if(digitalRead(BT_D) == LOW)
{
Keyboard.press('d');
}
else
{
Keyboard.release('d');
}
if(digitalRead(FX_L) == LOW)
{
Keyboard.press('z');
}
else
{
Keyboard.release('z');
}
if(digitalRead(FX_R) == LOW)
{
Keyboard.press('x');
}
else
{
Keyboard.release('x');
}
if(digitalRead(BT_ST) == LOW)
{
Keyboard.press('n');
}
else
{
Keyboard.release('n');
}
}
@MintCollie, 👍0
1 ответ
Лучший ответ:
Вы не используете рекомендованные контакты для подключения кодеров. По этой причине библиотека не использует прерывания, но зависит от того, будете ли вы вызывать encX.read()
достаточно часто, чтобы не пропустить никаких изменений. Это, в сочетании с задержкой в 100 мс в вашем коде, почти гарантирует, что вы пропустите некоторые изменения, заставляя библиотеку думать, что вы вращаетесь наоборот.
Измените контакты на 0, 1, 2, 3 (или хотя бы на один из них для каждого кодера).
В противном случае уменьшите задержку, например, до 1 мс. Я не смог выяснить, необходима ли эта задержка и какой продолжительности она должна быть, поэтому вам придется немного поэкспериментировать и посмотреть, что сработает.
Наконец; почему вы используете float
для хранения позиции? Вместо этого попробуйте использовать long
, поскольку именно этот тип возвращает enc.read().
- Вращающийся энкодер, использующий прерывание
- Arduino Pro Micro, получить данные с контакта Tx?
- Считывание нескольких поворотных энкодеров
- Использование поворотных энкодеров с прерываниями смены контактов
- Отправка мультимедийных клавиш клавиатуры с помощью библиотеки клавиатур
- Распиновка аналога Arduino Pro Micro
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
- Не удается загрузить скетч - avrdude: butterfly_recv(): programmer is not responding
была ли первая часть, которую отрезали?, @MintCollie
Извините, мне пришлось изменить порядок. Ничего не пропало., @Gerben
изменение контактов на 0,1, кажется, делает именно то, что мне нужно! У меня была задержка в качестве теста, так как я все еще учусь, а что касается поплавков, это часть исходного кода ребят, так что я не слишком уверен., @MintCollie
на самом деле я, кажется, периодически получаю старый результат, иногда кажется, что это работает., @MintCollie
Кажется, что большинство моих проблем с nvm связаны с шатким макетом, на котором соединяются контакты или что-то в этом роде., @MintCollie