Мытарства или опять кнопки

Добрый день! Если вопрос где-то обсуждался не закидывайте камнями, не нашел!

Делаю микроскоп для пайки и нашел обЪектив только от vhs камеры, управляется он двумя шаговыми двигателями(фокус и зум).

Пытался сделать управление с помощью потенциометров, но потерпел крах, шум на крайних позициях заставлял сходить с ума движки, а линзы имеют крайние положения, что также сбивало настройки положения. Пробовал и программные и “железные” фильтры ничего не помогло. Далее нашел резиновые кнопки от автомобильного пульта, которые выглядят как стрелки, что очень вписывается в проект, но и тут не обошлось без приключений. Решил подключить их к одному аналоговому пину по приведенной схеме. Но видимо из-за того, что резина замыкающая кнопки меняет свое сопротивление от силы нажатия, получил так-же немного не стабильный результат. Так как использую китайский клон nano для данного проекта и остальные пины мне не нужны решил использовать по цифровому пину для каждой кнопки. В итоге все работает кроме того, что при нажатии на кнопку zoom- удержание проскакивает иногда, а то и вовсе не срабатывает. Провода кнопок припаяны к ардуино, между землей и каждой копкой резистор 10кОм. В порте отработка кнопок отображается нормально, менять пины в программе пробовал. Помогите!!!

01

`#include <Stepper.h>`

`02`

`03` `const` `uint8_t zoomPlusBtn = 4; ` `// пины подключения кнопок`

`04` `const` `uint8_t zoomMinusBtn = 5;`

`05` `const` `uint8_t focusPlusBtn =3;`

`06` `const` `uint8_t focusMinusBtn =2;`

`07`

`08` `const` `uint8_t STEPS = 200;`

`09` `bool` `flag = ` `false` `;`

`10` `uint32_t btnTimer = 0;`

`11`

`12` `Stepper zoom(STEPS, 10, 11, 12, 13);`

`13` `Stepper focus(STEPS, 6, 7, 8, 9);`

`14`

`15` ` `

`16` `void` `setup` `() {`

`17` ` ` `Serial` `.begin(9600);`

`18` `  ` `pinMode(zoomPlusBtn, INPUT);`

`19` `  ` `pinMode(zoomMinusBtn, INPUT);`

`20` `  ` `pinMode(focusPlusBtn, INPUT);`

`21` `  ` `pinMode(focusMinusBtn, INPUT);`

`22` `  ` `zoom.setSpeed(50);`

`23` `  ` `focus.setSpeed(50);`

`24`

`25` `}`

`26`

`27` `void` `loop` `() {`

`28` ` `

`29` `//Serial.println(btnState);`

`30` `bool` `btnState[] = {digitalRead(zoomPlusBtn), digitalRead(zoomMinusBtn), digitalRead(focusPlusBtn), digitalRead(focusMinusBtn)}; ` `//массив для опроса кнопок`

`31` `Serial` `.print(` `"zoom+"` `);  ` `//для отладки`

`32` `Serial` `.println(btnState[0]);`

`33` `Serial` `.print(` `"zoom-"` `);`

`34` `Serial` `.println(btnState[1]);`

`35` `Serial` `.print(` `"focus+"` `);`

`36` `Serial` `.println(btnState[2]);`

`37` `Serial` `.print(` `"focus-"` `);`

`38` `Serial` `.println(btnState[3]);`

`39`

`40` `if` `(btnState[0] && !flag && millis() - btnTimer > 50) { ` `// если кнопка нажата однократно`

`41` `    ` `flag = ` `true` `;`

`42` `    ` `btnTimer = millis();`

`43` `    ` `Serial` `.println(` `"press+"` `);`

`44` `    ` `zoom.step(1); ` `//делаем шаг`

`45` `  ` `}`

`46` `  ` `if` `(btnState[0] && flag && millis() - btnTimer > 200) { ` `// если кнопка удерживается`

`47` `    ` `btnTimer = millis();`

`48` `    ` `Serial` `.println(` `"press hold+"` `);`

`49` `    ` `zoom.step(10);`

`50` `  ` `}`

`51` `  ` `if` `(!btnState[0] && flag && millis() - btnTimer > 200) { ` `//если кнопка отпущена`

`52` `    ` `flag = ` `false` `;`

`53` `    ` `btnTimer = millis();`

`54` `    ` `Serial` `.println(` `"release"` `);`

