hjælp til servo kontrol med timer (Læst 129752x)

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #180 Dato: Oktober 25, 2011, 22:41:02 »
Citér
da jeg arbejder på en hasteopgave
Jobbet skal selvfølgelig passes  :D

Det jeg mener jeg mangler er:
1. at få lavet pot conversion og få den til at leverer en værdi der ændre high i 20 ms PWM cyclen jf.

ergo værdier fra 0.8 ms til 2.2
(skal nok kun bruge værdier fra 1.2 - 1.8 men er ikke sikker endnu)

2. få lavet startknappen således at programmet starter med 1 dosering når denne trykkes ned, og der efter ud fra hvordan det er defineret i dips.
3.
Citér
Men med henblik på dette, har jeg en forbedring af dette system; mere herom senere.
Ud over dette, så mangler vi stadig argumenterne til startServo.
Jeg mener vi helt skal tømme 'initServo()', så den bliver helt tom.
fra den pdf du sendte (fejl nr 17)
4.
Citér
Vi har ikke beregningen af frekvensen endnu, så jeg har udkommenteret linierne den bruges i, indtil videre.
fra den pdf du sendte (fejl nr 19)

i forhold til førstnævnte er det svært at finde tutorials der ikke bare er lavet i assembly, men leder videre.



 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #181 Dato: Oktober 27, 2011, 13:35:14 »
Jeg er stadig igang med det tidligere nævnte projekt, men vil lige sende dig lidt...

Da jeg kiggede på Dosing.c, kom jeg til at tænke på at koden kan reduceres en smule:

Kode:
void timer0Elapsed()
{
    static const uint8_t repTable[] PROGMEM = { 1, 10, 4, 2 };
    uint8_t repeats;
    uint8_t a;
    uint16_t rotation;
    uint8_t unload;

    unload = 0;    /* Value 0 - 256 since the pot2 is removed and unload is defined by constant*/

    repeats = pgm_read_byte(&repTable[gSettings & 0x03]);

    for(a = 0; a < repeats; a++)
    {
        /* load: */
        waitSeconds(10);
        rotation = getADC2Value();
        startServo(200, rotation);
        /* unload: */
        waitSeconds(10);
        startServo(200, unload);
    }
}

Som du ser, er alle 'if' sætningerne erstattet med et enkelt tabel-opslag.
Dette kan vi gøre, da vi med bit-AND filtrerer de to nederste bits ud (dvs. bit 0 og bit 1).

Det samme system kan bruges i startDosing:
Kode:
void startDosing()      /* this routine starts when the 'start' button is pressed */
{                       /* setMinuteCountdown initiated corrosponding to dip setting*/
    static const uint16_t timeTable[] PROGMEM = { 2 * 60, 24 * 60, 12 * 60, 6 * 60 };

    setMinuteCountDown(pgm_read_word(&timeTable[(gSettings >> 2) & 0x03]));
    timer0Elapsed();
}

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #182 Dato: Oktober 28, 2011, 12:54:27 »
ahh smart  :P

Håber du når din hasteopgave. det er altid rart at blive presset lidt he he

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #183 Dato: Oktober 31, 2011, 20:33:08 »
Hej igen. Det er godt nok ved at blive en lang tråd det her. Ved ikke helt om det er pinligt he he

har prøvet at se på pin change interrupt, til startknappen, og her er hvad jeg kom frem til.
Har smidt det hele i main.c

Kode:
int main()
{
    GPIOR2 = SERVO_ENABLED; /* This must be the first code executed; no code goes before it, and GPIOR2 is not to be changed from now */
initADC(8);     /* initialize ADC, we'll use the 8-bit precision for now */
    initTimer0();
    initDosing();
    initServo();
sei();       /* globally enable interrupts */
   
PCMSK0 |= (1<<PCINT3);                          /*Set PA3 as the pin to use*/
MCUCR = (1<<ISC01);                             /*interrupt on INT0 pin falling edge*/
GIMSK  |= (1<<INT0);                            /*turn on interrupts*/

while(1)
{
/* we don't really need to do anything here. Everything is handled by the interrupts */
}
    return(0);      /* (never reached) */
}
SIGNAL (SIG_PCINT3)
{
   gSettings = calculateSettingsDip(getADC1Value()); /* update our settings */
}

