Dialkove ovladanie potenciometra

Zdravim, neviem si rady s otacanim potenciometra (ALPS s motorcekom) suvisle. Motorcek poteniometra je zapojeny cez dva vystupne piny MCU cez H mostik. Program robi to ze vyskakuje z cyklu kde by mal cakat na koniec prichadzajucich sprav. Cize vysledne mi MCU robi to ze ledka zapojena na danom vystupe blika, a blika to vtedy kym neskonci vysielanie (to by bolo dobre az na to blikanie).
Chcel by som aby niekto pomohol vyriesit problem, a to dosiahnut stalu uroven 5V (log1) na vystupe RB2 alebo RB3, od vtedy a do vtedy kym prichadzaju spravy (VOLUME_UP alebo VOLUME_DOWN) od vysielaca.

Vysielac a jeho funkia vysielania hlasitosti VOLUME_DOWN:

case 0b00001000: { while (RB3_bit==0) { Octet (VOLUME_DOWN); Octet (VOLUME_DOWN); Octet (VOLUME_DOWN); delay_ms(100); } break; }

Funkcia VOLUME_UP je robena uplne rovnako az nato ze vysiela po dobeznej hrany na RB2. Vysielac vysiela min 3 byty s ktorych ked su aspon 2byty rovnake(receiveBTN()), prijimac vykona funkciu (switch). Sirka celej trojice oktetov je 26,1ms, a jedneho bytu je 8,67ms.

Kod prijimaca:

[code]
#define VOLUME_UP 0x87 //Kod prijaty pri stlaceni Volume UP
#define VOLUME_DOWN 0x9C //Kod prijaty pri stlaceni Volume DOWN

unsigned char receiveBTN();
unsigned char STANDBY();
unsigned char rcvd;
int VOLUME_STATE;

unsigned char oktet1;
unsigned char oktet2;
unsigned char oktet3;
unsigned char getch();

main()
{
OSCCON = 0b11101001; //Interny oscilator 4Mhz
OPTION_REG = 0b00000000;
//PORTA register
PORTA = 0b00000000;
TRISA = 0b00000000;
ANSELA = 0b00000000;
LATA = 0b00000000;
WPUA = 0b00000000;
//PORTB register
PORTB = 0b11100000;
TRISB = 0b11100010;
ANSELB = 0b00000000;
LATB = 0b00000000;
WPUB = 0b11100000;
//Periferie
RXDTSEL_bit = 0; //RX/DT funkcia na RB1
T1CON = 0xC0;
CM1CON0 = 0x00;
CM1CON1 = 0x00;
SPBRGL = 0b00110011;
SPBRGH = 0b00000000;
TXSTA = 0b00000000;
RCSTA = 0b10111000;
BAUDCON = 0x00;
INTCON = 0b00000000;
RCIF_bit= 0;

    while(1)
    {
            delay_ms(10);
            RCREG=0;
            delay_ms(10);
            while(RCIF_bit==0);   //caka na prijatie spravy
            rcvd=receiveBTN();
            switch(rcvd)
            {
                    case MUTE:
                    {
                            RA3_bit=!RA3_bit;
                            delay_ms(10);
                                  break;
                    }
                    case VOLUME_UP:
                    {
                            RB2_bit=1;
                            delay_ms(10);
                            while(getch()!=0)     //z cyklu vyskakuje, jedno aky  velky ci maly delay je nadstaveny, v pripade ak je prilis velky tak cely program sa uplne zacykly
                            {
                                    delay_ms(130);
                                    if(RCIF_bit==0)break;      
                            }
                            delay_ms(10);
                            RB2_bit=0;
                            break;
                    }
                    case VOLUME_DOWN:
                    {
                            RB3_bit=1;

                            while(getch()==VOLUME_DOWN)    //funkguje rovnako ako VOLUME_UP, v inych intervaloch blikania :D, ;(
                            {
                                    delay_ms(100);
                            }
                            delay_ms(10);
                            RB3_bit=0;
                            delay_ms(10);
                            break;
                    }
                    default:
                    {

                            break;
                    }
            }
            delay_ms(10);
            RCREG=0;
            delay_ms(10);
    }

}

unsigned char getch() // prijme jeden oktet
{
int cnt;
cnt=0;
while(RCIF_bit==0)
{
cnt=cnt+1; //pocitadlo urcene nato by sa nezacyklil program pri funkcii hlasitosti
if(cnt>1000)return 0;
}
return RCREG;

}

