Богдан
01.Январь.2023 15:57:33
1
Добрый день! Если вопрос где-то обсуждался не закидывайте камнями, не нашел!
Делаю микроскоп для пайки и нашел обЪектив только от 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 шагов. Или наоборот.
BOOM
01.Январь.2023 17:30:54
3
sadman41:
Как насчёт энкодеров?
С кнопками проблемы, а ты ещё и усложнить хочешь ))) Хотя идея отличная, я за!
ЗЫ: ТС вставь код правильно.
vk007
01.Январь.2023 23:25:06
4
Так код тут еще не вставляли. Пора заводить раздел “Как не надо вставлять код” с подобными перлами.
Богдан
02.Январь.2023 09:03:20
5
Энкодеры покупать нужно, делаю из того что под рукой!
Green
02.Январь.2023 09:30:37
7
Богдан , неужто ты сразу не видишь, что вместо кода вставил херню! И тебе об этом уже сказали. А тогда почему не исправил? Какой тебе ещё ответ по существу!
Богдан
02.Январь.2023 09:35:07
8
С удовольствием бы исправил, но нет нигде кнопок редактирования, сижу с телефона! А ответ по сути поста!
Какой ответ, если нет вопроса по сути.
Богдан
02.Январь.2023 09:59:31
10
Вопрос в том, что почему удержание кнопки работает через раз или вовсе не работает, хотя нажатие записывается в переменную 100%? Поставил строчки с удержанием наверх все заработало норм, добавил управление фокусом и все опять работает через раз , может есть варианты более стабильные, может как-то можно оптимизировать конструкции if
Твои ошметки кода никому непонятны, вот и итог!
Богдан
02.Январь.2023 10:16:37
12
#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]);
}
*/
}
rkit
02.Январь.2023 10:21:02
13
86-108 строки
подумай внимательно
Богдан
02.Январь.2023 10:33:39
14
таймер лишний? ну и с flag не совсем однозначно получается
Код кривой, всё в одну кучу свалено ИМХО
Удержание сбрасывается другой не нажатой кнопкой, потом опять, по кругу.
Короткое нажатие тоже не так как задумано работает, хоть в этом глюке это не критично.
1 лайк
Богдан
02.Январь.2023 15:00:51
16
Спасибо за наводку, мысль понял! Получается под каждую кнопку свой флаг вводить или есть более удобные приёмы?
Это да.
Но сначала просто попробуйте весь loop(), (т.е. кнопки) опрашивать раз в 8-10мс. Только завести отдельную переменную для сохранения прошлого значения millis() )))
Богдан
03.Январь.2023 20:30:33
18
Стало все еще сложнее!) Попытался реализовать через отдельную функцию которая вызывается раз в 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() добавить
Богдан
03.Январь.2023 20:51:50
20
Тогда появляется проблема, массив определен внутри оператора if и во вне его не получается передать, определяю вне if получаю ошибку компиляции. Можно конечно уйти от массива, но хочется научиться с ними работать