Vil det virke ??
Er ikke lige sikker på det med rising, faling eller any logical change, i forhold til MCUCR

Læste et andet sted at man brugte en internal pull up og så havde knappen på fra jord til PA3 men ved ikke om attiny også kan det og om det overhovedet kan betale sig.

 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #184 Dato: Oktober 31, 2011, 22:05:54 »
Hej igen. Det er godt nok ved at blive en lang tråd det her. Ved ikke helt om det er pinligt he he
Det synes jeg ikke. Tværtimod; der vil nok være mulighed for at andre kan få løst deres problemer, ved at kigge lidt i tråden. :)

Desuden er du snart kommet hele turen rundt i microcontrolleren. Der er selvfølgelig stadig nogle ting du ikke har prøvet, fx. UART/USART (serielt interface) og nogle andre småting, men det meste af hvad microcontrolleren kan, har du snuset til nu; og så har du også prøvet at bruge interrupts, hvilket er noget de fleste venter med, til der er gået lidt over et år.
-Men interrupts er gode at bruge, hvis man har muligheden.

Citér
har prøvet at se på pin change interrupt, til startknappen, og her er hvad jeg kom frem til.
Har smidt det hele i main.c

Kode:
	PCMSK0 |= (1<<PCINT3);                          /*Set PA3 as the pin to use*/
MCUCR = (1<<ISC01);                             /*interrupt on INT0 pin falling edge*/
GIMSK  |= (1<<INT0);                            /*turn on interrupts*/


Åbn først dette datablad.

PCMSK0 ... ben 10 (PA3) enables, dette er som det skal være.
PCMSK0 finder du på side 52, dér står noget interessant omkring GIMSK.
GIMSK INT0 (ben 5, PB2) enables. Fint, men der er flere interrupts, som du gerne vil enable i dette I/O-register.
På side 50 finder du GIMSK, men det er først øverst på side 51, der står noget du skal bruge. :)


MCUCR ... bør ikke OR'es. Denne bør skrives på denne måde:
Kode:
MCUCR = (1 << ISC01) | (0 << ISC00);     /* interrupt on INT0 pin, falling edge */
-Fordi... Hvis MCUCR's laveste bit bliver sat et andet sted i koden, vil du få rising edge i stedet for falling.
(Det er ikke tilfældet i dette program, men hvis du senere plukker noget kode ud og bruger et andet sted, vil der gå ged i det).

Citér
Kode:
SIGNAL (SIG_PCINT3)
{
   gSettings = calculateSettingsDip(getADC1Value()); /* update our settings */
}

På side 47 ser du en oversigt over interrupt-vektorerne.
SIG_PCINT3 bliver aldrig kaldt. Se side 47 i databladet, der vil du se at der er kun PCINT0 og PCINT1 (dvs. SIG_PCINT0 og SIG_PCINT1). Hvilken én skal bruges ? :)

Derudover... Hvor er SIG_INTERRUPT0 ?

[/quote]Vil det virke ??[/quote]

Mjae, men ikke efter hensigten. ;)

Citér
Er ikke lige sikker på det med rising, faling eller any logical change, i forhold til MCUCR

Der er en ting mere omkring PINCHANGE interrupts...
Du bør sikre mod prel (glitches), for når brugeren trykker på knappen, vil du få mellem 10 og 50 interrupts!
Dette er fordi der springer gnister mellem kontakt-fladerne på knappen.

Du kan løse det på en let måde, eller en avanceret måde. Til at starte med, tror jeg det er bedst med den lette måde.
For at sikre mod prel, er det en god idé at finde ud af om knappen er trykket ned eller sluppet, derefter vente 5 ... 10 millisekunder, og så læse igen om den er trykket ned eller sluppet. Har den ændret værdi, så glem at der skete noget.