unsigned char receiveBTN()
{
unsigned char oktet1;
unsigned char oktet2;
unsigned char oktet3;
oktet1 = getch(); // caka na odpoved od uzivatela
oktet2 = getch();
oktet3 = getch();
if((oktet1==oktet2)||(oktet2==oktet3)||(oktet1==oktet3))
{
if(oktet1==oktet2)return oktet1;
if(oktet2==oktet3)return oktet2;
if(oktet1==oktet3)return oktet3;
}
return 0;
}[/code]

Rozdiel medzi funkciami VOLUME_UP a DOWN v prijimacej casti je kvoli mojej testovacej metode. Dialkove ma viacej funkcii ktore som vymazal z prilozeneho kodu, vsetky ostatne funkcie mi pracuju podla ocakavani az na ovladania hlasitosti.

MCU s ktorym robim je PIC16F1827. Pracujem v prostredi MikroC Pro for PIC v6.4.0.

V programovani MCU som zaciatocnik.

cau,asi takle, kdyz ti pride VOLUME _DOWN/UP tak jen nastav vystup, potom si nastav casovac treba na 100ms a pokud nepride dalsi VOLUME _DOWN/UP tak ho schot,jestly pride tak vynuluj casovac a jet dalsich 100ms,na primaci udelej kdyz podrzis tlacitko tak se ti ty 3 byty budou opakovat treba po 40ms aby si se vesel do tech 100ms, ty casy si pak muzes upravit podle sebe…

Dakujem za odpoved. Preco namiesto casovaca nemozem pouzit delay? Vzdy ked som nadstavil delay vecsi nez je medzera medzi trojicami bytmi tak sa kod cyklyl na neviem akom mieste. S casovacom som este vobec nerobil, nasla by sa vhodna ukazka v C, co by mi pomohla zostavit kod?

kdyz das delay_ms(100); jak zjistis ze pri 50ms se neco stalo ? jedine pomoci preruseni… nebo nepouzijes ten delay…
jak nastavit casovac se koukni do helpu tvyho prekladace,…
co pouzivas za prenos ?

Ak dobre chapem, tak casovac je paralerna operacia, ktora v mojom pripade neovplyvni plennie registru RCREG?
Tym prenosom neviem presne co myslis. Ak mas na mysli prenos dat tak USART.

ne neovlivnuje RCREG
a kdyz pouzivas uart tak taky existuje preruseni od prijmu na uartu

Zdravim, skusil som namiesto delay pouzit casovac, nadstavil som ho podla prikladu, no bez uspechu, fyzicky po nafleshovan to blika, cize vyskakuje a skace z cyklu po kazdom prijati 3jici bytov. Casovac som nadstavil na 200ms.

OPTION_REG = 0b00000111; //Prescaler 256 ... ... case VOLUME_UP: { RB2_bit=1; delay_ms(10); while(getch()!=0) { while(!TMR0IF_bit); TMR0IF_bit=0; Count++; if(Count==3) { Count=0; } } delay_ms(10); RB2_bit=0; break; }
Prijimac.c (6.24 KB)

chtelo by to odsimulovat, nechat tam jen akci pro jedno tlacitko, vyhazet z toho vsechny while krome hlavniho,mozna bych upravil nejak ten prijem , cpat to do pole a pak to porovnat , vsechno pomoci priznaku bez while aby to plynule bezelo…while(1) { if(RCIF){rcvd=receiveBTN(); if(rcvd==VOLUME_UP){TMR0=0; RB2_bit=1; TMR0IF=0; TMR0=ON; } } if(TMR0IF){TMR0=OFF; RB2_bit=0; } }jakou rychlosti to primas ?

Realne otestovat mi je ovela rychlejsie nez simulvoat :wink:. Skusil som nafleshovat co ste mi poslali, a ledka na danom vystupe blika trosku rychlejsie. No skusal som aj zmensit delay pri vysielani na 10ms a sprava sa to tak ze to par krat zablika a potom uz je na vystupe stale 1 kym nepustim. No delay 100ms pri vysielami mal vyznam taky ze setri beterky ovladaca. Stisknutie tlacitka ktore nic nevysiela zozere 1,11mA, vysielanie VOLUME s delay 100ms bere 1,2mA v pripade 10ms odozvy medzi bytmi je odber 1,64mA.

Neviem co mate na mysli rychlostou prijimania.

Nauč se simulovat, ušetříš čas…

Simulovat viem, predtym nez som pisal kod som vsetko simuloval a slo to podla ocavakni, no ked som sa dostal k realizacacii vyskystli sa nezhody. V tejto faze kde som mi je ovela rychlejsie vytiahnut MCU z nepajiveho pola, flesnut ho a znova sledovat jeho chovanie.

