Первоначально эта статья задумывалась как продолжение Еще одни часы на Ардуине. Часть 2. Выводим время на экран . Но потом решил что будет лучше "освоится с кнопками отдельно", а потом эти наработки - применим к построению часов.
Поэтому, в этой статье я буду использовать вывод в Serial, а не на экран. Что-бы те у кого нет такого LCD KeyPad Shiled могли повторить у себя мои эксперименты с помощью обычных кнопок и резисторов.
Если вы будете собирать cамостоятельно не обязательно брать "в точности такие же номиналы резисторов", мы все равно будет учится "калибровать скетч" под те резисторы которые удалось найти :)
Согласно документации на шилд кнопки этого шилда подключены к пину A0.
Когда мы нажимаем кнопку у нас образуется делитель напряжения . Его верхнее плечо равно 2K, а нижние - зависит от того какую кнопку мы нажали. C помощью A0 пина мы замеряем какое напряжение образовалось на этом делителе и так узнаем "какая кнопка была нажата".
Давайте посмотрим что происходит когда мы нажимаем кнопку LEFT. Ток пройдет через резистор R2 (верхние плечо делителя) и пойдет через резисторы R3,R4,R5 , через кнопку, в землю. Как мы знаем (надеюсь) последовательное соединение резисторов можно мысленно заменить одним резистором с номиналом равным их сумме. Складываем R+R4+R5=0.33K+0.62K+1K=1.95K . Это у нас получился номинал нижнего плеча делителя при нажатой кнопке LEFT. Верхнее плечо мы уже знаем - 2K. Далее с помощью закона ома, калькулятора или онлайн сервиса вычисляем что делить 2K/1.95K должен дать нам на выходе 2.47V (при пяти-вольтовом питании) . Это напряжение мы прочитаем с помощью analogRead(A0).
Но analogRead() возвращает нам значение не в вольтах, а в неких абстрактных "попугаях". Из документации мы знаем что "Напряжение поданное на аналоговый вход, обычно от 0 до 5 вольт будет преобразовано в значение от 0 до 1023, это 1024 шага с разрешением 0.0049 Вольт." Значит при нажатии кнопки LEFT analogRead() вернет нам число 2.47V/0.0049V~=504
По этой цифре мы и можем понять что нажата кнопка LEFT.
Вообщем-то, если мы поняли суть делителя. То мы можем немного "схитрить" и сразу высчитывать значение "в попугаях", не занимаясь конвертацией в "вольты". Главное соотношение номинала верхнего и нижнего плеча. Напряжение на делителе вычисляется Uвых.=Uпит. * Rнижнего /(Rверхние+Rнижнее) . В "попугаях" у нас Uпит.=1024.
Подставляем: 1024*1.95/(2+1.95)~=505 (цифра вышла на "один попугай больше" за счет округления, нам это не существенно).
Для закрепления давайте еще посчитаем что выйдет если нажать DOWN. Нижнее плечо, в этом случае, у нас образуется резисторам R4 и R4 , Rнижние=330 Ом + 620 Ом= 0.33K+0.62K=0.95K
Подставляем Uвых=1024*0.95/(2+0.95)~= 330
Значит, при нажатии кнопки DOWN, analogRead(A0) нам будет возвращать цифру 330
Вернее "около этой цифры". Так как реальные, в отличии от идеальных, резисторы имеют погрешность. От процентов до десятков процентов.
Только теперь мы можем понять "почему она именно такая". Что значат эти цифры. И перепроверить производителя если он ошибся. Скажем для кнопки DOWN. Судя по коду кнопка будет опознаваться если analogRead(A0) вернул число в диапазоне от 250 до 450 (точнее 451)
Смотрим "намерянные цифры". У меня DOWN возвращает 253. Что "попадает в диапазон". Кнопка распознается правильно. Хотя и опасно близко к границе диапазона. Может начать "глючить" (температура поменялась и т.п.)
Смотрим кнопку "SELECT'. По коду должна быть в диапазоне 650-850. А у меня - 635. Значит эта функция с моим шилдом будет работать не верно. Вместо SELECT распознает кнопку LEFT.
Но... ниже в комментариях мы видим еще цифры. Для старой версии шилда. Там другие диапазоны. Там SELECT должен лежать в интервале 555-790 - мне подходит :)
DOWN - должен лежать в 195-380 , а у меня 253. Тоже все верно.
LEFT/UP/RIGHT - тоже все совпадает.
Вывод - у меня версия шилда 1.0 Мне нужно закоментировать (или выкинуть) версию кода для V1.1 и использовать "For V1.0"
К сожалению нигде на шилде я не смог найти указания его версии. Так что пришлось выяснять "кто он" вот таким способом.
Обратите внимание, что для btnNONE - у нас нет пина. Так как мы "сменили парадигму". Ушли от "код клавиши", к идее "цифровых пинов". А для обычных пинов - нет пина "никакой" :)
Следующие что мы поменяем в "идеологии". Мы будем проверять не "попадается ли значение analogRead()" в какой-то диапазон. А возьмем "ожидаемое значение" (которое получили с помощью измерительного скетча выше) и будем сравнивать analogRead с ним. Если он "отличаемся" не больше чем, скажем на 50 - cчитаем что кнопка нажата. Если больше - считаем не нажатой.
Но что-бы написать эту функцию нам нужно для каждой кнопки задать "ожидаемые значение analogRead()". Сделаем это с помощью массива структур
Ну а теперь, мы можем написать свою версию digitalReadA(). Которая может читать и обычные цифровые пины, так и "псевдо".
Вот и все.
Теперь мы можем взять любой стандартный пример, скажем
http://www.arduino.cc/en/Tutorial/Switch - включение, выключение светодиода по нажатию обычной кнопки и вся его "переделка" сведется к замене двух строчек :
В качестве inPin мы укажем не D2, а PIN_SELECT и вызов функции digitalRead(inPin) заменим на вызов нашего "расширенного аналога" digitalReadA(inPin)
Сути это не меняет. Просто с нахлобученным шилдом - не видно встроенного светика. Он оказывается "под ним". Поэтому пришлось мигать 10-тым пином. На нем висит подсветка дисплея.
Так что если вы владелец шилда - у вас будет включатся выключатся подсветка при нажатии кнопки SELECT. Если шилда у вас нет и вы сами собирали/подключали кнопки - оставьте outPin=13 как в оригинальном туториале и смотрите на встроенный светодиод.
Поэтому, в этой статье я буду использовать вывод в Serial, а не на экран. Что-бы те у кого нет такого LCD KeyPad Shiled могли повторить у себя мои эксперименты с помощью обычных кнопок и резисторов.
Если вы будете собирать cамостоятельно не обязательно брать "в точности такие же номиналы резисторов", мы все равно будет учится "калибровать скетч" под те резисторы которые удалось найти :)
Железная составляющая
если у вас есть готовый шилд - можно пропустить этот раздел. Для использования кнопок в скетче эти знания - не обязательны. Но если вам любопытно "откуда берутся эти магические цифры", почему analogRead() возвращает именно такие значения, если захотите "еще кнопок добавить", то раздел вам поможет.Согласно документации на шилд кнопки этого шилда подключены к пину A0.
Когда мы нажимаем кнопку у нас образуется делитель напряжения . Его верхнее плечо равно 2K, а нижние - зависит от того какую кнопку мы нажали. C помощью A0 пина мы замеряем какое напряжение образовалось на этом делителе и так узнаем "какая кнопка была нажата".
Давайте посмотрим что происходит когда мы нажимаем кнопку LEFT. Ток пройдет через резистор R2 (верхние плечо делителя) и пойдет через резисторы R3,R4,R5 , через кнопку, в землю. Как мы знаем (надеюсь) последовательное соединение резисторов можно мысленно заменить одним резистором с номиналом равным их сумме. Складываем R+R4+R5=0.33K+0.62K+1K=1.95K . Это у нас получился номинал нижнего плеча делителя при нажатой кнопке LEFT. Верхнее плечо мы уже знаем - 2K. Далее с помощью закона ома, калькулятора или онлайн сервиса вычисляем что делить 2K/1.95K должен дать нам на выходе 2.47V (при пяти-вольтовом питании) . Это напряжение мы прочитаем с помощью analogRead(A0).
Но analogRead() возвращает нам значение не в вольтах, а в неких абстрактных "попугаях". Из документации мы знаем что "Напряжение поданное на аналоговый вход, обычно от 0 до 5 вольт будет преобразовано в значение от 0 до 1023, это 1024 шага с разрешением 0.0049 Вольт." Значит при нажатии кнопки LEFT analogRead() вернет нам число 2.47V/0.0049V~=504
По этой цифре мы и можем понять что нажата кнопка LEFT.
Вообщем-то, если мы поняли суть делителя. То мы можем немного "схитрить" и сразу высчитывать значение "в попугаях", не занимаясь конвертацией в "вольты". Главное соотношение номинала верхнего и нижнего плеча. Напряжение на делителе вычисляется Uвых.=Uпит. * Rнижнего /(Rверхние+Rнижнее) . В "попугаях" у нас Uпит.=1024.
Подставляем: 1024*1.95/(2+1.95)~=505 (цифра вышла на "один попугай больше" за счет округления, нам это не существенно).
Для закрепления давайте еще посчитаем что выйдет если нажать DOWN. Нижнее плечо, в этом случае, у нас образуется резисторам R4 и R4 , Rнижние=330 Ом + 620 Ом= 0.33K+0.62K=0.95K
Подставляем Uвых=1024*0.95/(2+0.95)~= 330
Значит, при нажатии кнопки DOWN, analogRead(A0) нам будет возвращать цифру 330
Вернее "около этой цифры". Так как реальные, в отличии от идеальных, резисторы имеют погрешность. От процентов до десятков процентов.
А можно как-то не заниматься этими расчетами?
Ну конечно можно. Мы может просто подключить все эти резисторы/кнопки к арудине, начать нажимать кнопки и смотреть что там образуется на analogRead(A0) :)
Вливаем вот такой скетчик:
#define SERIAL_SPEED 9600 #define KEYS_INPUT_PIN A0 // аналоговый вход на который через резисторы привешены кнопки #define SAMPLES 10 // сколько раз, для усреднения будем читать кнопку #define SAMPELS_DELAY 100 // пауза между замерами #define DETECT_DIFF 30 // насколько значение KEYS_INPUT_PIN должно отличаться от NO_KEYS_LEVEL что-бы мы поняли что "кнопка нажата нужно замерять" //в эти переменые будем делать наши замеры int avg; // среднее значение int max; // максимально значение int min; // минимальное // int NO_KEYS_LEVEL; // тут будем хранить значение KEYS_INPUT_PIN означающие "кнопки не нажаты" void setup(){ Serial.begin(SERIAL_SPEED); Serial.println("Please release all keys"); // не нажимайте пока кнопки delay(500); // даем время убрать руки с кнопок Serial.println("Measure NO_KEYS" ); // делаем замер KEYS_INPUT_PIN когда ни одна кнопка не нажата readSamples(); NO_KEYS_LEVEL=avg; // запомнили какой уровень означает "кнопка не нажата" printLevels(); } void loop(){ if(abs(analogRead(KEYS_INPUT_PIN ) - NO_KEYS_LEVEL)>DETECT_DIFF){ // нажата какая-то кнопка Serial.print("Start measure...."); readSamples(); // кнопку нужно продолжать держать, не отпускать Serial.println("done. Please release key"); printLevels(); delay(2000); // даем время убрать руку с кнопки } } // фукнция делает SAMPLES замер и находит их среднее, максимум и минимум void readSamples(){ // вначале все сбрасываем min=1024; max=0; // вводим временную переменную float, //что-бы на малых значениях не терять точность из округрления float tmpAvg; for(unsigned int i=0;i<SAMPLES;i++){ int val=analogRead(KEYS_INPUT_PIN); // делаем замер //ищем максимум/минимум if(valmax)max=val; // добавляем замер к среднему tmpAvg+=((float)val/SAMPLES); delay(SAMPELS_DELAY); } avg=round(tmpAvg); // округляем среднее до целого } // выводит среднее, минимальное и максимальное значение замеров void printLevels(){ Serial.print("avg=");Serial.print(avg,DEC); Serial.print(", min=");Serial.print(min,DEC); Serial.print(", max=");Serial.print(max,DEC); Serial.println(); }
Открываем Serial монитор и нажимаем по очереди кнопки RIGHT/UP/DOWN/LEFT/SELECT
На моем шилде у меня вывелось такое (держим кнопку пока не появится надпись "Please release key"):
Please release all keys Measure NO_KEYS avg=1023, min=1023, max=1023 Start measure....done. Please release key avg=0, min=0, max=0 Start measure....done. Please release key avg=98, min=97, max=98 Start measure....done. Please release key avg=253, min=253, max=254 Start measure....done. Please release key avg=405, min=405, max=405 Start measure....done. Please release key avg=635, min=635, max=635
Что в "переводе" означает такие значения для кнопок
- ничего не нажато - 1023
- RIGHT - 0
- UP - 98
- DOWN - 253
- LEFT - 405
- SELECT - 635
Как видите значение отличается от "расчетных". Тут возможны два объяснения: либо я ошибся в расчетах , либо это погрешность резисторов + сами кнопки дорожки и т.п. - тоже имеют какое-то сопротивление. Я склоняются в версии "погрешность". Потому что сам производитель указывает что для версии шилда V1.0 и V1.1 analogRead возвращает чуть-чуть разные значения. При этом судя по схеме номиналы резисторов на кнопках у них - одинаковые. Значит разницу можно объяснить либо погрешностью, либо производитель использует резисторы отличные от указанных в документации.
Но в данном случае это - не важно.
Но в данном случае это - не важно.
Главное что теперь я знаю какие значение возвращает analogRead(A0) именно на моем конкретном экземпляре шилда. Я просто буду пользоваться именно этими цифрами при дальнейшем написании кода. Вы можете сделать аналогичный замер на своем шилде, и соответственно "подправить примеры" если будет такая необходимость.
Так как я планирую в будущем для работы с кнопками сделать отдельную библиотеку, я буду благодарен вам если вы сделаете замер на своем шилде и дадите полученные цифры в комментариях к этой статье. Хочу "набрать статистику и использовать в качестве "по умолчанию" в библиотеке. Поэтому, пожалуйста, не забудьте указать какую версию шилда вы используете.
Так а как же читать кнопки?
Простейший путь - вы уже знаете. Взять пример от производителя . Ключевая функция в немint read_LCD_buttons() { adc_key_in = analogRead(0); // read the value from the sensor // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 // we add approx 50 to those values and check to see if we are close if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result // For V1.1 us this threshold if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 250) return btnUP; if (adc_key_in < 450) return btnDOWN; if (adc_key_in < 650) return btnLEFT; if (adc_key_in < 850) return btnSELECT; // For V1.0 comment the other threshold and use the one below: /* if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 195) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 555) return btnLEFT; if (adc_key_in < 790) return btnSELECT; */ return btnNONE; // when all others fail, return this... }
Только теперь мы можем понять "почему она именно такая". Что значат эти цифры. И перепроверить производителя если он ошибся. Скажем для кнопки DOWN. Судя по коду кнопка будет опознаваться если analogRead(A0) вернул число в диапазоне от 250 до 450 (точнее 451)
Смотрим "намерянные цифры". У меня DOWN возвращает 253. Что "попадает в диапазон". Кнопка распознается правильно. Хотя и опасно близко к границе диапазона. Может начать "глючить" (температура поменялась и т.п.)
Смотрим кнопку "SELECT'. По коду должна быть в диапазоне 650-850. А у меня - 635. Значит эта функция с моим шилдом будет работать не верно. Вместо SELECT распознает кнопку LEFT.
Но... ниже в комментариях мы видим еще цифры. Для старой версии шилда. Там другие диапазоны. Там SELECT должен лежать в интервале 555-790 - мне подходит :)
DOWN - должен лежать в 195-380 , а у меня 253. Тоже все верно.
LEFT/UP/RIGHT - тоже все совпадает.
Вывод - у меня версия шилда 1.0 Мне нужно закоментировать (или выкинуть) версию кода для V1.1 и использовать "For V1.0"
К сожалению нигде на шилде я не смог найти указания его версии. Так что пришлось выяснять "кто он" вот таким способом.
И все это было только ради того что-бы выяснить какая версия шилда?
Нет конечно :) На функцию "от производителя" мы смотрели только "для старта". Мы напишем свою. Другую :) Главная цель ее написания - что-бы ее использование было максимально похоже на обычный digitalRead(). Где мы передаем номер пина и получаем его состояние. Так и тут, мы будем писать такую функцию которая можно спросить "а не нажата ли кнопка SELECT?". Этот подход имеет то преимущество, что для аналоговых кнопок можно будет пользоваться всеми примерами и подходами которые мы применяем для обычных цифровых кнопок. Мы "спрячем" разницу между "аналоговыми" и "обычными" кнопками.
Для начала мы "придумаем" для них нумерацию. Предлагаю эти "псевдо-цифровые-кнопки" начать нумеровать скажем с сотни (просто круглое число, которое заведомо выше чем количество реальных пинов даже на мега платах).
Поместить вверху скетча что-то типа:
#define A_PINS_BASE 100 // номер с которого начинается нумерация наших "псевдо-кнопок". #define PIN_RIGHT 100 #define PIN_UP 101 #define PIN_DOWN 102 #define PIN_LEFT 103 #define PIN_SELECT 104
Обратите внимание, что для btnNONE - у нас нет пина. Так как мы "сменили парадигму". Ушли от "код клавиши", к идее "цифровых пинов". А для обычных пинов - нет пина "никакой" :)
Следующие что мы поменяем в "идеологии". Мы будем проверять не "попадается ли значение analogRead()" в какой-то диапазон. А возьмем "ожидаемое значение" (которое получили с помощью измерительного скетча выше) и будем сравнивать analogRead с ним. Если он "отличаемся" не больше чем, скажем на 50 - cчитаем что кнопка нажата. Если больше - считаем не нажатой.
Но что-бы написать эту функцию нам нужно для каждой кнопки задать "ожидаемые значение analogRead()". Сделаем это с помощью массива структур
struct A_PIN_DESC{ // определяем структуру которой будем описывать какое значение мы ожидаем для каждого псевдо-пина byte pinNo; // номер пина int expectedValue;// ожидаемое значение }; A_PIN_DESC expected_values[]={ // ожидаемые значения для псевдо-кнопок { PIN_RIGHT,0}, { PIN_UP,98}, { PIN_DOWN,253}, { PIN_LEFT,405}, { PIN_SELECT,635} }; #define A_PINS_COUNT sizeof(expected)/sizeof(A_PIN_DESC) // вычисляем сколько у нас всего "псевдо-кнопок" заданно. #define A_POSSIBLE_Aberration 50 // допустимое отклонение analogRead от ожидаемого значения, при котором псевдо кнопка считается нажатой
Ну а теперь, мы можем написать свою версию digitalReadA(). Которая может читать и обычные цифровые пины, так и "псевдо".
bool digitalReadA(byte pinNo){ if(pinNo<A_PINS_BASE)return digitalRead(pinNo); // если номер пина маленький - значит это настоящий пин. читаем его "по обычному", через digitalRead() for(byte i=0;i<A_PINS_COUNT;i++){ // ищем описание нашего всевдо-пина A_PIN_DESC pinDesc=expected_values[i];// берем очередное описание if(pinDesc.pinNo==pinNo){ // нашли описание пина? int value=analogRead(A0); // производим чтетине аналогово входа return (abs(value-pinDesc.expectedValue)<A_POSSIBLE_ABERRATION); // возвращаем HIGH если отклонение от ожидаемого не больше чем на A_POSSIBLE_ABERRATION } } return LOW; // если не нашли описания - считаем что пин у нас LOW }
Вот и все.
Теперь мы можем взять любой стандартный пример, скажем
http://www.arduino.cc/en/Tutorial/Switch - включение, выключение светодиода по нажатию обычной кнопки и вся его "переделка" сведется к замене двух строчек :
В качестве inPin мы укажем не D2, а PIN_SELECT и вызов функции digitalRead(inPin) заменим на вызов нашего "расширенного аналога" digitalReadA(inPin)
/* Read Analog Keys 2013 by alxarduino@gmail.com http://alxarduino.blogspot.com/2013/09/ReadAnalogKeys.html */ #define A_PINS_BASE 100 // номер с которого начинается нумерация наших "псевдо-кнопок". #define PIN_RIGHT 100 #define PIN_UP 101 #define PIN_DOWN 102 #define PIN_LEFT 103 #define PIN_SELECT 104 struct A_PIN_DESC{ // определяем структуру которой будем описывать какое значение мы ожидаем для каждого псевдо-пина byte pinNo; // номер пина int expectedValue;// ожидаемое значение }; A_PIN_DESC expected_values[]={ // ожидаемые значения для псевдо-кнопок { PIN_RIGHT,0}, { PIN_UP,98}, { PIN_DOWN,253}, { PIN_LEFT,405}, { PIN_SELECT,635} }; #define A_PINS_COUNT sizeof(expected_values)/sizeof(A_PIN_DESC) // вычисляем сколько у нас всего "псевдо-кнопок" заданно. #define A_POSSIBLE_ABERRATION 50 // допустимое отклонение analogRead от ожидаемого значения, при котором псевдо кнопка считается нажатой bool digitalReadA(byte pinNo){ if(pinNo<A_PINS_BASE)return digitalRead(pinNo); // если номер пина маленький - значит это настоящий пин. читаем его "по обычному", через digitalRead() for(byte i=0;i<A_PINS_COUNT;i++){ // ищем описание нашего всевдо-пина A_PIN_DESC pinDesc=expected_values[i];// берем очередное описание if(pinDesc.pinNo==pinNo){ // нашли описание пина? int value=analogRead(A0); // производим чтетине аналогово входа return (abs(value-pinDesc.expectedValue)<A_POSSIBLE_ABERRATION); // возвращаем HIGH если отклонение от ожидаемого не больше чем на A_POSSIBLE_ABERRATION } } return LOW; // если не нашли описания - считаем что пин у нас LOW } // ***************************************** ADAPTED FOR USE Analog keys arduino tutorial:http://www.arduino.cc/en/Tutorial/Switch /* switch * * Each time the input pin goes from LOW to HIGH (e.g. because of a push-button * press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's * a minimum delay between toggles to debounce the circuit (i.e. to ignore * noise). * * David A. Mellis * 21 November 2006 */ int inPin = PIN_SELECT; // the number of the input pin int outPin = 10; // the number of the output pin int state = HIGH; // the current state of the output pin int reading; // the current reading from the input pin int previous = LOW; // the previous reading from the input pin // the follow variables are long's because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long time = 0; // the last time the output pin was toggled long debounce = 200; // the debounce time, increase if the output flickers void setup() { pinMode(inPin, INPUT); pinMode(outPin, OUTPUT); } void loop() { reading = digitalReadA(inPin); // if the input just went from LOW and HIGH and we've waited long enough // to ignore any noise on the circuit, toggle the output pin and remember // the time if (reading == HIGH && previous == LOW && millis() - time > debounce) { if (state == HIGH) state = LOW; else state = HIGH; time = millis(); } digitalWrite(outPin, state); previous = reading; }Правда мне пришлось сделать еще одно косметическое изменения. Я поменял номер пина на котором мигаем диодом с 13-того (встроенный в ардуину диод), на 10-тый. outPin = 10 сделал.
Сути это не меняет. Просто с нахлобученным шилдом - не видно встроенного светика. Он оказывается "под ним". Поэтому пришлось мигать 10-тым пином. На нем висит подсветка дисплея.
Так что если вы владелец шилда - у вас будет включатся выключатся подсветка при нажатии кнопки SELECT. Если шилда у вас нет и вы сами собирали/подключали кнопки - оставьте outPin=13 как в оригинальном туториале и смотрите на встроенный светодиод.
Что дальше?
На сегодня я прощаюсь с вами. В дальнейшем для удобства использования я оформлю это все в виде библиотеки (она будет опубликована). Так же в ней хочется решить следующие задачи:
- Возможность работать с несколькими аналоговыми входами (возможно нам еще больше кнопок понадобится)
- "Анти-дребезг" из коробки.
- Помогалки для отлавливания событий типа "кнопка изменила свое состояние"
- Различие между "краткими нажатиями", "длинными" и "удержание..."
- и т.п.
Добъемся что-бы "с кнопками было работать просто". И с помощью этой библиотеки допишем реализацию наших часов.
Красивый код "наше все". :-)
ОтветитьУдалитьС нетерпением ждем продолжения (и исправления мелких опечаток в коде, вроде такой: if(valmax)max=val; а то вдруг не поймут)
И по кнопкам: (шилд судя по проверке - 1.1)
RIGHT=0
UP=145
DOWN=329
LEFT=505
SELECT=741
Использовал ваш код.
ОтветитьУдалитьАдаптировал его с обработкой короткого и длительного нажатия - и получилось!
Спасибо за ваш труд.
Здравствуйте, можете пожалуйста показать как Вы различали длинные и короткие нажатия? заранее спасибо!
УдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьЭтот комментарий был удален автором.
УдалитьДаёшь продолжение!
ОтветитьУдалитьif(valmax)max=val;
ОтветитьУдалитьTEST_KEY_ANALOG.ino: In function 'void readSamples()':
TEST_KEY_ANALOG:65: error: expected `)' before 'if'
где ошибка,не понимаю, как трактовать
f(valmax) max=val;
Удалить8К у них там похоже на схеме пропущено, посмотрим что ответят: http://www.dfrobot.com/index.php?route=product/product&keyword=DFR0009&category_id=0&description=1&model=1&product_id=51#comment-2030842201
ОтветитьУдалитьточнее, оно там неявно набегает :)
УдалитьБиблиотека готова, или проект заброшен?
ОтветитьУдалитькупить семена адениума
ОтветитьУдалитьЭкзотические растения свежиесемена адениума и другие комнатные цветы.
еще