Pin-change interruptet bliver kaldt både når en knap trykkes ned, og når knappen slippes.
Derfor skal vi læse om benet er LOW, når vi kommer ind i vores pin-change interrupt, og derefter vente 5...10 millisekunder, og derefter læse benets værdi og se om det stadig er LOW...

Kode:
SIGNAL (SIG_PCINT?)
{
    uint8_t pinValue;

    pinValue = PINA & (1 << PINA3);                             /* read value of input-pin */
    if(0 == pinValue)                                           /* we're only interested if button is pressed */
    {
        _delay_ms(10);                                          /* wait 10 ms */
        pinValue = PINA & (1 << PINA3);                         /* read value of input-pin */
        if(0 == pinValue)                                       /* only update settings when button value is stable */
        {
            gSettings = calculateSettingsDip(getADC1Value());   /* update our settings */
        }
    }
}


Citér
Læste et andet sted at man brugte en internal pull up og så havde knappen på fra jord til PA3 men ved ikke om attiny også kan det og om det overhovedet kan betale sig.

Det er faktisk dét de ar lavet til, så det kan du godt. :)

Dér skal du så sige...
Kode:
DDRA &= (1 << DDRA3);  /* set pin as input (you probably already set it to be input) */
PORTA |= (1 << PA3);   /* enable internal pull-up resistor */

Det kan altid betale sig at spare komponenter (hvis altså kvaliteten af produktet ikke forringes) - for selv en SMD-modstand til 0.02 øre koster 1 kr. at montere for en maskine. Dertil kommer prisen på printet. Her koster hver kvadratmillimeter penge. Du finder ud af på et tidspunkt, at printplader er dyre at få lavet, og derfor vil du gerne have lavet dem så små som muligt; derved kan du få lavet en hel masse boards på samme plade (dette kaldes panelizing).

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #185 Dato: Oktober 31, 2011, 23:12:39 »
Citér
SIG_PCINT3 bliver aldrig kaldt. Se side 47 i databladet, der vil du se at der er kun PCINT0 og PCINT1 (dvs. SIG_PCINT0 og SIG_PCINT1). Hvilken én skal bruges ? :)
Det er SIG_PCINT0. Den er til alle PA ben mens PCINT1 er til PB benene

Citér
Derudover... Hvor er SIG_INTERRUPT0 ?
Her forstår jeg ikke hvad du mener ?
Jeg troede at
SIGNAL (SIG_PCINT0)
{
   gSettings = calculateSettingsDip(getADC1Value()); /* update our settings */
}

Var nok til at registrerere om der er et interrupt

Citér
derefter vente 5...10 millisekunder
Smart !

Citér
Det kan altid betale sig at spare komponenter
Det kan være at jeg ændre det på en senere version. lige nu bruger jeg bare den knap jeg har lavet med "ekstern" pull down

Citér
GIMSK INT0 (ben 5, PB2) enables. Fint, men der er flere interrupts, som du gerne vil enable i dette I/O-register.
ændret til GIMSK  |= (1<<PCINT3);

Læser og læser side 50-52  :P

 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #186 Dato: November 01, 2011, 06:39:22 »
Citér
SIG_PCINT3 bliver aldrig kaldt. Se side 47 i databladet, der vil du se at der er kun PCINT0 og PCINT1 (dvs. SIG_PCINT0 og SIG_PCINT1). Hvilken én skal bruges ? :)
Det er SIG_PCINT0. Den er til alle PA ben mens PCINT1 er til PB benene

Korrekt. :)
Så nu ved du, at man kan bruge ét Pin-Change interrupt til at holde styr på 8 indgange. Ulempen er at man er nødt til selv at læse indgangene og undersøge hvad der er 1 og hvad der er 0, men alt i alt er det et fint system, at man kan have interrupt på hvert i/o-ben. :)

