|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:42 am
мултифункционален бутон + PWM
| Автор |
Съобщение |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
 мултифункционален бутон + PWM
от няколко седмици се боря да направя един контролер за 2 RGB лампи и една и една обикновенна
за целата ми трябва да направя бутон който да различва click, double click and hold работа с MPLAB под С
това е кода до който стигнах последно но така не работи бутона изобщо не засича. Тръгнал съм да го правя със инттерупт защото искам да вкарам и функция която да превърта плавно цветовете .
много съм го закъсал , вече направих кутия за трафа и за контролера , направих и дистанционно което да го ползвам за бутон, направих и водоустоичивите лампи. Мислех че кода няма да ми е толквоа проблем но уви.... та моля някой да даде едно рамо , че немошах да си намеря протеус зада ги тествам направо на машината и трябва постоянно да свалям и закачам което направо вече ме побърква. Чипа е 16f627a
Последна промяна pachuka на Вто Юни 28, 2011 10:29 am, променена общо 1 път
|
| Сря Юни 22, 2011 12:06 am |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Не съм ти гледал целия код, и не съм се мъчил да разбирам какво си правил, но на пръв поглед виждам в прекъсването, че никога няма да стане повече от 2, и съответно няма да влезе в нито едно условие. На всяко викане на прекъсването t0_cnt = 0. Ако я направиш статична въпросната променлива, може и да има някакъв шанс.
|
| Сря Юни 22, 2011 12:20 am |
|
 |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
даа бе защо съм ги оставил там а не при другите , още утре ще пробвам как ще е като ги извадя от там.
Но изобщо в правилна насока ли съм , някой правил ли е енещо подобно, по много техники се наблюдават такива бутони 
|
| Сря Юни 22, 2011 12:42 am |
|
 |
|
bkulev
Ранг: Популярен
Регистриран на: Сря Яну 25, 2006 12:47 pm Мнения: 305 Местоположение: Varna
|
Колега, тази тема е за "Академия".
И аз не съм ти гледал подробно кода, но мога да ти дам някои насоки, които така да се каже са общи при работа с бутони:
- Трябва да разпознаваш натискането и отпускането на бутона, т.е. преходите от едното в другото състояние, обикновенно се постига с прости логически функции приложени към текущото и предишното състояние
- Трябва да приложиш техника против трепкане на контактите, защото всички бутони повече или по малко го правят
- Има различни техники в прекъсване или не, но ако приложението ти не е сложно, не е необходимо да правиш прекъсване. В този случай имай предвид, че сканирането на бутоните се прави с ниска честота, т.е. рядко, защото не е необходимо да е бързо, все пак това е човешки интерфейс
|
| Сря Юни 22, 2011 9:31 am |
|
 |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
на теория ми е ясно как трябва да стане , но писането на кода ми куца.
|
| Съб Юни 25, 2011 4:54 pm |
|
 |
|
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 2:45 am Мнения: 263
|
Koпи & пейст (с допълнението за double-click) от друга подобна тема. Не гарантирам тръгване от раз, щото е нахвърляно набързо.
Само трябва да измислиш как да викаш OneButtonTask() циклично.
 |  |  |  | Код: // Таймерите: 0 = спрян, > 0 = работещ