`55` `  ` `}`

`56`

`57` `//`

`58` `  ` `//`

`59` `  ` `if` `(btnState[1] && !flag && millis() - btnTimer > 50) {`

`60` `    ` `flag = ` `true` `;`

`61` `    ` `btnTimer = millis();`

`62` `    ` `Serial` `.println(` `"press-"` `);`

`63` `    ` `zoom.step(-1);`

`64` `  ` `}`

`65` `  ` `if` `(btnState[1] && flag && millis() - btnTimer > 200) {`

`66` `    ` `btnTimer = millis();`

`67` `    ` `Serial` `.println(` `"press hold-"` `);`

`68` `    ` `zoom.step(-10);`

`69` `  ` `}`

`70` `  ` `if` `(!btnState[1] && flag && millis() - btnTimer > 200) {`

`71` `    ` `flag = ` `false` `;`

`72` `    ` `btnTimer = millis();`

`73` `    ` `Serial` `.println(` `"release"` `);`

`74` `  ` `}`



https://avatars.dzeninfra.ru/get-zen_doc/3472576/pub_5ee6669bcf2e1004e8f015e1_5ee668ad76f3fc727f678f90/scale_2400

Как насчёт энкодеров? На медленном вручении один клик - один шаг. На быстром - 10 шагов. Или наоборот.

С кнопками проблемы, а ты ещё и усложнить хочешь ))) Хотя идея отличная, я за!

ЗЫ: ТС вставь код правильно.

Так код тут еще не вставляли. Пора заводить раздел “Как не надо вставлять код” с подобными перлами.

Энкодеры покупать нужно, делаю из того что под рукой!

Дай ответ по существу)

Богдан, неужто ты сразу не видишь, что вместо кода вставил херню! И тебе об этом уже сказали. А тогда почему не исправил? Какой тебе ещё ответ по существу!

С удовольствием бы исправил, но нет нигде кнопок редактирования, сижу с телефона! А ответ по сути поста!

Какой ответ, если нет вопроса по сути.

Вопрос в том, что почему удержание кнопки работает через раз или вовсе не работает, хотя нажатие записывается в переменную 100%? Поставил строчки с удержанием наверх все заработало норм, добавил управление фокусом и все опять работает через раз , может есть варианты более стабильные, может как-то можно оптимизировать конструкции if

Твои ошметки кода никому непонятны, вот и итог!

#include <Stepper.h>

const uint8_t zoomPlusBtn = 4; // пины подключения кнопок
const uint8_t zoomMinusBtn = 5;
const uint8_t focusPlusBtn =3;
const uint8_t focusMinusBtn =2;

const uint8_t STEPS = 200;
bool flag = false;
uint32_t btnTimer = 0;

Stepper zoom(STEPS, 10, 11, 12, 13);
Stepper focus(STEPS, 6, 7, 8, 9);

 
void setup() {
 Serial.begin(9600);
  pinMode(zoomPlusBtn, INPUT);
  pinMode(zoomMinusBtn, INPUT);
  pinMode(focusPlusBtn, INPUT);
  pinMode(focusMinusBtn, INPUT);
  zoom.setSpeed(50);
  focus.setSpeed(50);

}