Citér
Citér
Derudover... Hvor er SIG_INTERRUPT0 ?
Her forstår jeg ikke hvad du mener ?
Jeg troede at
SIGNAL (SIG_PCINT0)
{
   gSettings = calculateSettingsDip(getADC1Value()); /* update our settings */
}

Var nok til at registrerere om der er et interrupt

Jep, det er korrekt. Men du sætter INT0 op, som er ben 5, PA2. INT0 er ikke et PCINT, men et selvstændigt interrupt (som har prioritet over PCINTs). Derudover kan du bestemme hvordan INT0 skal trigges. :)
Jeg går ud fra at du ikke er interesseret i at trigge et interrupt på ben 5; dette vil sige at du ikke behøver INT0.

Grundlæggende for AVR er:
1: Skriv en interrupt-rutine
2: Eventuelt clear interrupt-flag, så interruptet ikke udføres med det samme (se TIFR0, TIFR1 på side 84)
3: Hvis det fx. er et timer-interrupt, så sæt timer-delen op (TCNTx, OCRxA, OCRxB, opførsel: TCCRxA, TCCRxB)
4: Sæt Enable-bitten for det valgte interrupt (fx. GIMSK for generelle interrupts eller TIMSK for timer interrupts)
5: Hvis I-bitten ikke er sat, udfør da en SEI instruktion, som enabler interrupts (dette gør vi efter alt init, så denne del er iorden). -Så skulle det køre. Generelle interrupts er således lette at sætte op, mens timere og andet kræver lidt konfiguration.

Citér
Citér
Det kan altid betale sig at spare komponenter
Det kan være at jeg ændre det på en senere version. lige nu bruger jeg bare den knap jeg har lavet med "ekstern" pull down

OK, det er helt fint, men hvis du har pulldown på, vil den normalt ligge LOW, hvilket vil sige at du skal kigge i dit PCINT0 om den er HIGH. :)
Citér
ændret til GIMSK  |= (1<<PCINT3);

Fint, dette er korrekt.

Citér
Læser og læser side 50-52  :P

Lige netop de sider er rigtig guf, for der står meget information omkring interrupts. Det er ikke så indviklet, når det kommer til stykket.

Med hensyn til PA3, kan man gøre noget der er endnu smartere, men dette er foreløbig kun teori. :D

Hvis du kigger på databladet's side 2, ser du at PA3 også har en anden funktion, nemlig T0. Prøv at se på side 113, her står at T0 (og T1) kan bruges som ekstern clock-source til Timer0 (T1 til Timer1).

Hvad betyder så det?
-Jo, hvis vi kan få Timer0 til automatisk at starte, hver gang T0 ændres, fx. fra LOW til HIGH, kan vi starte en timer, der venter 10 ms. Når denne timer når fx. sit maks overflow kunne vi så få den til at starte SIG_OVERFLOW0 interruptet.
Det betyder at vi kan indbygge prel-sikring på denne måde, og derfor behøver vi ikke at vente de 10 ms med _delay_ms(10), men kan få interruptet til at klare den sag.

Det 'kedelige' ved at bruge _delay_ms(10), er at microcontrolleren er optaget med at tælle en variabel ned i de 10 ms. Det gør selvfølgelig ikke noget i dette tilfælde, da vi ved at brugeren jo sidder og holder knappen inde, så det er ikke kritisk at bruge interrupt på dette sted.
...Hvorfor skriver jeg så at det foreløbig kun er teori ?
Jo, for vi bruger allerede Timer0 til at tælle sekunder, minutter og timer. Derfor vil det være meget godt at lade den være som den er. ;)
Vi vil helst ikke bruge Timer1 til at tælle sekunder, minutter og timer, fordi Timer1 er en 16-bit timer, som kan bruges til langt bedre ting (fx. servo-PWM), men jeg synes du lige skulle have at vide at man kunne bruge T0 på denne måde.

