помогите с антидребезгом
- Войдите на сайт для отправки комментариев
Втр, 24/05/2016 - 10:55
всем привет. В программировании по сути 0 :)
решаю следующий вопрос по антидребезгу, поправте пожалуйста что и как неверно:
#define midi_cc 0xB0 #define midiOFF 0x00 #define midiON 0x7F #define midi_SW_CC1 0x50 long debouncedelay = 3000; const int button = 2; void setup() { Serial.begin(112500); pinMode(button, INPUT); } void loop { if (button == HIGH) { long currenttime = millis(); if(millis() - currenttime >= debouncedelay){ midicommand(midi_cc,midi_SW_CC1, midiON); } } } void midicommand(int channel, int pitch, int velocity){ Serial.write(channel); Serial.write(pitch); Serial.write(velocity); delay(20); }
В Вашем коде кнопка не сработает, попробуйте так:
Переменная button всегда будет HIGH, потому что она всегда = 2 (digitalRead() в скетче отсутствует).
Переменная button всегда будет HIGH, потому что она всегда = 2 (digitalRead() в скетче отсутствует).
digitalRead есть в коде, просто не делал копи паст, пропустил по невнимательности.
В Вашем коде кнопка не сработает, попробуйте так:
f_kn1 - это запоминание состояние кнопки?
Код немного не правильно работает если выставить debouncedelay 3000. Я так понимаю, при нажатии кнопки(когда ножка поймала 1), должна происходить задержка исполнения команды до стабилизации кнопки. В данном коде выходит немного наоборот, то-есть, при коротком нажатии кнопки, ничего не происходит, команда запускается только при удержании кнопки по времени 3000мс и выше. При delay(3000) все правильно работает, коротко нажал, задержка на 3000мс -> выполнение команды.
115200......
не копи паст, показал просто общую картину кода.
Вообще-то даже если батон читается с пина и сравнивается с хай, приведенный код работать тоже не может. вы бы привели полноценный кусок кода копипастом, а то так гадать можно очень долго что там уже есть, а что надо ещё подправить ..
и сразу возникает вопрос: а почему бы не воспользоваться титановым лисапедом, прибитым сверху "гвоздиком"?
Вот, немного обдумав, переписал(код прилагаю внизу). Обработка одиночного нажатия, плюс, анти-дребезг. Следующая проблема в том, что кнопка иногда не срабатывает, а иногда инвертирует действие, то-есть, включает на отжимание(отпускание) кнопки.
ggreenpowerp, я тут как-то приводил осциллограммы дребезга. Основной дребез идёт не при нажатии на кнопку (в этот момент дребезга вообще зачастую не бывает), а в момент отпускания. И длиться он для среднестатической кнопки -около 0,5 мс. А вы как я понял боритесь с дребезгом именно в момент нажатия, отсюда и не получаете результат. Так что нужно полностью изменить логику.
ggreenpowerp, я тут как-то приводил осциллограммы дребезга. Основной дребез идёт не при нажатии на кнопку (в этот момент дребезга вообще зачастую не бывает), а в момент отпускания. И длиться он для среднестатической кнопки -около 0,5 мс. А вы как я понял боритесь с дребезгом именно в момент нажатия, отсюда и не получаете результат. Так что нужно полностью изменить логику.
Попробую сегодня вечером поставить таймер на отпускание, где-то 10мс думаю хватит. На нажим тоже оставлю, где-то 3мс, думаю тоже хватит.
Спасибо за помощь.
сделал антидребезг при отжимании(отпускании) кнопки. Результат тот же. Иногда работает через раз, плюс, иногда работает почему-то в инвертированном состоянии(отпускаешь кнопку - действие, нажимаешь - ничего). Не могу понять с чем связано. Код прилагаю.
Я не понимаю , зачем бороться с антидрезезгом. Программы , как я думаю, должны что-то делать. Тем более вроде "принимать участие в жизни человека". Процессор все же считает очень быстро. Вот и вылезают проблемы, которые просто не зачем решать.
Разбейте время на 0,1 сек . Вот и раз в 0,1 сек обрашивайте клавишу и сохраняйте ее состояние в памяти, нажата/отжата.
класс титановый велосипед для тактовой кнопки.
ggreenpowerp, вы удлинили скетч, но логику так и не изменили. Вот смотрите, условие сработало по HIGH, вы кнопку отпустили. Появился первый LOW - сразу вошли по условию 51 строки, затем сразу по условию 53 строки, и обработали всё до 58 строки. И тут пришёл дребезг после LOW. И по дребезгу мы опять влетаем на исполнение..
класс титановый велосипед для тактовой кнопки.
Я понимаю что чужими трудами легко обойтись, но, поскольку я только учусь(полный нуб), думаю что понять, что да как, очень даже нужно. Надо понимать смысл работы элементарных вещей, а не сразу "master of puppets" :)
изучи простой код класс титановый велосипед StopWatch. и тебе станет всё понятно - остальное заморочки с условиями логических состояний булевых переменных.
ggreenpowerp, вы удлинили скетч, но логику так и не изменили. Вот смотрите, условие сработало по HIGH, вы кнопку отпустили. Появился первый LOW - сразу вошли по условию 51 строки, затем сразу по условию 53 строки, и обработали всё до 58 строки. И тут пришёл дребезг после LOW. И по дребезгу мы опять влетаем на исполнение..
Если честно, я совсем не понимаю как решить все это другой логикой. Буду думать. Может сойдет на меня озарение :)
изучи простой код класс титановый велосипед StopWatch. и тебе станет всё понятно - остальное заморочки с условиями логических состояний булевых переменных.
Спасибо. Постараюсь догнать все тонкости работы кода. Если что, можно в личку вам писать?
личка форуме отсутсвует - пиши в теме кода, который тебе не понятен.
личка форуме отсутсвует - пиши в теме кода, который тебе не понятен.
А слона я не заметил) ок. Буду писать в теме кода.
ggreenpowerp, вы удлинили скетч, но логику так и не изменили. Вот смотрите, условие сработало по HIGH, вы кнопку отпустили. Появился первый LOW - сразу вошли по условию 51 строки, затем сразу по условию 53 строки, и обработали всё до 58 строки. И тут пришёл дребезг после LOW. И по дребезгу мы опять влетаем на исполнение..
Вопрос:
А как мог прийти дребезг, если я его вроде убрал, ну точнее, заморозил считывание на 10 мс до стабилизации состояния LOW?
ggreenpowerp, я уже сам запутался в вашем коде) На всякий случай -как кнопка включена, стягивающий резистор есть? Вы же ловите HIGH, значит вход должен быть притянут к gnd
ЗЫ: вроде понял -у вас два ограничителя времени первый по HIGH , второй про LOW. Но пока вы держите кнопку -10 мс первого ограничения уже пройдут, и команда выполниться повторно от дребезга как только вы отпустите кнопку.
ggreenpowerp, я уже сам запутался в вашем коде) На всякий случай -как кнопка включена, стягивающий резистор есть? Вы же ловите HIGH, значит вход должен быть притянут к gnd
ЗЫ: вроде понял -у вас два ограничителя времени первый по HIGH , второй про LOW. Но пока вы держите кнопку -10 мс первого ограничения уже пройдут, и команда выполниться повторно от дребезга как только вы отпустите кнопку.
Да, подтягивающий резистор на землю( 10ком) есть. Переменная "flag" для того, чтобы считать одиночное нажатие, а не бесконечное по удержанию.
Точно, этого не учел. Действительно, пока удерживаю, 10 мс проходит, далее начинаются карусели. Буду думать как изменить. Нужно только одно считывание на один клик.
[/quote] Действительно, пока удерживаю, 10 мс проходит, далее начинаются карусели. Буду думать как изменить. Нужно только одно считывание на один клик.[/quote]
Процессор он перепад не ловит. Он ловит состояние, 0 или 1, нажата или отпущено. Так что програмно надо ловить перепад, когда кнопку нажимают 1-> 0 или отжимают 0->1 . Тогда у вас одно нажатие - оно выполнение этой программы. Но есть влияние дребезга , когда процессор может одно нажатие посчитать множественым. Вот для этого есть принцип 1 измерение , пауза больше чем время дребезга и еще измерение.
То есть банально разнести события измерения уровня опроса клавиши. Конечно тогда возникает погрешность измерения временного интервала. Временем нажатия считать 1 измерение или 2 измерение. Немного отвлекаясь если у вас есть линейка с шагом в 1 мм, то измерить длину с точностью 0,1 мм у вас хрен получится. Так и с кнопками. Если у вас дребезжащая кнопка, то точность + - дребезг. Или берите кнопку без дребега- на датчиках Холла.
Процессор он перепад не ловит. Он ловит состояние, 0 или 1, нажата или отпущено. Так что програмно надо ловить перепад, когда кнопку нажимают 1-> 0 или отжимают 0->1 . Тогда у вас одно нажатие - оно выполнение этой программы. Но есть влияние дребезга , когда процессор может одно нажатие посчитать множественым. Вот для этого есть принцип 1 измерение , пауза больше чем время дребезга и еще измерение.
То есть банально разнести события измерения уровня опроса клавиши. Конечно тогда возникает погрешность измерения временного интервала. Временем нажатия считать 1 измерение или 2 измерение. Немного отвлекаясь если у вас есть линейка с шагом в 1 мм, то измерить длину с точностью 0,1 мм у вас хрен получится. Так и с кнопками. Если у вас дребезжащая кнопка, то точность + - дребезг. Или берите кнопку без дребега- на датчиках Холла.
[/quote]
То есть, вы имеете ввиду, что имея дребезжащую кнопку то, как бы я не старался убрать дребезг программным способом, все равно дребезг будет, в той или иной степени, и избавиться от него полностью программным методом не получиться?
ggreenpowerp, сложно бороться с врагом не видя его в лицо :) Вот примеры дребезга.
Левая картинка полный импульс от кнопки, -правая увеличенный восходящий фронт этого-же импульса. Как видно дребезг длится 1 мс.
Тут левая картинка тоже полный импульс от кнопки, правая картинка -увеличенный нисходящий фронт импульса. Дребезг длиться 2 мс.
Теперь можно написать упрощённый алгоритм обработки кнопки:
Убедиться что всё идеально работает, и наконец всё переделать на функцию нетормозящую Loop. Или плюнуть, и воспользоваться готовой библиотекой :-)))
[/quote] То есть, вы имеете ввиду, что имея дребезжащую кнопку то, как бы я не старался убрать дребезг программным способом, все равно дребезг будет, в той или иной степени, и избавиться от него полностью программным методом не получиться?[/quote]
Дребезг механичесих кнопок не убирают. Просто кнопки очень дешевые, вот и просто снижают последствия как аппаратным, так и программным путем.
http://nauchebe.net/2011/04/knopki-pereklyuchateli-v-sxemax-na-mk/
Вот еще. Скорее всего вам не нужна идеальная кнопка для вашего проекта.
Да и еще. вариант. Подцепить кнопку на аналоговый вход и снимать аналоговый сингнал. Сделать некий аналоговый корпоратор программным путем.
Ну что ж.
Думал думал, и додумал до библиотеки "BOUNCE2". :D
Вылез следующий не понятный момент. Кнопка делает команду midi_SN_CM на третий клик. Запилил еще светодиод в программу, так вот, светодиод включается на первый клик, а вышеупомянутая команда на третий, почему-то. Подскажите пожалуйста, в чем может быть дело?
код конечно прилагаю:
Думал думал, и додумал до библиотеки "BOUNCE2". :D
Вылез следующий не понятный момент.
слушай, ну уже прямо скучно смотреть на твоё путешествие по граблям - реализуй свой проект на том, что не глючит и интуитивно понятно.
затем, разбирайся с персональными тараканами.
Думал думал, и додумал до библиотеки "BOUNCE2". :D
Вылез следующий не понятный момент.
слушай, ну уже прямо скучно смотреть на твоё путешествие по граблям - реализуй свой проект на том, что не глючит и интуитивно понятно.
затем, разбирайся с персональными тараканами.
Придется тащить все моменты библиотеками, так как по сути вообще ни.рена не понимаю:) Буду сегодня изучать ваш «клас титановый велосипед“.
нечего там изучать - брать и юзать.
нечего там изучать - брать и юзать.
Ну что ж. Прикрутил "клас титановый велосипед". Работает точно так же как и "BOUNCE2". Светодиод загорается на первый клик, а команда midi_SW_CC1 только каждый третий.
код:
Светодиод загорается на первый клик, а команда midi_SW_CC1 только каждый третий.
ну, и кто в этом виноват? - светодиод или команда МИДИ и КРЕВЕТКА?
Светодиод загорается на первый клик, а команда midi_SW_CC1 только каждый третий.
ну, и кто в этом виноват? - светодиод или команда МИДИ и КРЕВЕТКА?
в том то и дело что я вообще не знаю кто(что) в этом виноват(то), по-этому и пишу сюда. Знал бы - не писал бы.
в том то и дело что я вообще не знаю кто(что) в этом виноват(то), по-этому и пишу сюда. Знал бы - не писал бы.
а, что здесь понимать - закоменти миди-шмиди и выводи в сериал количество нажатий на кнопку: ты же сомневаешься, что у тебя дребезг или что там.
*про что у тебя тема? про дребезг или про шмиди?
в том то и дело что я вообще не знаю кто(что) в этом виноват(то), по-этому и пишу сюда. Знал бы - не писал бы.
а, что здесь понимать - закоменти миди-шмиди и выводи в сериал количество нажатий на кнопку: ты же сомневаешься, что у тебя дребезг или что там.
*про что у тебя тема? про дребезг или про шмиди?
дребезга нет! Библиотеки "Bounce2" и "титановый велосипед " справились отлично. Спасибо за помощь.
На счет "Шмиди". Просто не хочу создавать новую тему, дабы не нагружать и не засирать форум, одними и теми же вопросами. По этому, если кому не лень, напишите почему команда проходит на третий клик.
Основная тема закрыта(решено). Всем спасибо.
ты бы для начала объяснил, что это вообще такое?
midi_SN_CM(midi_cc, midi_SW_CC1, midiON);
void
midi_SN_CM(
int
channel,
int
pitch,
int
velocity)
ты бы для начала объяснил, что это вообще такое?
midi_SN_CM(midi_cc, midi_SW_CC1, midiON);
void
midi_SN_CM(
int
channel,
int
pitch,
int
velocity)
отправляет в звуковую карту по миди каналу команду.
midi_SN(send)_CM(command)
channel(номер канала на каком работает миди. В данном случае 1(первый(из 16 возможных) 0xB0.
pitch(высота ноты, но, в данном случае команда номер 70(из 127 возможных)) 0x46.
velocity(с какой силой нажата клавиша, но в данном случае или команда 70 вкл или выкл. 0-64 выкл. 65-127 вкл. 0x7F)
итог. Должно одновременно в миди отправить три значения по этому порядку: channel, pitch, velocity.
ну как то так :)
не совсем понятно, где у тебя МИДИ-фейс? МИДИ по сериалу подключено?
а, так, что происходит? - тоже с третьего раза?
не совсем понятно, где у тебя МИДИ-фейс? МИДИ по сериалу подключено?
а, так, что происходит? - тоже с третьего раза?
Да, так тоже пробовал, тоже с третьего раза. Следующий момент. Пакетно три команды отправляет только через if millis()-...... Если антидребезг сделать через delay, то только с третьего раза. Даже не знаю с чем связано.
Следующий момент. Пакетно три команды отправляет только через if millis()-...... Если антидребезг сделать через delay, то только с третьего раза.
перефразируй - существует ли хоть один вариант, когда работает сразу?
Следующий момент. Пакетно три команды отправляет только через if millis()-...... Если антидребезг сделать через delay, то только с третьего раза.
перефразируй - существует ли хоть один вариант, когда работает сразу?
сразу отправляет на первый клик, только так:
все остальные манипуляции с библиотеками, а также при борьбе с дребезгом с помощью delay, приводят к срабатыванию команды только на третий клик.
сразу отправляет на первый клик, только так:
ты сам себе на слово веришь? - убедись, что это не так:
сразу отправляет на первый клик, только так:
ты сам себе на слово веришь? - убедись, что это не так:
я же тебе говорю, что, светодиод загорается с первого раза, так же если включить монитор порта то, команда приход на первый клик, но если я отправляю все в миди вход моей звуковой карты, то, команда исполняется только на третий раз, хотя светодиод загорается каждый клик.
ggreenpowerp, а в этом скетче у вас через 25мс держания кнопки сработает повторно. Так что скорее всего тут тоже с третьего раза, просто тут вы не контролируете ситуацию. Видимо сериал не успевает отправить все три команды подряд, попробуйте команду serial.flush() после каждого байта отсылки.
я же тебе говорю, что, светодиод загорается с первого раза, так же если включить монитор порта то, команда приход на первый клик, но если я отправляю все в миди вход моей звуковой карты, то, команда исполняется только на третий раз, хотя светодиод загорается каждый клик.
слушай, твой тупняк уже утомил - твоя шмиди не работает с одного клика.
я же тебе говорю, что, светодиод загорается с первого раза, так же если включить монитор порта то, команда приход на первый клик, но если я отправляю все в миди вход моей звуковой карты, то, команда исполняется только на третий раз, хотя светодиод загорается каждый клик.
слушай, твой тупняк уже утомил - твоя шмиди не работает с одного клика.
прилагаю тебе гифку которую только что снял:https://drive.google.com/open?id=0B-keRyLxrrvheHhzTGxFLTFXZVE
Три нажатия: светодиод загорелся, потух, загорелся. На третий клик команда миди на экране.
Я понимаю что достал мой тупняк, так не помогай.
ggreenpowerp, а в этом скетче у вас через 25мс держания кнопки сработает повторно. Так что скорее всего тут тоже с третьего раза, просто тут вы не контролируете ситуацию. Видимо сериал не успевает отправить все три команды подряд, попробуйте команду serial.flush() после каждого байта отсылки.
К сожалению не помогло. Спасибо.
На третий клик команда миди на экране.
ну? и, кто виноват, если твоя миди с третьего пинка работает?
я должен читать мануалы к твоей миди?