void loop() {
 
//Serial.println(btnState);
bool btnState[] = {digitalRead(zoomPlusBtn), digitalRead(zoomMinusBtn), digitalRead(focusPlusBtn), digitalRead(focusMinusBtn)}; //массив для опроса кнопок



  if (btnState[0] && flag && millis() - btnTimer > 200) { // если кнопка zoom+ удерживается
    btnTimer = millis();
    Serial.println("press hold+");
    zoom.step(10);
  }
 
   if (btnState[1] && flag && millis() - btnTimer > 200) { // если кнопка zoom- удерживается
    btnTimer = millis();
    Serial.println("press hold-");
    zoom.step(-10);
  }
  
 if (btnState[2] && flag && millis() - btnTimer > 200) { // если кнопка focus+ удерживается
    btnTimer = millis();
    Serial.println("press hold+");
    focus.step(10);
  }
 
   if (btnState[3] && flag && millis() - btnTimer > 200) { // если кнопка focus- удерживается
    btnTimer = millis();
    Serial.println("press hold-");
    focus.step(-10);
  }
  
  if (btnState[0] && !flag && millis() - btnTimer > 50) { // если кнопка zoom+ нажата однократно
    flag = true;
    btnTimer = millis();
    Serial.println("press+");
    zoom.step(1); //делаем шаг
  } 
  
  if (btnState[1] && !flag && millis() - btnTimer > 50) { // если кнопка zoom- нажата однократно
    flag = true;
    btnTimer = millis();
    Serial.println("press-");
    zoom.step(-1);
  }
  
  if (btnState[2] && !flag && millis() - btnTimer > 50) { // если кнопка focus+ нажата однократно
    flag = true;
    btnTimer = millis();
    Serial.println("press+");
    focus.step(1); //делаем шаг
  } 
  
  if (btnState[3] && !flag && millis() - btnTimer > 50) { // если кнопка focus- нажата однократно
    flag = true;
    btnTimer = millis();
    Serial.println("press-");
    focus.step(-1);
  }
  
  if (!btnState[0] && flag && millis() - btnTimer > 200) { //если кнопка zoom+ отпущена
    flag = false;
    btnTimer = millis();
    Serial.println("release");
  }
  
  if (!btnState[1] && flag && millis() - btnTimer > 200) { // если кнопка zoom- отпущена
    flag = false;
    btnTimer = millis();
    Serial.println("release");
  }
  
   if (!btnState[2] && flag && millis() - btnTimer > 200) { //если кнопка focus+ отпущена
    flag = false;
    btnTimer = millis();
    Serial.println("release");
  }
  
  if (!btnState[3] && flag && millis() - btnTimer > 200) { // если кнопка focus- отпущена
    flag = false;
    btnTimer = millis();
    Serial.println("release");
  }
/* if(!btnState[0]&&flag)
flag = false;

if(btnState[0]&&!flag){
zoom.step(5);
Serial.print("+");
Serial.println(btnState[0]);

flag = true;
}
if(btnState[1]){
zoom.step(-1);
Serial.print("-");
Serial.println(btnState[1]);

}

if(btnState[2]){
focus.step(1);
Serial.print("+");
Serial.println(btnState[2]);

}

if(btnState[3]){
focus.step(-1);
Serial.print("-");
Serial.println(btnState[3]);

}
*/
}

86-108 строки
подумай внимательно

таймер лишний? ну и с flag не совсем однозначно получается

Код кривой, всё в одну кучу свалено ИМХО
Удержание сбрасывается другой не нажатой кнопкой, потом опять, по кругу.
Короткое нажатие тоже не так как задумано работает, хоть в этом глюке это не критично.

1 лайк

Спасибо за наводку, мысль понял! Получается под каждую кнопку свой флаг вводить или есть более удобные приёмы?

Это да.
Но сначала просто попробуйте весь loop(), (т.е. кнопки) опрашивать раз в 8-10мс. Только завести отдельную переменную для сохранения прошлого значения millis() )))

Стало все еще сложнее!) Попытался реализовать через отдельную функцию которая вызывается раз в 8-10мс для опроса пинов кнопок, но не получается присвоить значение массива из функции значению массива в loop

bool btnState[4];
if(millis()-oprosTimer>=10){
oprosTimer=millis();
//bool btnState1[] = {digitalRead(zoomPlusBtn), digitalRead(zoomMinusBtn), digitalRead(focusPlusBtn), digitalRead(focusMinusBtn)}; 
btnState[] = think();
}
bool think(){
 bool btnState1 = {digitalRead(zoomPlusBtn), digitalRead(zoomMinusBtn), digitalRead(focusPlusBtn), digitalRead(focusMinusBtn)}; //массив для опроса кнопок
 return btnState1;
 }

Читал про указатели и ссылки, но не помогло))) Помогите понять как реализовать возврат массива в массив или что-то в этом роде

Чего-то Вы усложняете…Я говорил лишь об этом

void loop() {
  if (millis() - last_millis > 10) {
    last_millis = millis();

    //Serial.println(btnState);
    bool btnState[] = {digitalRead(zoomPlusBtn), digitalRead(zoomMinusBtn), digitalRead(focusPlusBtn), digitalRead(focusMinusBtn)}; //массив для опроса кнопок

И.Т.Д.

И скобочку } в конце loop() добавить

Тогда появляется проблема, массив определен внутри оператора if и во вне его не получается передать, определяю вне if получаю ошибку компиляции. Можно конечно уйти от массива, но хочется научиться с ними работать