I mit lille spil-konsol, har jeg lavet en forbindelse fra OC1A til T0, hvilket vil sige at jeg bruger Timer1 til at lave en 31kHz frekvens, og Timer0 tæller så hver puls som Timer1 giver.

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #187 Dato: November 02, 2011, 14:25:55 »
Hej igen
Har lige et spørgsmål klidt uden for emnet.
Jeg skal jo have noget nyt lys over mit akvarie, da hqi er aaaalt for dyrt og da jeg ikke vil risikerer at der sker et uheld igen.
Jeg har bestilt 5 10w led Forward voltage: 9-12V DC, Forward current: 1000mA.
Jeg har tænkt mig selv at lave drivers til dem, men vil lige spørge om der er noget jeg skal være særligt opmærksom på.
Jeg ved at det er et helt anden projekt, men er lige nød til at have lys over baljen igen. Til at starte med skal der ikke være nogen form for styrring, men når dosering systemet er færdigt har jeg tænkt mig at prøve at overføre alle principper til en styrring af lyset, til at simulerer sol op og ned -gang. men til at starte med skal det bare være en driver der kan drive 10w leds, enten 1 driver til alle 5 eller en driver pr stk.
Det ville være lettest at driveren kan kobles på 230v
har du et godt forslag

 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #188 Dato: November 02, 2011, 15:21:33 »
Jeg har bestilt 5 10w led Forward voltage: 9-12V DC, Forward current: 1000mA.

Dvs. hver LED bruger 1A, i alt 5A lagt sammen.

Det er egentlig meget simpelt. Til at starte med skal du bare have fundet en strømforsyning på 10V/5A (eller højere antal ampere), for vi kan ikke have at strømforsyningen futter af, pga. der trækkes for meget strøm.

Hos RS kan man købe nogle switch-mode strømforsyninger til fornuftige priser. Prøv at se denne side. Desværre har jeg lidt bøvl med at se netop denne side selv, da den ikke virker i Safari.
Klik ude i venstre side på udgangsspænding, vælg udgangsspænding, derefter klik på udgangsstrøm og vælg 5A og alt over 5A. Så burde du få nogle fornuftige resultater.

Alternativt kan du prøve at se om du falder over en strømforsyning til en bærbar PC, som er på 12V/5A. Chancen for dette er nok minimal. Der er selvfølgelig også mulighed for at rippe en gammel PC der er på vej på lossepladsen; der sidder nemlig ofte en kraftig strømforsyning i sådan nogle gutter.

Hvis vi antager at du senere skal lave en styring disse LEDs, kan du sætte en TIP127 transistor på (klarer lige akkurat 5A), eller en BDX34C eller BDW46G. Men du skal lige have en BC546/BC547/BC548 på inden da; tilbage til dette senere.
Det er en god idé altid at have et par TIP127 liggende. Du kan eventuelt lave individuel styring på alle 5 LEDs, så behøver du kun at bruge TIP127; eller to stk. TIP127 til at styre 2 og 3 LEDs, så er du sikker på ikke at trække for meget strøm gennem transistoren.

Tilbage til BC547 (og lignende)...
Fra microcontrolleren's i/o-ben sætter du en 1K modstand over til basis på BC547. Emitter sætter du til GND. På collector sætter du en 47K modstand til +12V. Yderligere fra collector sætter du en 1K modstand til TIP127's basis.
TIP127's emitter sætter du til +12V. Fra TIP127's collector sætter du en 1N400x, så anoden's ende er mod collector, og kathoden's ende er på +12V.
Output får du mellem GND og collector på TIP127. :)

Nu kan du styre jævnspænding op til 45V/5A med en microcontroller (hvis du bruger BC547).
Har du brug for op til 65V, bør du bruge BC548.
Så kan du bare gange op med det antal udgange du vil styre. =)
Du kan sætte en DC-motor direkte på denne udgang (da den er beskyttet af 1N400x; og også en intern diode i TIP127).

