Редактирование скетча для регулятора громкости на Attiny85

М'айк_лжец

✩✩✩✩✩✩✩
14 Июн 2021
4
0
Доброго времени суток господа! На Attiny85 был собран регулятор громкости для Win10. Скетч взят из библиотеки TrinketHidCombo. Есть пара вопросов по редактированию данного скетча.
1) Подскажите, какая строка изменяет шаг изменения уровня громкости? Сейчас при повороте энкодера на один угол, громкость изменяется на два пункта, а не на один.
2) Возможно ли сделать так, чтобы при резком повороте энкодера шаг изменения уровня громкости увеличивался (громкость увеличивалась/уменьшалась по экспоненте)?
3) Не работает отключение/включение громкости при нажатии на кнопку энкодера. При этом светодиод на плате Attiny гаснет при нажатии.
// see tutorial at http://learn.adafruit.com/trinket-usb-volume-knob

#include "TrinketHidCombo.h"

#define PIN_ENCODER_A 0
#define PIN_ENCODER_B 2
#define TRINKET_PINx PINB
#define PIN_ENCODER_SWITCH 1

static uint8_t enc_prev_pos = 0;
static uint8_t enc_flags = 0;
static char sw_was_pressed = 0;

void setup()
{
// set pins as input with internal pull-up resistors enabled
pinMode(PIN_ENCODER_A, INPUT);
pinMode(PIN_ENCODER_B, INPUT);
digitalWrite(PIN_ENCODER_A, HIGH);
digitalWrite(PIN_ENCODER_B, HIGH);

pinMode(PIN_ENCODER_SWITCH, INPUT);
// the switch is active-high, not active-low
// since it shares the pin with Trinket's built-in LED
// the LED acts as a pull-down resistor
digitalWrite(PIN_ENCODER_SWITCH, LOW);

TrinketHidCombo.begin(); // start the USB device engine and enumerate

// get an initial reading on the encoder pins
if (digitalRead(PIN_ENCODER_A) == LOW) {
enc_prev_pos |= (1 << 0);
}
if (digitalRead(PIN_ENCODER_B) == LOW) {
enc_prev_pos |= (1 << 1);
}
}

void loop()
{
int8_t enc_action = 0; // 1 or -1 if moved, sign is direction

// note: for better performance, the code will now use
// direct port access techniques
// http://www.arduino.cc/en/Reference/PortManipulation
uint8_t enc_cur_pos = 0;
// read in the encoder state first
if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_A)) {
enc_cur_pos |= (1 << 0);
}
if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_B)) {
enc_cur_pos |= (1 << 1);
}

// if any rotation at all
if (enc_cur_pos != enc_prev_pos)
{
if (enc_prev_pos == 0x00)
{
// this is the first edge
if (enc_cur_pos == 0x01) {
enc_flags |= (1 << 0);
}
else if (enc_cur_pos == 0x02) {
enc_flags |= (1 << 1);
}
}

if (enc_cur_pos == 0x03)
{
// this is when the encoder is in the middle of a "step"
enc_flags |= (1 << 4);
}
else if (enc_cur_pos == 0x00)
{
// this is the final edge
if (enc_prev_pos == 0x02) {
enc_flags |= (1 << 2);
}
else if (enc_prev_pos == 0x01) {
enc_flags |= (1 << 3);
}

// check the first and last edge
// or maybe one edge is missing, if missing then require the middle state
// this will reject bounces and false movements
if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) {
enc_action = 1;
}
else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) {
enc_action = 1;
}
else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) {
enc_action = -1;
}
else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) {
enc_action = -1;
}

enc_flags = 0; // reset for next time
}
}

enc_prev_pos = enc_cur_pos;

if (enc_action > 0) {
TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_UP);
}
else if (enc_action < 0) {
TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_DOWN);
}

// remember that the switch is active-high
if (bit_is_set(TRINKET_PINx, PIN_ENCODER_SWITCH))
{
if (sw_was_pressed == 0) // only on initial press, so the keystroke is not repeated while the button is held down
{
TrinketHidCombo.pressMultimediaKey(MMKEY_MUTE);
delay(5); // debounce delay
}
sw_was_pressed = 1;
}
else
{
if (sw_was_pressed != 0) {
delay(5); // debounce delay
}
sw_was_pressed = 0;
}

TrinketHidCombo.poll(); // check if USB needs anything done
}
Схема подключения.jpg
 

bort707

★★★★★★✩
21 Сен 2020
3,066
915
Подскажите, какая строка изменяет шаг изменения уровня громкости? Сейчас при повороте энкодера на один угол, громкость изменяется на два пункта, а не на один.
никакая. В коде четко на один щелчок энкодера кнопка изменения горомкости нажимается один раз. Так что причину изменения сразу на 2 шага ищите не в коде, а где-то еще - например может у вас энкодер на каждый поворот дает два щелчка. а не один
 

kostyamat

★★★★★★✩
29 Окт 2019
1,098
632
Не работает отключение/включение громкости при нажатии на кнопку энкодера. При этом светодиод на плате Attiny гаснет при нажатии.
Гы... Так если вы голый энкодер подключили, а не модуль, на котором резисторы есть, и по этой схеме, то у вас при нажатии на кнопку просто КЗ происходит, поэтому и светодиод гаснет (когда-то погаснет USB, раз и навсегда).
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
634
45
Это в Windows так работает. У меня на клавиатуре изменение громкости тоже энкодером и тоже минимум по 2 меняется.