Обращние к индексу массива
- Войдите на сайт для отправки комментариев
Приветствую!
Новичок, пытаюсь написать свой первый скетч для подключения нескольких кнопок к одному выходу arduino nano.
Подсмотрел в сети решения с последовательным подключением резисторов - при нажатии на каждую последующую из кнопок будет понижаться напряжение.
Напряжения перевожу в АЦП и создаю из этого одномерный массив. Соответственно теперь напряжение при нажатии каждой из кнопок соответствует её номеру (индексу) в заданном массиве.
Как мне обратиться к номеру кнопки, а не к значению АЦП, если я хочу чтобы при нажатии определённо кнопки выполнялось действие?
Насколько я понимаю, это должно выполняться через имя переменной NumberToValue (см. часть скетча ниже)
{
int NumberToValue (int value)
int values[8] = {128, 144, 169, 204, 255, 341, 511, 1023}; //массив для 8 кнопок по значением АЦП
int error = 15; // Погрешность
for (int i = 0; i <= 7; i++)
{
if (value <= values[i] + error && value >= values[i] - error) return i;
}
return -1; // Значение не принадлежит заданному диапазону
}
Но при попытке обращения к ней (см. часть скетча ниже)
if (NumberToValue == 3)
получаю ошибку
C:\ARDUINO\1\1.info: In function 'void loop()': C:\ARDUINO\1\1.info:180:39: warning iso c++ forbids comparison between pointer and integer [-fpermissive] if (NumberToValue == 3)
Если же указать значение массива, то ошибок нет и всё компилируется, но это не тот результат, что мне нужен.
Я конечно могу просто задать диапозон для полученных значений АЦП от нажатия кнопки, но с массивом было бы проще..
Подскажите, как правильно решить данную задачу?
приведите скетч полностью, судя по ошибке. вы в скетче обращаетесь к функции не так, как в показанном примере
Ну и еще - очень похоже. что вы эту функцию где-то скопипастили и ни черта не понимаете, как она работает.
Так я и не скрываю что скопипастил с просторов интернета, об этом писал в начале :)
Моё понимание работы это функции вероятно отличается от правильного, скажем так..
Скетч ниже, это программа для универсального пульта от ТВ и ресиверов, там много лишнего, что я ещё только планирую задействовать, просто пока хочу эту задачурешить, а дальше буду решать остальные.
//подключаю 8 кнопок к порту A0, резисторы 10К //подключаю ИК к порту D6 #include <IRremote.h> //Библиотека для ИК диода IRsend irsend; const int IR = 6; // присваиваю переменной IR порт D6 (один из ШИМ - 3,5,6,9,10,11) IRrecv irrecv(IR); //присваиваю порт ИК Диоду //Частоты кнопок для работы с ресивером ONLIME, разбиты на связки из 8, каждая из которых подключается к отдельному порту ардуино (7 портов) #define O_ONOFF 0x807F807F //Кнопка Включения/Выключения #define O_MUTE 0x807F48B7 //Кнопка Mute #define O_1 0x807F00FF //Кнопка 1 #define O_2 0x807F00FF //Кнопка 2 #define O_3 0x807F00FF //Кнопка 3 #define O_4 0x807F00FF //Кнопка 4 #define O_5 0x807F00FF //Кнопка 5 #define O_6 0x807F00FF //Кнопка 6 #define O_7 0x807F00FF //Кнопка 7 #define O_8 0x807F00FF //Кнопка 8 #define O_9 0x807F00FF //Кнопка 9 #define O_TVP 0x807F00FF //Кнопка TV Portal #define O_0 0x807F00FF //Кнопка 0&@_ #define O_MENU 0x807F00FF //Кнопка MENU #define O_PLAY 0x807F00FF //Кнопка PLAY #define O_PAUSE 0x807F00FF //Кнопка PAUSE #define O_STOP 0x807F00FF //Кнопка STOP #define O_REC 0x807F00FF //Кнопка REC #define O_REW 0x807F00FF //Кнопка REWIND #define O_FOR 0x807F00FF //Кнопка FORWARD #define O_2REW 0x807F00FF //Кнопка 2xREWIND #define O_2FOR 0x807F00FF //Кнопка 2xFORWARD #define O_RED 0x807F00FF //Кнопка RED #define O_GREEN 0x807F00FF //Кнопка GREEN #define O_YELLOW 0x807F00FF //Кнопка YELLOW #define O_BLUE 0x807F00FF //Кнопка BLUE #define O_MEDIA 0x807F00FF //Кнопка MEDIA #define O_GUIDE 0x807F00FF //Кнопка GUIDE #define O_LEFT 0x807F00FF //Кнопка LEFT #define O_UP 0x807F00FF //Кнопка UP #define O_RIGHT 0x807F00FF //Кнопка RIGHT #define O_DOWN 0x807F00FF //Кнопка DOWN #define O_OK 0x807F00FF //Кнопка OK #define O_EXIT 0x807F00FF //Кнопка EXIT #define O_BACK 0x807F00FF //Кнопка BACK #define O_VOLUP 0x807F00FF //Кнопка VOLUME + #define O_VOLDWN 0x807F00FF //Кнопка VOLUME - #define O_LIST 0x807F00FF //Кнопка LIST #define O_I 0x807F00FF //Кнопка I #define O_CHUP 0x807F00FF //Кнопка CHANNEL + #define O_CHDWN 0x807F00FF //Кнопка CHANNEL - #define O_OPTPLUS 0x807F00FF //Кнопка OPT+ #define O_LANG 0x807F00FF //Кнопка LANGUAGE #define O_SUB 0x807F00FF //Кнопка SUBTITLE #define O_RADIO 0x807F00FF //Кнопка TV/RADIO #define O_TEXT 0x807F00FF //Кнопка TEXT #define O_SOURCE 0x807F00FF //Кнопка SOURCE #define O_VF 0x807F00FF //Кнопка V-FORMAT #define O_WIDE 0x807F00FF //Кнопка WIDE //Частоты кнопок для работы с телевизором Philips, разбиты на связки из 8, каждая из которых подключается к отдельному порту ардуино (3 порта) #define P_ONOFF 0x807F807F //Кнопка Включения/Выключения #define P_MUTE 0x807F48B7 //Кнопка Mute #define P_SOURCE 0x807F00FF //Кнопка SOURCE #define P_1 0x807F00FF //Кнопка 1 #define P_2 0x807F00FF //Кнопка 2 #define P_3 0x807F00FF //Кнопка 3 #define P_4 0x807F00FF //Кнопка 4 #define P_5 0x807F00FF //Кнопка 5 #define P_6 0x807F00FF //Кнопка 6 #define P_7 0x807F00FF //Кнопка 7 #define P_8 0x807F00FF //Кнопка 8 #define P_9 0x807F00FF //Кнопка 9 #define P_LEFT 0x807F00FF //Кнопка LEFT #define P_UP 0x807F00FF //Кнопка UP #define P_RIGHT 0x807F00FF //Кнопка RIGHT #define P_DOWN 0x807F00FF //Кнопка DOWN #define P_OK 0x807F00FF //Кнопка OK #define P_BACK 0x807F00FF //Кнопка BACK //Частоты кнопок для работы с ресивером Denon, все 4 подключаются к одному отдельному порту ардуино #define D_ONOFF 0x807F807F //Кнопка Включения/Выключения #define D_MUTE 0x807F48B7 //Кнопка Mute #define D_VOLUP 0x807F00FF //Кнопка VOLUME + #define D_VOLDWN 0x807F00FF //Кнопка VOLUME - //Задаю переменные для обозначения портов ардуино //Сначала аналог - 8 штук const int A_0 = A0; // присваиваю переменной A0 порт A0 const int A_1 = A1; // присваиваю переменной A1 порт A1 const int A_2 = A2; // присваиваю переменной A2 порт A2 const int A_3 = A3; // присваиваю переменной A3 порт A3 const int A_4 = A4; // присваиваю переменной A4 порт A4 const int A_5 = A5; // присваиваю переменной A5 порт A5 const int A_6 = A6; // присваиваю переменной A6 порт A6 const int A_7 = A7; // присваиваю переменной A7 порт A7 //Теперь цифровые - 12шт const int D_2 = 2; // присваиваю переменной D2 порт D2 const int D_3 = 3; // присваиваю переменной D3 порт D3 const int D_4 = 4; // присваиваю переменной D4 порт D4 const int D_5 = 5; // присваиваю переменной D5 порт D5 //на 6-м порту уже сидит ИК диод const int D_7 = 7; // присваиваю переменной D7 порт D7 const int D_8 = 8; // присваиваю переменной D8 порт D8 const int D_9 = 9; // присваиваю переменной D9 порт D9 const int D_10 = 10; // присваиваю переменной D10 порт D10 const int D_11 = 11; // присваиваю переменной D11 порт D11 const int D_12 = 12; // присваиваю переменной D12 порт D12 const int D_13 = 13; // присваиваю переменной D13 порт D13 int keyValue = 0; //состояние покоя (эта переменная это значение напряжения при нажатии кнопки) void setup() { //переключаю порты ардуино на считывание и прием информации pinMode(A_0, INPUT); //порт A0 работает на считывание данных pinMode(A_1, INPUT); //порт A1 работает на считывание данных pinMode(A_2, INPUT); //порт A2 работает на считывание данных pinMode(A_3, INPUT); //порт A3 работает на считывание данных pinMode(A_4, INPUT); //порт A4 работает на считывание данных pinMode(A_5, INPUT); //порт A5 работает на считывание данных pinMode(A_6, INPUT); //порт A6 работает на считывание данных pinMode(A_7, INPUT); //порт A7 работает на считывание данных pinMode(D_2, INPUT); //порт D2 работает на считывание данных pinMode(D_3, INPUT); //порт D3 работает на считывание данных pinMode(D_4, INPUT); //порт D4 работает на считывание данных pinMode(D_5, INPUT); //порт D5 работает на считывание данных pinMode(IR, OUTPUT); //порт D6 теперь работает на считывание данных pinMode(D_7, INPUT); //порт D7 работает на считывание данных pinMode(D_8, INPUT); //порт D8 работает на считывание данных pinMode(D_9, INPUT); //порт D9 работает на считывание данных pinMode(D_10, INPUT); //порт D10 работает на считывание данных pinMode(D_11, INPUT); //порт D11 работает на считывание данных pinMode(D_12, INPUT); //порт D12 работает на считывание данных pinMode(D_13, INPUT); //порт D13 работает на считывание данных irsend.enableIROut(36); //режим ИК передатчика (ещё варианты: 38,40) Serial.begin(9600); //открываем последовательный порт, устанавливаем скорость 9600 бит/c } void loop() { int newKeyValue = GKV(); // Получаем актуальное состояние кнопок с коррекцией дребезга if (keyValue != newKeyValue) { // Если новое значение не совпадает со старым - реагируем на него keyValue = newKeyValue; // Актуализируем переменную хранения состояния if (keyValue > 0) // Если значение больше 0, значит кнопка нажата { if (GetButtonNumberByValue == 0) { delay(50); irsend.sendNEC(O_ONOFF, 32); delay(50); } if (GetButtonNumberByValue == 1) { delay(50); irsend.sendNEC(O_MUTE, 32); delay(50); } if (GetButtonNumberByValue == 2) { delay(50); irsend.sendNEC(O_1, 32); delay(50); } if (GetButtonNumberByValue == 3) { delay(50); irsend.sendNEC(O_2, 32); delay(50); } if (GetButtonNumberByValue == 4) { delay(50); irsend.sendNEC(O_3, 32); delay(50); } if (GetButtonNumberByValue == 5) { delay(50); irsend.sendNEC(O_4, 32); delay(50); } if (GetButtonNumberByValue == 6) { delay(50); irsend.sendNEC(O_5, 32); delay(50); } if (GetButtonNumberByValue == 7) { delay(50); irsend.sendNEC(O_6, 32); delay(50); } }}} int GKV() { // Функция устраняющая дребезг static int count; static int oldKeyValue; // Переменная для хранения предыдущего значения состояния кнопок static int innerKeyValue; // Здесь уже не можем использовать значение АЦП, так как оно постоянно меняется в силу погрешности int actualKeyValue = GetButtonNumberByValue(analogRead(A_0)); // Преобразовываем его в номер кнопки, тем самым убирая погрешность if (innerKeyValue != actualKeyValue) { // Пришло значение отличное от предыдущего count = 0; // Все обнуляем и начинаем считать заново innerKeyValue = actualKeyValue; // Запоминаем новое значение } else { count += 1; // Увеличиваем счетчик } if ((count >= 10) && (actualKeyValue != oldKeyValue)) { oldKeyValue = actualKeyValue; // Запоминаем новое значение } return oldKeyValue; } int GetButtonNumberByValue(int value) { // Новая функция по преобразованию кода нажатой кнопки в её номер int values[8] = {128, 144, 169, 204, 255, 341, 511, 1023}; int error = 15; // Величина отклонения от значений - погрешность for (int i = 0; i <= 7; i++) { // Если значение в заданном диапазоне values[i]+/-error - считаем, что кнопка определена if (value <= values[i] + error && value >= values[i] - error) return i; } return -1; // Значение не принадлежит заданному диапазону }слушайте, вы совсем чтоли в этом коде ничего не понимаете?
У вас текущий номер кнопки уже сидит в переменной keyValue - так и используйте его! зачем вы в своих условиях (строка 165 и далее) снова вызываете GetButtonNumberByValue, да еще и с неправильным синтаксисом?
разве keyvalue, в данном случае, это не значение АЦП?
GetButtonNumberByValue я использую чтобы присвоить значению АЦП номер в массиве.
И соответтвенно по его значению хочу чтобы ИК диод посылал нужный код.
Что не так с синтаксисом?
разве keyvalue, в данном случае, это не значение АЦП?
к чему эти вопросы - код ведь перед вами. Посмотрите сами, откуда берется значение keyvalue в строчках 160 и 162
Что не так с синтаксисом?
GetButtonNumberByValue - это функция. Синтаксис вызова функции смотрите в учебнике
в третьей строке должно быть NumberToValue(какое то начение или переменная)
Пух, вылазь своими лямбдами фарцовать, без тебя тут не обойтись.
Спасибо, я сам себя запутал, когда решил, что keyvalue это значение АЦП.
Буду дальше допиливать код...
Меня вот вопрос беспокоит. Сколько не пробовал кнопки на резисторах нажимать всегда разные значения дает. Но 1-2 разряда, но всё же. Выходил из положения тем, что делил результат на 64 и получал значения от 0 до 16 сразу значение нопки, которое использовал в программе без всяких переназначений и массивов.
Я правильно понимаю, что Вы значение АЦП делите на 64 ?
Если не сложно, можете покзазать пример кода?
Простите не понял. key = analogRead(analogPin) / 64; Что тут может быть непонятного? Единственное что я делал, это в экселе посчитал номиналы резисторов так, что бы при нажатии кнопки напяжение на получившемся делителе после оцифровки попало точно в середину диапазона шага по 64 бита. Чтобы специально не подбирать номиналы резисторов. Получилось с первого раза, резисторы из стандартного ряда уложились в погрешность измерения. Ошибок определения кнопок не было.
Но значение же будет не целое, а Вы говорире про целые числа (0-16)
Допустим при 5v 1023/65=15,98
Но значение же будет не целое, а Вы говорире про целые числа (0-16)
Допустим при 5v 1023/65=15,98
если переменная результата описана как int - то результат деления будет целым.
int key = 1023/65=15
https://metanit.com/cpp/tutorial/2.6.php
Опять моя невнимательность....
спасибо!
Вообще, на мой взгляд, такой метод более изящный, нежеле массив, буду пробовать.