Возможно ли библиотеку GyverButton подружить со сдвиговым регистром?

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
Собственно, вопрос в заголовке.
Необходимо к ардуино подключить пару кнопок и пару переключателей посредством сдвигового регистра на 8 бит.
Естественно, им понадобится защита от дребезга.
В программировании не силен, поэтому хотелось бы получить совета, как функцию антидребезга из этой библиотеки применить к данным, получаемым из сдвигового регистра.
Спасибо.
 

poty

★★★★★★✩
19 Фев 2020
2,988
895
Я, конечно, всё понимаю, но типичный сдвиговый регистр работает не на вход, а на выход. Т.е., выдать на энное количество светодиодов сигнал или превратить последовательный код в параллельный - пожалуйста, но не обратно. Есть и двунаправленные регистры, но их стоимость Вас опечалит.
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,282
945
58
Марий-Эл
@poty, Есть сдвиговые регистры преобразующие последовательный код в параллельный. - CD 4094
Есть регистры преобразующие параллельный код в последовательный. Чистые не помню. Унивесальных дохрена. Так же их можно сделать на мультиплексорах
Есть сдвиговый регистр, который умеет и то и другое К155ИР13. CD4034

Но проще всего использовать универсальный. Их дохрена разных.
 
Изменено:

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@poty,
74HC595 выходной, а у меня 74HC165 - он входной.

@Геннадий П,
Это будет самодельное подобие джойстика для компьютера на основе ардуино. На входах сдвигового регистра находятся пара кнопок и пара выключателей. Значение с регистра упаковывается в один байт, а там уже побитно растаскивается и эмулируется собственно джойстик.
Нужна банально защита от дребезга - он будет что у кнопок, что у переключателей.

Я сегодня бегло просмотрел библиотеку GyverButton и задался вопросом - нельзя ли как-то ей скормить не "кнопка на таком-то пине", а "бит номер N из такого-то байта-переменной"?

@Эдуард Анисимов, Я выше как раз отписался - 74HC165 у меня. По крайней мере, что в рунете он называется сдвиговым регистром, что в англоязычной части shift register.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,192
1,281
Москва
Не знаю как новая версия библиотеки, но в старой каждая кнопка обрабатывалась через tick и была возможность работы с несколькими кнопками на аналоговом входе:
C++:
  btnL.tick(analog <= 1023 && analog > 950);
  btnR.tick(analog <= 850 && analog > 650);
  btnSet.tick(analog <= 300 && analog > 100);
И ничего не мешает делать то же самое с битами:
C++:
  btnL.tick(bits & 1);
  btnR.tick(bits & 2);
  btnSet.tick(bits & 4);
Ну и цена в не дешевой амперке 80р - не самая большая. По ссылке есть и описание функции shiftin
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@Старик Похабыч,
Вот за подсказку с переделыванием функции большое спасибо, буду завтра изучать.
В России что-то покупать - себе не уважать, а ещё кормить дармоедов.
На Али десяток можно купить подешевке. Где, собственно, и раздобыл их.

@kDn,Увы, нет, не хватает.

UPD Кажется решилось, расспросил аж самого нашего Гайвера, можно использовать библиотеку EncButton, которая поддерживает виртуальные кнопки и которой как раз и можно кормить нужные входные данные.
Шо ж, будем тестить...
 
Изменено:

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
Народ, вопрос решился - задействовал библиотеку ShiftIn (так и называется на гитхабе) и её функционал (считывание входа регистра) скормил библиотеке EncButton, создав виртуальную кнопку. Всё работает просто шикарно.

Правда, есть одно но:

C++:
#include <ShiftIn.h>
#include <EncButton.h>

// Init ShiftIn instance with a single chip
ShiftIn<1> shift;

EncButton<EB_TICK, VIRT_BTN> enc;
EncButton<EB_TICK, VIRT_BTN> enc2;
int counter = 0;

void setup() {
  Serial.begin(9600);
  // declare pins: pLoadPin, clockEnablePin, dataPin, clockPin
  shift.begin(2, 3, 4, 5);

  Serial.println("Alles ist bereit");
}



void loop()
{
  if (shift.update())
  { // read in all values. returns true if any button has changed
    enc.tick(shift.state(0));
    enc2.tick(shift.state(1));
    
  }

  if (enc.isClick())
  {
    counter++ ;
    Serial.println(counter);
  }
 
  if (enc2.isClick())
  {
    counter--;
    Serial.println(counter);
  }
  //delay(1);
}
Посмотрите на строки 23-28. Гайверовский тик приходится заворачивать в условие из shift.Update - функционал той библиотеки для чтения регистра, который возвращает true, если состояние кнопок обновилось.
Если тик опрашивать в основном лупе, то ничего не работает, хоть убейте...
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
Если тик опрашивать в основном лупе, то ничего не работает, хоть убейте...
Ну так, а что вас удивляет? shift.update() фактически такой же тик, который обновляет значения shift.state(). Если его не вызывать, то и значения стейтов менятся не будут.
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@kostyamat,
Я в программировании не силён вот прямо вообще, увы...