Og ups. På diagrammet nedenfor har jeg glemt at angive +12V; det er selvfølgelig øverst i højre hjørne. ;)
« Senest Redigeret: November 02, 2011, 15:23:14 af pacman »

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #189 Dato: November 02, 2011, 15:59:23 »
Citér
Det er egentlig meget simpelt. Til at starte med skal du bare have fundet en strømforsyning på 10V/5A

ok

Har aldrig helt forstået hvorfor man ikke bare smider en omformer på, istedet for en driver. er det bare et salgstrik at de vil have os til at købe drivers frem for en alm strømforsyning.
Er det ikke sådan at en led trækker al den strøm den har til rådighed, også selv om at det er mere end den kan tåle, og det vil jo være spild af watt at have modstande til at styrre dette

 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #190 Dato: November 02, 2011, 16:11:06 »
Citér
Det er egentlig meget simpelt. Til at starte med skal du bare have fundet en strømforsyning på 10V/5A

ok

Har aldrig helt forstået hvorfor man ikke bare smider en omformer på, istedet for en driver. er det bare et salgstrik at de vil have os til at købe drivers frem for en alm strømforsyning.
Er det ikke sådan at en led trækker al den strøm den har til rådighed, også selv om at det er mere end den kan tåle, og det vil jo være spild af watt at have modstande til at styrre dette

Mht. LED der trækker strøm. Både ja og nej. Jeg har set folk sætte en LED direkte på en 3V forsyning uden at deres LED brænder af - men det kan være det er et spørgsmål om tid.

Har du en alm. LED på 3V/20mA og en 5V forsyning, så er dit officielle max-output med en modstand på 100 ohm, da der skal ligge 3V over LED'en og 2V over modstanden, og der går 20mA gennem begge.
2V / 20mA = 100 ohm.

Nogle lysdioder er lavet til at køre på 12V og har 'indbyggede modstande'.

En LED driver er sådan set et vidt begreb.
Fx. en microcontroller der skal styre et 7-segment display med 4 cifre, kunne have gavn af en driver, for driveren gør det nemmere at holde lys i alle cifre på én gang.
Med andre ord: Her er driverens opgave at give ampere nok til LED'ne.

Men jeg kan forestille mig at der findes LED drivere, som jeg ikke har nogen forstand på. For eksempel kan man købe nogle kraftige LED-moduler, og disse har brug for en eller anden type driver siges der. Nu har jeg aldrig selv brugt sådanne moduler, så i dette tilfælde bliver jeg dig svar skyldig.
Jeg kunne forestille mig at sådanne drivere pulser LEDne og skifter hurtigt mellem hver LED, så i alt bliver der kun brugt 1A selvom alle LEDs lyser 'på samme tid'. Lyset bliver en smule svagere, med mindre man båler lidt op for spændingen. Se datablad på LED-modulet for at se hvor meget man kan give den i overspænding. (Dette gælder også almindelige 3mm, 5mm og SMD LEDs)

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #191 Dato: November 02, 2011, 16:32:23 »
ok.
Så vidt jeg har kunnet læse mig til så er driverens formål at sikre at der ikke bliver leveret mere end eks 1 amp til  10w led
det kan jo gå hen og koste temmelig mange penge at brænde dem af specielt hvis man kører med cree
« Senest Redigeret: November 02, 2011, 17:03:32 af jascore »

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #192 Dato: November 05, 2011, 15:54:45 »
Citér
OK, det er helt fint, men hvis du har pulldown på, vil den normalt ligge LOW, hvilket vil sige at du skal kigge i dit PCINT0 om den er HIGH.

vil det sige at MCUCR skal være rising edge ?
eller skal pinValue sættes til at være > 0

 

Offline pacman

  • Højpas filter
  • *****
  • Indlæg: 311
  • Antal brugbare Indlæg: 8
  • Jens Bauer (Forsøgs-person)
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #193 Dato: November 05, 2011, 22:45:44 »
Citér
OK, det er helt fint, men hvis du har pulldown på, vil den normalt ligge LOW, hvilket vil sige at du skal kigge i dit PCINT0 om den er HIGH.

