Официальный сайт компании Arduino по адресу arduino.cc
энкодер для управления громкостью
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Сб, 14/02/2015 - 02:09
Привет.
Пытаюсь в машину поставить планшет и очень уж хочется поставить энкодер для управления громкостью...
В принципе всё вроде как работает. Единственно что какие-то лаги при попытке изменить уровень громкости... он то меняется еле-еле, то резко довольно таки резко поднимается вдвое...
Принцип управления - замыкаю контакты кнопок на дешёвенькой китайской усб звуковухе. До куче контроллер ещё и переключает реле своей кнопкой.
Проблем с кнопкой которая управляет реле не замечено...а вот с энкодером не айс... может есть какой-то другой способ кроме делэя что-б замкнуть контакт на какое-то время и потом опять его разомкнуть?
unsigned long currentTime; unsigned long loopTime; const int pin_A = 0; // pin 0 const int pin_B = 1; // pin 1 unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; const int button = 3; //пин кнопки вкл/выкл const int relay = 13; //пин управления реле void setup() { // declare pin 9 to be an output: pinMode(9, OUTPUT); // устанавливаем pin 9 как выход + pinMode(10, OUTPUT); // устанавливаем pin 10 как выход - pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); currentTime = millis(); loopTime = currentTime; pinMode(relay, OUTPUT); pinMode(button, INPUT); } void loop() { currentTime = millis(); if(currentTime >= (loopTime + 5)){ // проверяем каждые 5мс (200 Гц) encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера encoder_B = digitalRead(pin_B); // считываем состояние выхода Б энкодера if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю if(encoder_B) { // выход В в полож. сост., значит вращение по часовой стрелке digitalWrite(9, HIGH); delay(500); digitalWrite(9, LOW); } else { // выход В в 0 сост., значит вращение против часовой стрелки digitalWrite(10, HIGH); delay(500); digitalWrite(10, LOW); } } encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла loopTime = currentTime; } if (digitalRead(button)==HIGH){ if (digitalRead(relay)==HIGH){digitalWrite(relay,LOW);delay(300);}else{digitalWrite(relay,HIGH);delay(300);} } }
А зачем в сетапе строки 18 и 19?
хз. я не курил тот мануал особо детально. Это изначально было примером как работать с энкодером для управления яркостью светодиода. Я лишь немного подогнал под себя тот пример =)
http://cxem.net/arduino/arduino8.php
9 и 10 выходы у вас подпаяны к кнопкам управления громкости планшета?
Почему еле еле увеличивается уменьшается это понятно, что из-за delay, пока вы в delay энкодер продолжает выдавать импульсы которые вы не учитываете, поэтому большую часть просто теряете отсюда и такой эффект.
А резкое увеличение вполне может быть связано с особенностью планшета. Короткое нажатие это на один шаг увеличить громкость, а длинное, вполне может хватить 500 быстрое (в андроиде так, например). Т.е. чуть чуть передержали и сразу несколько ступений громкости получили.
9 и 10 выходы через резисторы подключены у транзисторам.
вот так примерно - https://drive.google.com/file/d/0BxUnFu94i50SdG5JN3FhOFlJeXc/view?usp=sharing
проверял работу на винде покамест.
Сами кнопки замыкаются не на планшете напрямую, а на усб звуковой карте. резкое оно не то чтобы резкое... оно как раз плавное но сразу примерно вдвое увеличивает громкость...
Я вообще думаю может это связано как-то с тем что цикл обработки энкодера выполняется раз в 5мс... может это как-то связано в тем что там внутри делэй стоит... что-то типа рассинхронизации получается...
Так у вас и нет цикла 5мс в рабочем полождении. 5мс только в простое, а как только начинаете крутить у вас сразу цикл 500мс из-за делаев. Вот если будите крутить так чтобы один щелчок энкодера был раз в пол секунды хотябы а лучше и раз в секунду, всё будет чётко работать.
Надо избавляться от delay как минимум, а там уже видно будет.
вот я и спрашивал - как можно выставить пин в 1 на 100-200мс и потом опять в 0 без делэя... пока мне ничего не придумалось =\
хотя есть одна идея..... сейчас попробую =)
Конечно можно, BlinkWithoutDelay в помощь
а вот такой вопрос возник... что выдаёт энкодер когда он не крутится никуда?
я вот подумываю в этот цикл энкодера при вращении в одну сторону - замыкать и не размыкать контакт 9 но разомкнуть 10 и наоборот. но мне тогда надо при прекращении вращения разомкнуть оба...
Я так понимаю у вас инкрементный энкодер а не абсолютный, значит ничего не выдаёт.
Я с энкодарами вплотную не работал, но если бы вот пярм сейчас не поленился и сходил в гараж раскурочил старую магнитолу вытащил оттуда энкодер принёс его домой и подключил, то действовал бы примерно так :)
В цикле loop читаю энкодер (тем кодом что у вас есть) с частотой в 200Гц и умеличию значение переменных volume_up и volume_down. После чтения энкодера (всё в том же loop) в зависимости он значений volume_up/down (пока не 0 грубо говоря) давал бы высокий уровень на выход и уменьшал значение переменной на 1. Тогда при остановки вращения энкодера звук прибавится/убавится пока переменная 0 не станет, а потом будет просто крутиться в цикле и ждать новых вращений энкодера.
Ну как-то так :) Хотя думаю есть и более красивые решения, может кто-то отзовётся из тех кто сталкивался с энкодерами поближе
не ну это имхо немного не то. громкость должна реагировать в процессе пока крутится энкодер а не после... имхо...
Так то что я описал и есть в процессе. Я имел ввиду что после того как прекратили крутить вы получите две переменных со значением 0 по которым и сможете оба выхода установить в LOW
прпробовал так - не пашет =\ очень медленно и почему-то только увеличивается громкость... не уменьшается... видимо слишком часто цикл выполняется и если не быстро крутить - получается что размыкается кнопка быстрее чем успеет сработать...
ок попробую покурить... что-то голова совсем с утра не варит =) навер надо к коням сходить сначала, а ардуинку вечером мучать )
ну скажем так - работает намного лучше, но если крутить быстро энкодер - тупит тоже... если неспешно - то всё красиво и плавно получается =)
duh, а зачем вам usb-звуковуха, в планшете же есть свой выход аудио? Можно было бы просто купить Usb-регулятор громкости на енкодере, и никаких забот. Или можно собрать такой регулятор самому, (http://obruboff.ru/usb-volume-control-ver-2/ ) там всего несколько деталей Ещё интересней что нибудь через bluetooth придумать..
А почему 20 всегда присваивается? Империческим путем установилось? :) Я бы в 7 строке просто делал vol_up++ а если HIGH держится небольшое время и надо чтобы подольше держался для срабатывания то в 7 строке делал бы vol_up += 2 (3, 5, 10), а в 18 строке оставил как есть уменьшение на 1.
++ не катит - не работает. она сразу-же обнуляется и задержка маленькая слишком. 20 - это 100мс заедржка =) т.е получается всегда нажата кнопка какбыдто пока крутится энкодер. перестали крутить - чере 100 мс прекращает наживаться кнопка )
шоп я ещё заранее знал что есть такие усб регуляторы =) знакомый сказал заказать звуковуху и с неё сделать управления...а я повлся =) ну а для планшета надо переделаывать.... на звуковухе кнопки наживаются на землю, а на планшете хз куда - надо оба контакта замыкать.. у меня плата разведена так что кнопки на землю замыкаться будут
duh, на планшете ничего замыкать не надо :) Усб регулятор громкости -по факту обрезок мультимедия-клавиатуры. Есть готовые например: http://store.griffintechnology.com/powermate А можно сделать и самому (ссылку давал) . А есть вообще полная юсб-карта с енкодером.
Вы представляете себе то, что вы хотите сделать? Это ж какая масса проводов будет болтаться. планшет-юсб карта, юсб карта -ардуино, юсб карта - усилитель, ардуино -питание. Я бы на вашем месте сделал вообще беспроводный регулятор громкости )
беспроводной тоже будет когда-то. а все провода убираются внутрь за планшет и не будут видны совсем ;)
Кстати ссылка первая не открылась =\
http://pccar.ru/showthread.php?t=21401
вообще почему я взялся за контроллер - мне надо управлять реле для включения и выключения планшета. в данном случае регулятор громкости + кнопка будут выполнены одним девайсом. в итоге на приборке будет торчать одна ручка и одна дырка под усб.