#define TASK_PERIOD_MS 10 // Период на OneButtonTask(). #define DEBOUNCE_TIME (50 / TASK_PERIOD_MS) // Дебаунс време #define DOUBLE_CLICK_TIME (500 / TASK_PERIOD_MS) // Време между две натискания, което минава за double-click #define BTN_PRESSED 0 // или 1, зависи как е вързан бутона #define pBUTTON pA2 // тук си дефинираш пина, на който си вързал бутона.
typedef enum { IDLE, // бутона е отпуснат DEBOUNCING, // бутона е натиснат и тече дебаунс DEBOUNCED, // бутона е натиснат, дебаунс времето е изтекло, състоянието на бутона е потвърдено DOUBLE_CLICKED, CANCELLED, // бутона е отпуснат преди да е изтекло дебаунс времето RELEASING // чакаме бутона да се отпусне } TStates;
static TStates еState = IDLE;
void OneButtonTask(void) { static UInt16 debounceTimer = 0; static UInt16 doubleClickTimer = 0;
switch (еState) { case IDLE: { if (BTN_PRESSED == pBUTTON) { // Стартираме дебаунс debounceTimer = DEBOUNCE_TIME; еState = DEBOUNCING; }
break; }
case DEBOUNCING: { // Натиснат ли е все още бутона? if (BTN_PRESSED == pBUTTON) { // Да. Дебаунс времето изтекло ли е? if (0 == debounceTimer) { // Да, имаме натискане еState = DEBOUNCED; } } else { // Бутона е отпуснат по време на дебаунс еState = CANCELLED; }
break; }
case DEBOUNCED: { // Тук можеш да свършиш каквото трябва при еднократно натискане на бутона // ..... // // Стартираме таймера за double-click, само ако е изтекъл doubleClickTimer. if (0 == doubleClickTimer) { еState = RELEASING; doubleClickTimer = DOUBLE_CLICK_TIME; } else { еState = DOUBLE_CLICKED; doubleClickTimer = 0; }
break; }
case DOUBLE_CLICKED: { // Тук си при двоен клик. // ..... // еState = RELEASING; break; }
case CANCELLED: { // Тук можеш да свършиш нещо в случай, че бутона се отпусне преждевременно. Удобно е при дълъг дебаунс // .....
еState = RELEASING; break; }
case RELEASING: { // Бутона отпуснат ли е? if (BTN_PRESSED != pBUTTON) { // Да, почваме отначало еState = IDLE; } break; }
default: { // По принцип тук не трябва да се влиза никога, но кой знае... :) еState = IDLE; break; } }
// Накрая придвижваме таймерите if (0 < debounceTimer) { debounceTimer--; }
if (0 < doubleClickTimer) { doubleClickTimer--; } }
|  |  |  |  |
edit: Опс, намерих грешка. По-добре е таймерите в случая да са с 2 стейта.
Последна промяна tolstolob на Нед Юни 26, 2011 1:11 pm, променена общо 3 пъти
|
| Нед Юни 26, 2011 12:48 am |
|
 |
|
relsys
Ранг: Форумен бог
Регистриран на: Пет Ное 25, 2005 11:41 am Мнения: 1680
|
@tolostolob +1
Все едно аз съм го писал тоя код. Като покажа на някой обаче код написан в такъв стил, нещо не могат да го разберат. Толкова ли е сложно и неразбираемо? Според мен, стейт машините са най-разбираемия начин за описване на дадена задача.
|
| Нед Юни 26, 2011 10:38 am |
|
 |
|
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 2:45 am Мнения: 263
|
Е, точно в тоя му вид не бих го ползвал в мой код, но за илюстрация - става.
@relsys, виждам, че работиш с пикове основно, ако искаш добави разните му там честоти, инициализации, фюзове и т.н. и да стикнем темата, че като гледам половината въпроси тук са за бутони 
|
| Нед Юни 26, 2011 1:19 pm |
|
 |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
@tolstolob благодаря много ако го бях видял по рано твоя отговор щях да си спестя доста нерви. Но успях да се спрява и сам с бутона  с което съм горд. ето го и целяи код може на някой да е полезен
НО сега ми идва другия проблем. За да е всичко готово ми се иска там където е "mode==3" да се пускат да се връткат всички възможни цветове едновременно и на двата RGBta демек RA2=RB1= зелено RA3=RB2= червено RB0=RB3 = синьо та моляви дайте едно бързо рамо че съм си дал срок до петък да е готово всичко и да ги монтирам  PIC а е 16f627a че това със пулса не съм го рпавил досега и тези настройки са доста мътни пробвах следния код но промлема е че така само светва плавно свето диода , а неиска да се изгася плавно
|
| Вто Юни 28, 2011 2:13 am |
|
 |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
искам да постигна този ефект. някой можели поне да разясни малко как трябва да стане защото миголяма мешавица в главата .
вече имам прекъсване на с него мисля да увеличвама честотата, как да задам тази стойност да светка постепенно или да изгася постепенно даден пин.
|
| Сря Юни 29, 2011 3:52 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
Мммм какво конкретно те мъчи, трябват ти 3 PWM, аз не бих изпрал точно пик за целта но при тебе вече е факт. Остава ти въпроса с преливането на цветовете което може да стане по два начина, по сложния да измислиш алгоритъм който да мени едновременно трите PWM в желаната от теб комнинация, другия по лесен ако си решил да имаш примерно 64 стъпки на промяна да си зададеш табличните стойности и да ги въртиш. може и нещо междинно, да се движиш по таблични стойности, но да апроксимираш между тях, така ще имаш повече стъпки и плавност. Тук апроксимацията трябва да с епомисли дали винаги ще е линейна, или по скоро дали винаги ще е един тип функция без значение линейна или не.
Като знам колко много флаш имат тия пикове може и да не ти стигне 
|
| Сря Юни 29, 2011 7:38 am |
|
 |
|
valioman
Ранг: Почетен член
Регистриран на: Съб Сеп 17, 2005 5:07 pm Мнения: 813 Местоположение: Сливен
|
Що бе Тони ако иска точно това от картинката .. ми то се вижда алгоритъма ..колко флаш ще иде за пускане на един таймер и в прекъсването му според зададените стойности да клатиш 3 те крака .
Май Цецо преди беше се бъзикал с един пикльо 12-ка на тази тема.
Е ако имаше 3 PWM щеше да е прекалено лесно ама нали за това сме пикоборци .. да ни е трудно 
|
| Сря Юни 29, 2011 9:22 am |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
Правих и аз нещо за RGB ... ама не се сещам вече за какво беше и как изглеждаше.
Спомням си че плавно се смесваха цветовете, и имаше условие да не с включват трите диода заедно, нещо пазене на батерииката ... . Мисля че основното беше това :
 |  |  |  | Код: #include "D:\3_led\main.h" char flag,tmr1,i,j; #bit rtmr=flag.0 #bit gtmr=flag.1 #bit btmr=flag.2 #bit xxxx=flag.3 //#use fast_io(ALL) #int_RTCC void RTCC_isr(void) { set_RTCC(200); tmr1++; if(tmr1==1){ output_low(PIN_A2); if(rtmr)output_high(PIN_A0); output_low(PIN_A1); }; if(tmr1==2){ output_low(PIN_A0); if(gtmr)output_high(PIN_A1); output_low(PIN_A2); }; if(tmr1>=3){ output_low(PIN_A1); if(btmr)output_high(PIN_A2); output_low(PIN_A0); tmr1=0; }; }
#int_TIMER1 void TIMER1_isr(void) { set_timer1(0); //rtmr=1,gtmr=1,btmr=1; }
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD); setup_adc(ADC_OFF); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_wdt(WDT_18MS); setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); setup_comparator(NC_NC); setup_vref(FALSE); enable_interrupts(INT_RTCC); // enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL);
// TODO: USER CODE!! while(1){ restart_wdt(); rtmr=1,gtmr=0,btmr=0; delay_ms(500); for(i=1,j=15;i<=15;i++,j--){ gtmr=1; rtmr=0; delay_ms(i); rtmr=1; gtmr=0; delay_ms(j); }; rtmr=0,gtmr=1,btmr=0; delay_ms(500); for(i=1,j=15;i<=15;i++,j--){ gtmr=0; btmr=1; delay_ms(i); btmr=0; gtmr=1; delay_ms(j); }; rtmr=0,gtmr=0,btmr=1; delay_ms(500); for(i=1,j=15;i<=15;i++,j--){ btmr=0; rtmr=1; delay_ms(i); btmr=1; rtmr=0; delay_ms(j); }; }; } |  |  |  |  |
_________________ Вниманиене съмвишист....ИЙ.
|
| Сря Юни 29, 2011 9:34 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
Е ако иска точно това от картинката нещата са прости, там се мени само едният ШИМ, но не знам какво преливане би се получило, иначе по тоя начин може д астане мног опо плавно значително по лесно, може и 10 битов да е ШИМ.
|
| Сря Юни 29, 2011 12:41 pm |
|
 |
|
pachuka
Ранг: Минаващ
Регистриран на: Вто Юни 21, 2011 9:51 pm Мнения: 46 Местоположение: Bulgaria
|
точно това искам от катинката, преливане само най голямата яркост на цветовете. гледам че му викат дъга или rainbow само къде аз искам да има и бяло. във youtybe е пълно със готови таквиа проекти с пикчета 12фххх
таймера ми е на лице не е проблем да вкарам в него една променлива "x" която да се мени от 0до 255 за желано от мен време.
но как да задам на самия пин тая стойност ако напиша RB1=255; и RB2=120; свети само с максимална мощност RB2
та май това ми е проблема алгоритъма ще го измисля за връткането, но дори и таблично да го направя както предлага тони пак незнам как да задам да свети примерно наполовина единия лед.
|
| Сря Юни 29, 2011 4:25 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 2 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|