vil det sige at MCUCR skal være rising edge ?

Du kan ikke sætte MCUCR til at være rising edge på andet end INT0.
INT0 og PCINT0 er to forskellige ting.
PCINT0 og PCINT1 er af samme type. Disse to interrupts håndterer flere hver pins på samme tid.
INT0 interruptet har højere prioritet end PCINT interrupts. Du kan også styre det mere nøjagtigt, men der er kun én pin der er forbundet til dette interrupt, nemlig ben 5.

Citér
eller skal pinValue sættes til at være > 0

Jeg anbefaler at lave if-sætningen således (dvs. mit fokus er kun på den ene linie med 'if'):

Kode:
if(pinValue)
{
    /* pin is high, button is pressed */
}
else
{
    /* pin is low, button not pressed */
}

-Undgå altså at bruge større-end, som nedenstående, når du sammenligner værdier du laver bit-operationer på...

Kode:
if(pinValue > 0)
{
    /* pin is high, button is pressed */
}

-Det først-nævnte er renere / bedre logik, for pinValue kan enten være nul eller ikke-nul.
Det har vi sikret os ved at lave en 'bitwise and' tidligere.

(Det er selvfølgelig ikke en katastrofe, da vi er ovre i bagatel-afdelingen, men efterhånden som man arbejder med kode, finder man mere og mere ud af, hvordan man undgår uheldige - næsten usynlige - fejl der sniger sig ind. Årsagen til min anbefaling er baseret på at man senere ændrer lidt i koden).

Hvis det er helt rigtigt, ville det være mest korrekt at sætte pinValue således:
Kode:
    pinValue = (PORTA >> PCINT3) & 1;

Så vil pinValue enten være 0 eller 1.
-Men den færdige binære fil vil fylde mere, end hvis du gør følgende:

Kode:
    pinValue = PORTA & (1 << PCINT3);

-Fordi compileren kan reducere (1 << PCINT3) til tallet 8, hvor der ellers skal indsættes ekstra maskinkode, for at få bitten ned på nederste position; her afhænger kodestørrelsen af hvor mange bitpladser bitten skal flyttes.

 

Offline jascore

  • Jordet Basic
  • **
  • Indlæg: 157
  • Antal brugbare Indlæg: 0
    • Vis profil
Sv: hjælp til servo kontrol med timer
« Svar #194 Dato: November 07, 2011, 22:11:27 »
Jeg fik en fejl på Prel funktionen så lagde følgende linje ind i starten af main.c
#include <util/delay.h>

Det gav mig så en fejl om at F_CPU bliver redefined, da den  bliver defined både i <util/delay.h> og <main.h>
så jeg lagde #include <util/delay.h> ned under #include <main.h>

Startkanp funktionen lavede jeg om til flg.
Kode:
SIGNAL (SIG_PCINT0)
{
    uint8_t pinValue;

    pinValue = PINA & (1 << PINA3);                             /* read value of input-pin */
    if(pinValue)                                                 /* we're only interested if button is pressed */
    {
        _delay_ms(10.);                                         /* wait 10 ms */
        pinValue = PINA & (1 << PINA3);                         /* read value of input-pin */
        if(pinValue)                                            /* only update settings when button value is stable */
        {
            startDosing();
        }
    }
}

Eneste ændring er at if sætningerne er ændret til
if(pinvalue)
istedet for
if(0==pinvalue)
samt at jeg smed et kald til startdosing() ind

Går ud fra at det løser problemet med at jeg bruger pull down og ikke pull up

Jeg går også ud fra at flg. bliver overflødigt i ADC.c
Kode:
uint16_t getADC1Value()
{
    return(getADCValue(1)); /* ADC value of startbutton */
}

Hvis ovenstående er korrekt så tror jeg kun at jeg mangler pot til PWM funktionen til servoen
« Senest Redigeret: November 07, 2011, 22:34:55 af jascore »