ARDUINO Резистивная клавиатура для управления Bluetooth модулем

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Прошу помочь с скетчем для управления блютуз модуля на BK8000L.
Суть в чём, есть 6 резистивных кнопок и они на одном проводе.
Одна сторона кнопок подтянута к земле, другая к пину + резистор на 10кОм от 5в.

По умолчанию, когда все кнопки разомкнуты, сопротивление 5кОм.
1 кнопка - 53.7Ом
2 кнопка - 146.6Ом
3 кнопка - 300.8Ом
4 кнопка - 562Ом
5 кнопка - 1.040кОм
6 кнопка - 2.041кОм

И получается, что если зажму какую-то кнопку, на выходе у меня должен получиться высокий уровень, когда по умолчанию, на всех выходах низкий.
Я пробовал в начале получить значения с кнопок, таким способом, только идёт сплошной поток данных.
C++:
byte key(){ 
    int val = analogRead(3); // считываем значение с аналогового входа и записываем в переменную val
        if (3) return 1;
        else if (15) return 2;
        else if (30) return 3;
        else if (56) return 4;
        else if (96) return 5;
        else if (176) return 6
        else return 0; 
}
void setup() {
    Serial.begin(9600);
}
void loop() {
    int sensorValue = analogRead(A3); //считываем кнопку
        Serial.print(key()); // выводим номер кнопки в serial
        Serial.print(" ");
        Serial.println(sensorValue);
        delay(1);       
}
Почитал документацию на библиотеку кнопок Подключение кнопки к Arduino. GyverButton v3.8 | AlexGyver .
Только у меня, скетчи не работают(

Я не понимаю, как это реализовать? Чтоб на своей клавиатуре нажал кнопку, у меня на пине появился высокий уровень.
Сталкивался кто с подобным? Спасибо.
 

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Я тут пошаманил, и сделал определение, получилось на примере этого скетча.
Осталось понять как это сделать грамотно и при нажатии кнопки, поднимать сигнал на каком-то выходе.
C++:
// задаем аналоговый пин ардуино куда подключены кнопки
int wheelPin = A5;

// Команды имеющихся на руле кнопок
const int VOL_DN = 1;
const int VOL_UP = 2;
const int UP = 3;
const int DOWN = 4;
const int MODE = 5;
const int MUTE = 6;

// Эта функция читает сопротивление с кнопок и возвращает код нажатой кнопки, либо 0
int getR()
{
int r = analogRead(wheelPin);

// Ищем, какая кнопка соответствует этому сопротивлению
if (r >= 1 && r <= 5) return (VOL_DN);
if (r >= 10 && r <= 20) return (VOL_UP);
if (r >= 25 && r <= 35) return (UP);
if (r >= 50 && r <= 60) return (DOWN);
if (r >= 90 && r <= 100) return (MODE);
if (r >= 170 && r <= 180) return (MUTE);
// если ни одна из кнопок не нажата, возвращаем 0
return (0);
}
void setup() {
    Serial.begin(9600);
}
void loop() {
        Serial.println(getR()); // выводим номер кнопки в serial
        Serial.print(" ");
        delay(1);      
}
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
3,230
940
@Slfl, зачем браться за то, что не понимаешь? Учиться, конечно, нужно, но как-то не так. Задача простая, не спорю, но решать её нужно последовательно. Сначала определить (или, если знаний не хватает, - считать) уровни напряжения (в цифровом "выражении"), которые получаются на аналоговом входе, именно эти уровни использовать для определения нажатой кнопки. Затем применить, допустим, case для "присвоения" действий.
Первый код показывает, что программирование - тоже новый предмет для Вас?
 
  • Лойс +1
Реакции: Slfl

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Как это ни странно, я много лет назад изучал шарп, потом ушел в вёрстку сайтов.

Это пример кода, что нашел в интернете.
В втором скетче я начал получать данные с моих кнопок. И я в логах уже вижу какая кнопка нажата. Осталось решить как прикрутить к этому действие)
Чтоб при нажатии какой-то кнопки, у меня на А2 была логическая единица.

Я посчитал, что проще измерять сопротивление, чем высчитывать падение напряжения.
 

poty

★★★★★★✩
19 Фев 2020
3,230
940
@Slfl, странные у Вас знания по #. Ну, например, то, что внутри if должно быть логическое выражение, а не число (как в Вашем первом примере, откуда бы он ни был взят), в любом языке программирования одинаково. Синтаксис изменяется, но не смысл.
Если Вы уже определили, что за кнопка нажата, то что Вам мешает создать такую же конструкцию из if, что используете для определения кнопки, (если уж не знаете про case) и использовать в ней результат getR()? Функции управления портом известны.
Я посчитал, что проще измерять сопротивление, чем высчитывать падение напряжения.
А Вы о своём решении что-то сказали микроконтроллеру? Он-то напряжение измеряет! Я не знаю, откуда Вы эти цифры взяли, что в коде. На первый взгляд они примерно соответствуют правильным. Т.е., при отсутствии нажатия на кнопку результат чтения порта будет 5*1024/(5+10)=341. При нажатии на 6 кнопку - 173... Но это не означает, что Вы сопротивление измеряете. И интервал между кнопками такой, что есть вероятность появления ложных срабатываний из-за помех. Впрочем, как учебный материал - сойдёт.
 

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Первый код, был очень ужасен)))
И с помощью подобного кода я слушал порт и смотрел на значения, при нажатой кнопке.
Потом, когда я уже +- знал значения, я сделал простую формулу для погрешности. Наводки/длинные провода/плохое соединение. Если значение будет плавать в моём диапазоне, значит кнопка зажата верная.

Сейчас мне надо выбрать нужные порты выхода(для подключение блюта), повесить на LOW уровень и при нажатии кнопки там выставить HIGH. И дело в шляпе.