То есть, если я правильно понял, можно shift.update вынести из условия if и просто вызывать в начале цикла?

shift.update
button1.tick(shift.state(0));
button2.tick(shift.state(1));

так?

Я просто вообще не думал, что shift.update именно читает и обновляет показания. Думал, что просто выдает true если что-то изменилось.
 

bort707

★★★★★★✩
21 Сен 2020
2,898
862
Чем вас конструкция с if не устраивает? Это правильная конструкция. Если состояние регистра не изменилось - и тики вызывать незачем.
 
  • Лойс +1
Реакции: kostyamat

bort707

★★★★★★✩
21 Сен 2020
2,898
862
@bort707,
Мне удобнее без if, чтобы каждый раз опрашивалось.
Чем удобнее? Не надо загружать МК лишней работой, ее и так в скетчах новичков навалом.

Да и странное заявление для человека, который "совсем не программист". Хорошее правило - не понимаешь - не трогай.
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@bort707,

Основной цикл - отправка показаний в компьютер (это джойстик для компьютера) будет жестко ограничен в 20мс, то бишь лишняя работа в виде обсчета котроллер не особо нагрузит, я полагаю. Или ошибаюсь?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,192
1,281
Москва
Начнем с того, что вот тут:
C++:
if (shift.update())
  { // read in all values. returns true if any button has changed
    enc.tick(shift.state(0));
    enc2.tick(shift.state(1));   
  }
shift.update() выполняется в каждом проходе цикла loop. А тики энкодеров только в том случае , если функция shift.update вернет ИСТИНУ. В каких случаях она ее возвращает надо смотреть в библиотеке.Логично было бы предположить, что только в том случае когда было изменение по состоянию пинов. А раз так, то такая конструкция самая удачная: сдвиговый опрашивается каждый раз, но энкодеры обрабатываются только по изменению.
Да, и судя по комменту так и есть, только при изменении.
Не думаю, что нужно ограничивать тут как то все жестко.
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@Старик Похабыч,
Но я все равно так и не понял - почему если вынести тики кнопок из под условия, то ничего не работает?

Или это особенность компилятора? - если цикл if не содержит полезного кода, то игнорируется?

Вот из описания библиотеки:

This function (or the update function) should be called each frame exactly once. It will read in all values from the shift registers and it will return the new state.

ShiftType read()
This function is basically the same as the read function, but it will return true if some button has changed its state and false otherwise

boolean update()

есть смысл вызывать read вне цикла вместо update?
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,192
1,281
Москва
Будет работать. Но зачем ?
Вот у вас есть в почтовом ящике отверстие, что бы видеть есть ли почта или нет. Но вы видите, что почты нет и все равно будите открывать ящик? Такая конструкция будет экономить процессорное время. Сейчас оно вам может и не надо , но в будущем может очень пригодиться.
 

bort707

★★★★★★✩
21 Сен 2020
2,898
862
Избыточное цитирование
@Старик Похабыч,
Но я все равно так и не понял - почему если вынести тики кнопок из под условия, то ничего не работает?

Или это особенность компилятора? - если цикл if не содержит полезного кода, то игнорируется?
покажите код, как вы "из под условия выносите", похоже вы там чего-то накрутили
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@bort707,

Это из примера выше, как работает нормально.

if (shift.update())
{ // read in all values. returns true if any button has changed
enc.tick(shift.state(0));
enc2.tick(shift.state(1));

}

А вот так пробовал - так не работает:

if (shift.update())
{ // read in all values. returns true if any button has changed


}

enc.tick(shift.state(0));
enc2.tick(shift.state(1)); - вот эти оба тика были в самом loop без дополнительных вложений.


Хочу ещё попробовать вот так и посмотреть, что будет:

loop

и далее друг за дружкой
shift.update

enc.tick
enc2.tick
 

bort707

★★★★★★✩
21 Сен 2020
2,898
862
Ну и ну...
Скорее всего, во втором случае оптимизатор выкидывает весь if, как бессмысленный. И, на мой взгляд, это правильное слово для этого кода. Вы сами-то можете обьяснить, зачем вы этот бред написали...?
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@bort707,

Я всего-то пытался объединить два exampl'а из двух библиотек, чтобы оно работало, а вышла какая-то ерунда.
 

bort707

★★★★★★✩
21 Сен 2020
2,898
862
А в чем была идея выноса тиков из условия? Зачем вы стали это переписывать?
 

derungebundener

✩✩✩✩✩✩✩
18 Июл 2020
117
3
@bort707, Просто у меня была "хотелка" - чтобы опрос был не при изменении состояния кнопок, а постоянно.
Но сейчас меня переубедил народ - оставлю именно при изменении.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,192
1,281
Москва
Кстати странно, что при вынесенных тиках не работает.
Попробуйте такую конструкцию:
C++:
shift.update());
enc.tick(shift.state(0));
enc2.tick(shift.state(1));