OneButton есть вопросы..
- Войдите на сайт для отправки комментариев
Сб, 21/11/2020 - 21:34
Столкнулся с проблемой при работе с модулем nRF24. Не получается считать состояние кнопки. Компилятор пишет: cannot convertto 'uint8_t {aka unsigned char}' for argument '1' to 'int digitalRead(uint8_t)'
Что не так? Подозреваю, что с библиотеками типа 'OneButton' надо как-то по другому считывать состояние кнопок. Не подскажете как?
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "OneButton.h"
OneButton button1(4, true);
RF24 radio(10, 9);
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
struct Data_Package {
bool butt;
};
Data_Package data;
void setup() {
Serial.begin(9600);
radio.begin();
radio.setRetries(0, 15);
radio.enableAckPayload();
radio.setPayloadSize(32);
radio.openWritingPipe(address[0]);
radio.setChannel(0x60);
radio.setPALevel (RF24_PA_MAX);
radio.setDataRate (RF24_250KBPS);
radio.powerUp();
radio.stopListening();
}
void loop() {
data.butt = digitalRead(button1);
radio.write(&data, sizeof(Data_Package));
}
Что ж вы класс суете в digitalRead().
В библиотеке примеры есть - смотрели?
Да, но там нет примеров для отправки по радио.((
Да, но там нет примеров для отправки по радио.((
Там есть примеры считывания состояния кнопки. А уж радио - это ваша забота
Да, но там нет примеров для отправки по радио.((
и быть не может, отправка по радио это уже другой девайс другая библиотека
Да, но там нет примеров для отправки по радио.((
Там есть примеры считывания состояния кнопки. А уж радио - это ваша забота
Все верно, кстати, ваша библиотека мне нравится больше, её и использую. Не поможете реализовать долгое и двойное нажатие на примере из под Debounce? Сам никак не осилю - ерунда выходит, гляньте пожалуйста..
Код:
#define buttonPin 4 int LedPin = 13; int bounceTime = 10; int doubleTime = 300; int i = 0; boolean lastReading = false; boolean buttonSingle = false; boolean buttonDouble = false; long onTime = 0; long lastSwitchTime = 0; void setup() { Serial.begin(9600); pinMode (buttonPin, INPUT_PULLUP); pinMode(LedPin, OUTPUT); } void loop() { boolean reading = digitalRead(buttonPin); if (reading && !lastReading) { onTime = millis(); } if (!reading && lastReading) { if (((millis() - onTime) > bounceTime)) { if ((millis() - lastSwitchTime) >= doubleTime) { lastSwitchTime = millis(); buttonSingle = true; i = 1; } else { i = 2; lastSwitchTime = millis(); buttonDouble = true; } } } lastReading = reading; if (buttonSingle && (millis() - lastSwitchTime) > doubleTime) { digitalWrite(LedPin, HIGH); } else { digitalWrite(LedPin, LOW); } if (buttonDouble && (millis() - lastSwitchTime) > doubleTime) { digitalWrite(LedPin, HIGH); } else { digitalWrite(LedPin, LOW); } }В последнем коде я не вижу ни своей, ни какой-то другой библиотеки. В моей и длинное, и двойное нажатие реализуется буквально парой строк в скетче, но сейчас с телефона я вам не помощник. Гляньте в примерах
Я хочу обойтись не используя никаких библиотек, т.к. в моем случае их использование не пригодно. Думаю написать обработчик на три разных нажатия и уже его использовать в своем коде для передачи по nRF24. Так-то проблем при использовании вашей библиотеки нет никаких. Там действительно все очень наглядно и просто, а вот как это сделать без использования библиотеки - вопрос.
Я взял за основу пример из Debounce и на него накидал свои наработки которые не корректно отрабатывают функции от них требующиеся. В частности - что при одинарном клике, что при двойном происходит одновременное срабатывание. Там у меня с логикой какие-то проблемы. (
21 строка 22 строка - нажатие кнопки - Gnd.
Земля матушка, хм, пойду прилягу..
Не, ну если хочется помучиться, то вопросов нет. Но разделять одинарный и двойной клики - задачка не из тех, что в двух словах можно объяснить))
Я хочу обойтись не используя никаких библиотек,
Видите ли, то, что в Ардуино называется библиотеками, на самом деле называется классами и представляет собой стандартную практику.
т.к. в моем случае их использование не пригодно.
Значит, Вы чего-то не понимаете. В любом случае Ваше мнение ошибочно.
В разделе "Программирование" есть прикрепленная тема "Титановый велосипед". Посмотрите, как там реализовано. Возможно, что-то сумеете использовать у себя.
Я хочу обойтись не используя никаких библиотек,
Видите ли, то, что в Ардуино называется библиотеками, на самом деле называется классами и представляет собой стандартную практику.
т.к. в моем случае их использование не пригодно.
Значит, Вы чего-то не понимаете. В любом случае Ваше мнение ошибочно.
В разделе "Программирование" есть прикрепленная тема "Титановый велосипед". Посмотрите, как там реализовано. Возможно, что-то сумеете использовать у себя.
Все это понятно, только для реализации моего проекта вынужден отказаться от использования стандартной практики. Я не знаю как реализовать передачу по радиоканалу с использованием библиотек. Если вы знаете - поделитесь методом. С радостью применю его в своем небольшом проекте. Ссылку про велосипед читал и раньше. Автор - остроумный весельчак. Мне такой тип характера импонирует, но увы, там те же библиотеки(классы) которые мне в данном проекте ничем не помогут.
Я тут наковырял с подходящей библиотеки нужные мне строки, правда без двойного клика - удержание и одиночный клик, в принципе устраивает. Остался один нерешенный вопрос - развести функции при длительном нажатии. Надо, чтобы после удержания менялся режим на противоположный. Как можно это реализовать?
#define buttonPin 3 bool button_state = false; bool button_long_state = false; uint32_t ms_button = 0; void setup() { Serial.begin(115200); Serial.println("Test button ..."); pinMode(buttonPin, INPUT_PULLUP); } void loop() { uint32_t ms = millis(); bool pin_state = digitalRead(buttonPin); if ( pin_state == LOW && button_state == false && ( ms - ms_button ) > 50 ) { uint16_t dt = ms - ms_button; button_long_state = false; button_state = true; ms_button = ms; } if ( pin_state == LOW && !button_long_state && ( ms - ms_button ) > 2000 ) { button_long_state = true; Serial.println("Long press key"); } if ( pin_state == HIGH && button_state && ( ms - ms_button ) > 50 ) { button_state = false; ms_button = ms; if ( !button_long_state )Serial.println("Press key"); } }NVN Plus - вы какую-то откровенную ерунду пишете. Как НРФ24 может мешать вашей работе с кнопками? Забудьте пока вообще про радио, напишите обработку кнопки - с библиотекой или вообще без них - а только когда все закончите, добавьте радио.
Многие новички не умеют разделять задачи и сами загоняют себя в тупик. Если вы хотите прибить доску и покрасить ее - не стоит в одну руку брать молоток, в другую кисть - ничего не выйдет. Решайте проблемы поочередно.
Я совершенно не понимаю, что мешает вам СНАЧАЛА получить от библиотеки кнопки события isClick() или isDublClick(), а только ПОТОМ отправить этот статус по радио?
Передавайте для начала по радиоканалу просто состояние кнопки, а не мультиклик с переворотом.
Вы заблуждаетесь насчёт нерешённых вопросов. Единственный нерешённый вопрос у вас - с самообразованием. Когда перестанете наковыривать строки и предлагать всем подряд в них исправить код на нужный лично вам, а начнёте вникать в написанное, пробовать, ошибаться и разбираться в ошибках по учебнику - тогда дело сдвинется с мертвой точки.
И, нет - форум не для этого, о чем вы сейчас подумали.
Спасибо, буду пробовать. С библиотекой работать вроде научился, тем более v258 написал удобную в использовании. Просто нигде нет информации, где можно почитать о том как правильно работать в подобных случаях. Когда уже не получается, начинаешь рыскать в надежде найти что-то уже готовое. Не серчайте, мне не легко дается освоение материала - потому порой и глупые вопросы.
Просто нигде нет информации, где можно почитать о том как правильно работать в подобных случаях.
конечно нет. Это все вытекает из логики программирования, и никто об этом писать не будет.
#include <PinButton.h> PinButton myButton(3); bool ledOn = false; void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { myButton.update(); if (myButton.isClick()) { ledOn = !ledOn; digitalWrite(LED_BUILTIN, ledOn); } }На этом простом примере можете объяснить какие действия мне надо предпринять? Состояние события кнопки isClick() получено. Дальше я должен этот статус прописать в структуру для передачи данных - верно? Почему в структуру - потому что на ряду с этими данными предполагается передать большое количество данных (до десяти состояний кнопок и данные с трех потенциометров). Структура может в свои 32 байта уместить такой большой объем и одним пакетом передать. По крайне мере я так это понимаю из усвоенного раньше материала по структурам. Дальше мне не понятны действия, которые надо произвести. Как прописать состояния потенциометров и кнопок мне известно, с этим я разобрался, а вот с этой ситуацией я сталкиваюсь впервые. В общем мне нужна ваша помощь..
допустим, состояние этой кнопки вы передаете в элементе структуры data под индексом 9
void loop() { myButton.update(); if (myButton.isClick()) { data[9] = 1; } else data[9] = 0; }Для начала вы разобрались с кнопкой, теперь опишите структуру, которую будете передавать
Принцип понятен - индексируем значение внутри структуры, а на принимающей стороне считываем эти значения. Сам алгоритм передачи понятен, вот только процесс индексации как правильно оформить я не знаю. Должен ли я завести переменную в типе данных скажем: byte a[9];?
Еще раз - опишите структуру. Например, в нулевом посту вы попытались это сделать
struct Data_Package { bool butt; }; Data_Package data;В таком случае можно присваивать значение по имени
Только если планируется передавать более, чем два состояния кнопки (отжато, нажато, долго нажато и т.д.), то вместо типа bool нужно использовать тип byte.
struct Data_Package { byte butt; }; data.butt = 2;В этой структуре вы можете задавать поля для всех кнопок и потенциометров.
struct Data_Package { byte butt1; byte butt2; word potn1; word potn2; };Ну а когда определитесь со структурой, можно будет переходить к передаче данных
Я со структурой определился. У меня обычные функции давно прописаны как вы любезно и описали со всеми подробностями, за что не премину вас поблагодарить равно как и остальных помогающих. Вот как я поступил с основными позициями. Все прекрасно передается и принимается другой стороной. Мне бы осилить теперь новую для меня конструкцию.
#define ShiftPin 4 #define ModePin 5 #define TriggerPin 6 struct Data_Package { int TiltChannel; int PanChannel; int RollChannel; bool buttonShift; bool Mode; bool Trigger; }; Data_Package data; void setup() { pinMode(ShiftPin, INPUT_PULLUP); pinMode(ModePin, INPUT_PULLUP); pinMode(TriggerPin, INPUT_PULLUP); } void loop() { data.TiltChannel = map(analogRead(A6), 0, 1023, 1700, 350); data.PanChannel = map(analogRead(A7), 0, 1023, 1700, 350); data.RollChannel = map(analogRead(A5), 0, 1023, 1700, 350); data.buttonShift = digitalRead(ShiftPin); data.Mode = digitalRead(ModePin); data.Trigger = digitalRead(TriggerPin); radio.write(&data, sizeof(Data_Package)); }Ну а что сложного-то?
void loop() { myButton.update(); if (myButton.isClick()) { data.TiltChannel = map(analogRead(A6), 0, 1023, 1700, 350); data.PanChannel = map(analogRead(A7), 0, 1023, 1700, 350); data.RollChannel = map(analogRead(A5), 0, 1023, 1700, 350); data.buttonShift = digitalRead(ShiftPin); data.Mode = digitalRead(ModePin); data.Trigger = digitalRead(TriggerPin); radio.write(&data, sizeof(Data_Package)); } }По клику кнопки данные считываются и передаются
..если планируется передавать более, чем два состояния кнопки (отжато, нажато, долго нажато и т.д.), то вместо типа bool нужно использовать тип byte.
struct Data_Package { byte butt; }; data.butt = 2;Скажите, "data.butt = 2;" разве в случае с библиотекой я могу указывать кнопку и номер пина?
Здесь не было кнопки и номера пина, тут был пример записи состояния кнопки. butt в данном случае - поле структуры Data_Package, его имя может быть любым
А двойка - это состояние кнопки, типа: 0 - отжата, 1 - нажата, 2 - двойной клик и т.д. Опять же, что вам заблагорассудится
Ну а что сложного-то?
void loop() { myButton.update(); if (myButton.isClick()) { data.TiltChannel = map(analogRead(A6), 0, 1023, 1700, 350); data.PanChannel = map(analogRead(A7), 0, 1023, 1700, 350); data.RollChannel = map(analogRead(A5), 0, 1023, 1700, 350); data.buttonShift = digitalRead(ShiftPin); data.Mode = digitalRead(ModePin); data.Trigger = digitalRead(TriggerPin); radio.write(&data, sizeof(Data_Package)); } }По клику кнопки данные считываются и передаются
Это все что требовалось сделать!? Ну.. не знаю - сколько времени бился чтобы решить эту проблему, а оно во как.. Не ожидал, что будет все так просто, даже не верится.)) Спасибо! Вы сильно мне помогли.
сколько времени бился чтобы решить эту проблему, а оно во как.. Не ожидал, что будет все так просто, даже не верится.))
Ага, волшебство - это просто ;))
Не ожидал, что будет все так просто
ну вот... а мы никак не можем понять. о чем вы вообще спрашиваете.
Тут нет никакого волшебства. вам же сразу сказали что работа с кнопками по радио ничем не отличается от работы без радио...
А вы в ответ "использование библиотек с радио невозможно" :)
Тогда вы волшебник..))
Не могу не воспользоваться вашим присутствием и задам вопрос в случае с вашей библиотекой - также вставляю данные до свичей, а те потом на принимающей стороне вылавливаю и оформляю в лучшем виде!? Я правильно освоил тему?
static int8_t oldState = -1; // опрос кнопки, для уверенной обработки состояния кнопки опросы нужно делать как можно чаще int8_t curState = but.getButtonState(); if (oldState != curState) { oldState = curState;Не ожидал, что будет все так просто
ну вот... а мы никак не можем понять. о чем вы вообще спрашиваете.
Тут нет никакого волшебства. вам же сразу сказали что работа с кнопками по радио ничем не отличается от работы без радио...
А вы в ответ "использование библиотек с радио невозможно" :)
Когда я не владею темой, начинаю слушать окружающих и как в таких случаях происходит делаешь не правильные выводы. Где-то, что-то не до понял и пошло поехало.. Спасибо вам за помощь, вы кстати не в первый раз меня наталкиваете на правильные измышления. Буду потихоньку двигаться дальше.. есть ещё несколько задумок, которые хочу реализовать сам. Так что я вас ещё помучаю.))
Так что я вас ещё помучаю.))
а где положительные эмоции )))
Ну да, помнится и вас я мучил в другой ветке. )) Там такой же был результат - эмоции били через край! Благодарю!
Тогда вы волшебник..))
Не могу не воспользоваться вашим присутствием и задам вопрос в случае с вашей библиотекой - также вставляю данные до свичей, а те потом на принимающей стороне вылавливаю и оформляю в лучшем виде!? Я правильно освоил тему?
static int8_t oldState = -1; // опрос кнопки, для уверенной обработки состояния кнопки опросы нужно делать как можно чаще int8_t curState = but.getButtonState(); if (oldState != curState) { oldState = curState;Нет. Как раз здесь обработка состояния кнопки ведется в свитчах. Только если вы хотите иметь разную реакцию на одинарный и двойной клик, то лучше использовать пример из ClickAndDblClick.ino
#include <shButton.h> shButton but(10); // равнозначно shButton but(10, PULL_UP, BTN_NO) void setup() { but.setVirtualClickOn(true); // включение режима виртуального клика } void loop() { switch (but.getButtonState()) { case BTN_ONECLICK: // здесь вставляете то, что должно произойти при одинарном клике break; case BTN_DBLCLICK: // а здесь - то, что должно произойти при двойном клике break; } }Я уже распределил с помощью свичей в вашей библиотеке на какие кнопки какие функции будут повешены, говорю же - там все просто и наглядно, по мне - лучшая библиотека в своем классе на сегодня. Одно одновременное нажатие на две кнопки чего стоит! Вопрос заключался в отправке по радио в случае с вашей библиотекой, так сказать для проверки себя в правильном освоении темы.
Все это понятно, только для реализации моего проекта вынужден отказаться от использования стандартной практики.
Видите ли, программирование целиком основано на использовании стандартной практики. Так что выбор у Вас невелик: либо отказаться от надуманных утверждений (типа "стандартная практика мне не подходит"), либо отказаться от программирования вообще и Ардуино в частности.
От чего отказываться - решайте сами. Но без "стандартной практики" Вы проект реализовать не сможете.
Кто из нас не ошибается в этой жизни. Но.. дорогу осилит идущий и какие бы ошибки не совершал человек он должен продолжать свой путь. Признавая и исправляя текущие, совершая следующие идти и идти, ибо движение - жизнь, а она, жизнь тем и интересна, что человеку свойственно ошибаться. Так-что и проекты будут и стандарты со временем изменятся, а человек все одно будет совершать ошибки. Мы ж не роботы, всего лишь люди и это здорово!
Кто из нас не ошибается в этой жизни. Но.. дорогу осилит идущий и какие бы ошибки не совершал человек он должен продолжать свой путь. Признавая и исправляя текущие, совершая следующие идти и идти, ибо движение - жизнь, а она, жизнь тем и интересна, что человеку свойственно ошибаться. Так-что и проекты будут и стандарты со временем изменятся, а человек все одно будет совершать ошибки. Мы ж не роботы, всего лишь люди и это здорово!
столько слов... и о чем? По сути - эти слова хороши для утешения плачущего ребенка, когда у того что-то не получается. Применять же их к себе самому - крайне вредная и расслабляющая практика.
И еще... Не хочу бросить тень на код v258, но вообще я бы запретил новичкам использовать библиотеки для кнопок. Я имею в виду те, что новички написали не сами. Работа с кнопкой - это то, что любой новичок должен пройти сам - от начала и до конца. Разберитесь досконально в логике кнопки, она не слишком хитрая. И напишите СВОЮ библиотеку.
Работа с кнопкой - это то, что любой новичок должен пройти сам - от начала и до конца. Разберитесь досконально в логике кнопки, она не слишком хитрая. И напишите СВОЮ библиотеку.
В общем-то это верно, но... Справедливости ради, я написал свою библиотеку не из желания разобраться, а потому, что все, мною пощупанные, кнопочные библиотеки почему-то оперируют флагами состояний (isClick, isHold и т.д.), а мне, в прошлом "писателю" прикладных программ под винду, было привычнее работать с событиями кнопки. Вот эту событийность с учетом фактической однозадачности авр-ок я и попытался реализовать. Т.е. исключительно из-за неудовлетворенности имеющимися "материалами". А попадись мне библиотека, которая бы меня удовлетворила, или если бы я никогда раньше не писал под винду - скорее всего ничего сам изобретать не стал бы )))