Cože?? Proč tam nemáš ICSP?

mas neco blbe,sesmolil sem toto a v pohode to funguje , preruseni od timeru a primu …[code]#INT_RDA
void RDA_isr()
{
unsigned int8 data;

data=getc();
if(data=='*')buf_len=0;
buf[buf_len++]=data;
if(buf_len>3)f_buf=true;

}
//***********************************
#INT_TIMER1
void TIMER1_isr()
{
tmr1_count++;
}
//***********************************
void main()
{
unsigned int8 i;

CLEAR_INTERRUPT(INT_RDA);
CLEAR_INTERRUPT(INT_TIMER1);
ENABLE_INTERRUPTS(INT_RDA );
ENABLE_INTERRUPTS(INT_TIMER1 );
ENABLE_INTERRUPTS(GLOBAL);

SETUP_TIMER_1(T1_DISABLED | T1_DIV_BY_8);
//SETUP_TIMER_1(T1_INTERNAL| T1_DIV_BY_8);

while (TRUE)
{
if(f_buf){f_buf=false;
			if((buf[1]=='1')&& (buf[2]=='2')&& (buf[3]=='4')){OUTPUT_HIGH(PIN_A0);
																tmr1_count=0;
																SET_TIMER1(0);
																SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
															}
			}
if(tmr1_count>3){
					SETUP_TIMER_1(T1_DISABLED );OUTPUT_LOW(PIN_A0);tmr1_count=0;OUTPUT_toggle(PIN_A1);}
}

}[/code]vysilam * + 3byte informace , pokud do dvou sekund pride spravna informace tak sviti porad jinak se ledka vypina sama po 2s (delam to rucne pres terminal)

Na programovanie pouzivam ZIP 40 pinovy socket, a nepouzivam ICSP kvoli tomu ze vyuzivam piny PGD, PGC pri testovani, co by som musel pri fleshovani odpajat jednotlive zapojenia z tychto pinov. Mam dobru pinzetu na vytahovanie MCU :wink:.

Mrkol by sa mi niekto na pociatocne hodnoty bitov v registroch , ci su vobec tie dobre nadstavene? Dneska som stym zabil cely den s neuspechom, uz som skusal sialene veci ako napr:

[code]while(1)
{
delay_ms(10);
RCREG=0; //clear received data
delay_ms(10);
while(RCIF_bit==0);
rcvd=receiveBTN();
switch(rcvd)
{
case MUTE:
{
RA3_bit=!RA3_bit;
break;
}
case VOLUME_UP:
{
RB2_bit=1;
Count = 0;
test2: delay_ms(10);
while(RCIF_bit==0)
{
Count++;
if(Count > 100000) //asi po 300ms by mal skocit na test1 //medzera medzi 3jicou bytmi je 100ms, kde za ten cas ak nieco pride by sa mal nadstavit RCIF na 1 a skocit spet na test2
{
Count = 0;
goto test1;
}
}
if(receiveBTN()==VOLUME_UP)
{
goto test2;
}
test1: RB2_bit=0;
Count=0;
break;
}

            }

}[/code]

MiloPS3 vdaka za posledny prispevok, ale ked som kod skusal prelozit do mikroC tak mi stoho vyslo podobna vec ako kod ktory ste mi poslali predtym, cize robi mi to presne to iste. Ak som presne pochopil, tak ten timer je presne to iste ako Count v cykle, len stym ze si viem s timerom presne v ms nadstavit cas!?
Vysielac.c (5.41 KB)

Takto to funguje :smiley:, len neviem ci je to spravne riesenie, a hlavne blbovzdorne? Cas medzi 3jicou vysielania volume som znizil na 50ms.

[code]while(1)
{
delay_ms(10);
RCREG=0; //clear received data
delay_ms(10);
while(RCIF_bit==0);
rcvd=receiveBTN();
switch(rcvd)
{
case MUTE:
{
RA3_bit=!RA3_bit;
break;
}
case VOLUME_UP:
{
RB2_bit=1;
test2: Count = 0;
delay_ms(1);
while(RCIF_bit==0)
{
Count++;
if(Count > 15000)
{
Count = 0;
goto test1;
}
}
rcvd=receiveBTN();
if(rcvd==VOLUME_UP)
{
while(RCIF_bit==1);
delay_ms(1);
goto test2;
}
test1: delay_ms(1);
RB2_bit=0;
break;
}

            }[/code]