Учебный материал, очень даже хорош. Делать копию другого проекта или прошить блинк, это не то. А тут не заморочено и чисто своё, самое оно)
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
@Slfl, про блютуз вы что-то непонятное пишете. Вы где лоу и хай собрались выставлять, на блютузе?
 

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
У блюта есть пины управления. На пин подаётся 3.3 через резистор 10кОм. Если учитывать напряжение на выходе ардуинки и поставить маленького сопротивления, этого должно хватить.

А по умолчанию, на ардуинке выходы управления опускаются в ноль, когда нажимаю кнопку, там появляется единица и управляю блютом
 

poty

★★★★★★✩
19 Фев 2020
3,230
940
Сейчас мне надо выбрать нужные порты выхода(для подключение блюта), повесить на LOW уровень и при нажатии кнопки там выставить HIGH. И дело в шляпе.
Я не понимаю, почему Вы об этом говорите, а не делаете? У Гайвера есть уроки по управлению цифровыми пинами, в конце-концов упомянутый Вами Blink "выбирает" порт D13 и управляет его состоянием: "вешая" на LOW, "выставляя" HIGH.
Предполагаю в скором будущем пару проблем. Например, кнопка будет проверяться несколько тысяч раз в секунду и каждый раз выполнять какие-то действия, не думаю, что в этом состоит Ваша логика. Второе - тоже связано с логикой: единица появляется только тогда, когда кнопка нажата? А после отжатия что происходит? Как Вы будете управлять при нажатой кнопке, если Вы не можете нажать одновременно с первой нажатой кнопкой ещё одну?
 

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Система не предусмотрена на управление сразу несколькими кнопками. И да, на всех выходах будет ноль, когда зажата кнопка, появляется единица, кнопка отжата и снова ноль.

Пишу сейчас с телефона, по этому и не сижу над кодом, по этому и не делаю а рассказываю вам.

Скорость опроса кнопок... Тут тоже надо будет над этим подумать.
 

Slfl

✩✩✩✩✩✩✩
1 Авг 2018
9
0
Grodno
Моих текущих знаний хватило до такого уровня)
Всё работает, ложных срабатываний нету, все кнопки соответствуют своему выходному пину.
Я считаю, цель достигнута и код работает.

Если можно сделать проще и красивее, буду рад помощи)

C++:
// задаем аналоговый пин ардуино куда подключены кнопки
int wheelPin = A5;

// Команды имеющихся на руле кнопок
int VOL_DN = 1;
int VOL_UP = 2;
int UP = 3;
int DOWN = 4;
int MODE = 5;
int MUTE = 6;

// Пины выхода с ардуинки
int VOL_DN_A = 2; //D2
int VOL_UP_A = 3; //D3
int UP_A = 4; //D4
int DOWN_A = 5; //D5
int MODE_A = 6; //D6
int MUTE_A = 7; //D7

// Инициализировать переменные для состояний кнопок
int buttonState_1 = 0;
int buttonState_2 = 0;
int buttonState_3 = 0;
int buttonState_4 = 0;
int buttonState_5 = 0;
int buttonState_6 = 0;

// Эта функция читает сопротивление с кнопок и возвращает код нажатой кнопки, либо 0
// Ищем, какая кнопка соответствует этому сопротивлению
int getR(){
  int r = analogRead(wheelPin);
  if (r >= 1 && r <= 5) return (1); // VOL_DN_A
  if (r >= 10 && r <= 20) return (2); // VOL_UP_A
  if (r >= 25 && r <= 35) return (3); // UP_A
  if (r >= 50 && r <= 60) return (4); // DOWN_A
  if (r >= 90 && r <= 100) return (5); // MODE_A
  if (r >= 165 && r <= 185) return (6); // MUTE_A
  return (0); // если ни одна из кнопок не нажата, возвращаем 0
}

void setup() {

  pinMode(VOL_DN_A, OUTPUT);
  pinMode(VOL_UP_A, OUTPUT);
  pinMode(UP_A, OUTPUT);
  pinMode(DOWN_A, OUTPUT);
  pinMode(MODE_A, OUTPUT);
  pinMode(MUTE_A, OUTPUT);

  Serial.begin(9600); // Включаем UART для отладки
}

void loop() {

  int buttonState_1 = getR(); // VOL_DN_A
    if (buttonState_1 == 1) {
      digitalWrite(VOL_DN_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(VOL_DN_A, LOW); // Set output pin to LOW (0V)
    }

  int buttonState_2 = getR(); // VOL_UP_A
    if (buttonState_2 == 2) {
      digitalWrite(VOL_UP_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(VOL_UP_A, LOW); // Set output pin to LOW (0V)
    }

  int buttonState_3 = getR(); // UP_A
    if (buttonState_3 == 3) {
      digitalWrite(UP_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(UP_A, LOW); // Set output pin to LOW (0V)
    }

  int buttonState_4 = getR(); // DOWN_A
    if (buttonState_4 == 4) {
      digitalWrite(DOWN_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(DOWN_A, LOW); // Set output pin to LOW (0V)
    }

  int buttonState_5 = getR(); // MODE_A
    if (buttonState_5 == 5) {
      digitalWrite(MODE_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(MODE_A, LOW); // Set output pin to LOW (0V)
    }

  int buttonState_6 = getR(); // MUTE_A
    if (buttonState_6 == 6) {
      digitalWrite(MUTE_A, HIGH); // Set output pin to HIGH (5V)
    } else {
      digitalWrite(MUTE_A, LOW); // Set output pin to LOW (0V)
    }

    // Debug
    Serial.println(getR()); // выводим номер кнопки в serial
    Serial.print(" ");

  delay(1);      
}
И пример, как это выглядит и работает.
result.png
 
Изменено: