Vis indlæg

Denne sektion tillader dig at se alle indlæg oprettet af dette medlem. Bemærk at du kun kan se indlæg der er oprettet i områder du i øjeblikket har adgang til.


Beskeder - pacman

Sider: 1 2 [3] 4 5 ... 21
31
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 21, 2011, 17:23:44 »
Med en toggleLED inde lige efter adcCounter++; toggler den ikke led med mindre at det går så hurtigt at jeg ikke kan se det
Med en setLED1(0) slukker den godt nok der inde

prøv i toppen af interruptet at sætte en...

Kode:
setLED1(1);

og i bunden...

Kode:
setLED1(0);

...Hvis så du kan se lysdioden sender (sikkert svagt) lys ud, vil det betyde at ADC-interruptet kører hele tiden.

Hvis derimod lysdioden er helt slukket (og du måler 0V med multimetret), så betyder det at ADC-interruptet kun kører én gang.

Citér
i flg
if(ADCSRB & (1 << ADLAR))                                          /* check hardware alignment-configuration and act accordingly */
      {
         adLo = 0;
         adHi = inb(ADCH);                                             /* (read highbyte only) */
      }
      else
      {
         adHi = 0;
         adLo = inb(ADCH);                                             /* (read highbyte only) */
      }
reagerer den ikke med en setLED i if, kun i else
og i den overordnet funktion if(adcBits <= 8)
reagerer den ikke i else
Dette er korrekt opførsel. Den skal kun komme ind i én af disse 3.
Dette er fordi vi indstiller ADC-rutinen til at håndtere 8-bits i main().
Havde vi valgt at bruge 10-bits, ville det være den nederste den kom ind i.

Citér
men under alle omstændigheder er det efter med gSettings = calculateSettingsDip(getADC1Value()); kaldet i startdosing funktionen at systemet stopper

Ja, det er fordi waitUntilADCStable() venter på at adcCounter er talt op til værdien af ADC_STABLE (som er 8 i dette tilfælde).
adcCounter bliver talt op af ADC-interruptet i linien...
Kode:
			adcCounter++;

-Og den tæller kun op, hver gang vi har været alle ADC-kanaler igennem, og kun så længe den er under værdien af ADC_STABLE.

Men køres ADC-interruptet kun én gang, vil adcCounter kun nå op på værdien 1.
-Så vi må finde ud af om interruptet bliver ved med at køre, eller om det er faldet i søvn...

32
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 21, 2011, 15:34:41 »
Citér
Så prøv at flytte startDosing() fra initDosing over i Main.c, lige efter sei();

Det virkede desværre ikke den hænger stadig i waitUntilADCStable().

OK, men lad den blive dér, for det vil ikke komme til at fungere, hvis den sidder i initDosing. ;)

Prøv at åbne ADC.c og ændre det sidste af den til følgende:
Kode:
	adcValue[adcChannel - ADC_FIRST][adcWriteIndex] = (adHi << 8) | adLo;				/* save the value we've read above */

if(adcChannel++ >= ADC_LAST) /* next channel. If channel reached last channel... */
{
adcChannel = ADC_FIRST; /* ...start over */
adcWriteIndex = adcWriteIndex >= (ADC_SIZE - 1) ? 0 : (adcWriteIndex + 1); /* increment write position and wrap if necessary */
adcReadIndex = adcReadIndex >= (ADC_SIZE - 1) ? 0 : (adcReadIndex + 1); /* increment read position and wrap if necessary */
if(adcCounter < ADC_STABLE) /* if we haven't reached the number of conversions required for the ADC to stabilize... */
{
adcCounter++; /* increment counter */
}
}
ADMUX = (0 << REFS1) | (0 << REFS0) | (adcChannel & 0x07); /* set which channel to read next time */
ADCSRA |= (1 << ADSC); /* start another conversion */
}

Jeg har lavet følgende ændringer:
  • flyttet ADCSRA |= (1 << ADSC); ned i bunden.
  • sat paranteser omkring adcWriteIndex + 1 og adcReadIndex + 1

ADCSRA-linien bør nok stå efter ADMUX linien, fordi ADMUX fortæller hvilken kanal vi vil læse fra næste gang, og ADCSRA-linien starter næste konvertering.
Derudover sætter jeg parantes omkring adcWriteIndex + 1 og adcReadIndex + 1, fordi 'select', dvs. udtrykket " <udtryk> ? <udtryk> : <udtryk> " har det med at være prioriteret anderledes end man forventer, så det er bedst altid at bruge paranteser, når man bruger dem.

Det burde hjælpe at få ADCSRA linien flyttet. Jeg har ingen anelse om hvorfor jeg ikke har sat den efter ADMUX linien... <glob> :)

Prøv at sætte noget lysdiode-test ind i ADC-interruptet.

33
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 21, 2011, 08:17:05 »
lige efter initled() i main så slukker alle led (det gør de ikke hvis jeg først skriver dem efter eks sei)

Aha. Jeg tror jeg er klar over hvad der sker nu. :)

Jeg har på fornemmelsen at programmet går ned.
-Du skal nemlig kunne tænde/slukke LEDs uanset hvor du er i koden.
Virker det ikke efter sei(), så betyder det at programmet ikke kommer videre.

Dvs. der er sikkert et eller andet interrupt, som er gået i ged. Mere om hvordan vi får det på plads senere.

Citér
apropos SEI. skal den stå 2 steder. kan det ikke skabe problemer at enable interrupts 2 steder?

cli() slår interrupts fra.
sei() slår interrupts til.
Du kan gøre dette så ofte du vil.
Mere detaljeret: sei() sætter bit 7 i SREG, mens cli() sletter bit 7 i SREG.
SREG's bit 7 hedder I, og står for "global Interrupt enable'.

Citér
så men efter de alle er slukket, smider jeg setLED1((SREG >> 7) & 1); ind i main's while løkke og alt er stadig slukket så væk med den igen.

Sikkert fordi programkørslen aldrig kommer ind i main's while-loop. ;)

Citér
Fandt ud af noget interessant. Jeg kan bruge setLED#(0) før initdosing i main.c men samme komando virker ikke efter initdosing

Aha.. Fejlen er fundet.

Citér
så det må vel betyde at den hænger i init af dosing et eller andet sted

Fuldstændig korrekt.

Citér
men så tænker jeg
i startdosing sætter den gSettings = calculateSettingsDip(getADC1Value()); men calculateSettingsDip funktionen hedder calculateSettingsDip(uint16_t gDipSwitches) det stemmer jo ikke overens, så prøver at ændre i startdosing så det er gSettings = calculateSettingsDip(uint16_t gDipSwitches istedet for gSettings = calculateSettingsDip(getADC1Value());
og det kunne jeg ikke.

Nej, for gDipSwitches er en parameter som er lokal og kun kan ses af calculateSettingsDip, og derfor bør denne parameter ikke hedde gDipSwitches, men aDipSwitches. :)

Kode:
uint8_t calculateSettingsDip(uint16_t aDipSwitches)
-Så alle steder i koden, bør gDipSwitches blive erstattet med aDipSwitches.
(Dette er i Dosing.h og Dosing.c)

Citér

den slukker led gennem hele uint16_t getADCValue(uint8_t aADC) men i void waitUntilADCStable() slukker den ikke noget

Fejlen(e) er:

1: Koden venter på at ADC'en er stabil, men ADC'en er ikke sat igang endnu, så den venter forgæves og bliver ved med at vente.

2: Hvis nu vi kom forbi waitUntilADCStable(), så ville vi komme ind i timer0Elapsed, som venter 10 sekunder. Her vil den blive ved og ved at vente, fordi timer0 ikke er startet endnu.

Løsningen er ganske simpel:

Du bør ikke kalde startDosing() fra din initDosing().
Dette er fordi init____ rutinerne er ment som at skulle lave opsætning (opsætning der lige tager få clock-cycles) og ikke andet; de må ikke vente på noget.

Så prøv at flytte startDosing() fra initDosing over i Main.c, lige efter sei();


Citér
og nu vil jeg stoppe for i dag og hoppe i seng  8)

Fornuftigt. :)
Denne beskrivelse har været rigtig god. Jeg regner med at du i dag kan få lysdioderne til både at lyse og blinke, plus nogle andre småting. ;)

Du burde efter ændringen kunne få følgende i main's while-loop til at virke...

Kode:
while(1)
{
    toggleLED1();
    waitSeconds(1);
}

34
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 20, 2011, 15:52:08 »
Tænk at man kan få en weeee fornemmelse af at se en led toggle he he, men glæder mig faktisk gg

Ja, jeg har selv prøvet den med en LED. ;)
-Det var endda efter AVR, for jeg gik videre til ARM, men ... Det tog jeg ved ikke hvor meget bøvl, først skulle jeg have compilet en hel toolchain, så skulle denne toolchain sættes op (dvs. compiler + brænder/debugger programmet OpenOCD), så skulle JTAG'en konfigureres i OpenOCD, for den setting der var med duede ikke. Nå, men langt om længe fik jeg lavet et program, compilet det, brændt det over i ARM-chippen og den ville ikke noget, der skulle speciel hardware-opsætning til (5 gange så meget opsætning som AVR), og den var stadig umulig. Men efter nogle måneder lykkedes det mig at få en lysdiode til at blinke på netop den måde jeg ville blinke den (dvs. uden toggle; alle eksempler der var givet, var nemlig med toggle; jeg ville skrive den direkte værdi til porten).

...Jeg stoppede med Atmel ARM, da jeg yderligere efter flere måneder (og spørgen om hjælp på AT91 forum'et) ikke kunne få timeren til at køre; jeg fik dog lavet mit proof-of-concept. :)

35
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 20, 2011, 09:28:32 »
Hmm nej. jeg forstår det ikke.
Her kan jeg være helt med. ;D

...Men du skal ikke lade dig forvirre af disse ting. :)
Citér

hvis jeg har prescaler 8 i TCCR0B kan jeg godt toggle leds ved tryk på start knap, og følge det helt hen til start dosing. men den vil ikke toggle pr. sek i timeren.

OK. Vi skal prøve at lave en test. =)

Prøv at lave main's while loop om til...
Kode:
while(1)
{
    setLED1((SREG >> 7) & 1);
}

Dette skulle gøre at LED1 fortæller (hele tiden) om vores interrupts kører eller ej.

Citér
sætter TCCR0B prescaleren til 64 som den skal kan jeg tænde og slukke dem med en setLED(1) eller 0 i main lige efter init led, men reagerer ikke på noget med toggle eller on eller off  hvis jeg smider det ind i startknap funktionen ??

HOV! Jeg kom til at klokke i det; en ting jeg næsten altid glemmer med hensyn til toggle.

Toggle-linien må ikke hedde...

Kode:
PINA |= (1 << PA4);

men skal hedde

Kode:
PINA = (1 << PA4);

-Det kan godt påvirke i den retning, at det slukker alle de andre portben på PORT A, og dermed alle andre LEDs. :)

-Jeg har sendt dig en ny leds.c og leds.h. =)

Citér


Til gengæld kan jeg se at den springer direkte over i startdosing i dosing.c uden at jeg trykker på knappen for der kan jeg kode leds til at tænde eller slukke men stadig reagerer de ikke på startknappen

...Mumle, mumle... Måske indsætte toggle-LED i timer0Elapsed() ?

Citér
Efterfølgende har jeg fået 1 led til at toggle ved tryk på start, med prescaler 64, men den lyser stadig konstant hvis jeg smider toggle ind efter sSeconds++

Sikkert beslægtet med toggle-LED fejlen jeg omtalte ovenover.

Citér
tror også jeg fandt en anden fejl.
når der trykkes på start kaldes startdosing rutinen, men den har jo ingen adc1 værdier at forholde sig til så ved ikke om  flg skal ind i startknap rutinen lige inden startdosing bliver kaldt
gSettings = calculateSettingsDip(getADC1Value());

Korrekt. Et bedre sted at sætte den er dog i startDosing(), fordi startDosing bliver kaldt 2 steder fra, nemlig i initDosing() og fra start-knappen.

Nu ser min startDosing således ud:
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 };

gSettings = calculateSettingsDip(getADC1Value()); /* read dip switches and update gSettings */
setMinuteCountdown(pgm_read_word(&timeTable[(gSettings >> 2) & 0x03]));
timer0Elapsed();
}

36
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 20, 2011, 08:25:26 »
Man skulle næsten tro at min avr er brændt af eller noget. når jeg sætter prescaler til det som du sagde, så lyser alle leds hvad enten jeg sætter dem til off eller ej ?!?!  :-[

Heh, den er ikke brændt af; der skal en del til. :)

Denne prescaler værdi burde være korrekt.
I Makefile er fuses sat til H:0xdf og L:0x62.
Dette betyder at microcontrolleren kører 1 MHz.
F_CPU skal derfor være 1000000, det er den også.

Hvis vi dividerer F_CPU med 64, får vi 15625.
Dividerer vi 15625 med 125, får vi 125. Begge disse værdier (125 og 125) passer i en byte.
Da vi har sat WGM0x til 0:0:0, er vores Timer0's MAX værdi 255.
-Så den ene trækker vi fra 256 og lægger i TCNT0 (for Timer0's MAX er 255, og der er så 256 tælle-værdier). altså 256 - ((1000000 / 64) / 125) = 131.

Derfor ser linien der sætter TCNT0's værdi sådan ud:
Kode:
TCNT0 = 256 - ((uint8_t) ((F_CPU / 64) / 125));

TCNT0 starter med andre ord på 131 og tæller op til 255, hvorefter Timer0's overflow interrupt udføres så snart TCNT0 vippes om fra 255 til 0.

I overflow-interruptet gen-indstilles værdien på TCNT0, til næste gang. (Dette er det aller første der skal være i interruptet, for ellers vil værdien kunne 'glide', og derved ville tidsmåleren kunne tabe tid.

Derudover har jeg været årsag til endnu en fejl (fordi jeg ikke har været ordentlig vågen), i initTimer0 står nemlig:
Kode:
	TIMSK0 &= (1 << TOIE0);

Dette skulle have været...
Kode:
	TIMSK0 &= ~(1 << TOIE0);

... tilde (~) vender nemlig alle bits i en værdi til det modsatte.

Hvis der stadig ikke er nogen ændring, så prøv lige midlertidigt, at stille værdien tilbage til CS0x = 0:1:0, og se om der ændres noget.
Hvis alle LEDs derefter lyser, er det ikke pga. timeren det er galt.

Min initTimer0 ser nu således ud:
Kode:
void initTimer0()
{
cli(); /* disable interrupts if not already done */
sSeconds = 0;
sMinuteCountdown = 0;
sMinuteCountdownRestart = 0;
TIMSK0 &= ~(1 << TOIE0); /* clear 'Timer Overflow Interrupt Enable 0' bit in 'Timer Interrupt MaSK 0' */
/* set up timer to run in normal mode: (WGM02:WGM01:WGM00 = 000 */
/* make timer use PRESCALER64: (CS02:CS01:CS01 = 011): */
TCCR0A = (0 | (0 << COM0A1) | (0 << COM0A0) | (0 << COM0B1) | (0 << COM0B0) | (0 << WGM01) | (0 << WGM00));
TCCR0B = (0 | (0 << FOC0A) | (0 << FOC0B) | (0 << WGM02) | (0 << CS02) | (1 << CS01) | (1 << CS00));
/* Clear any pending interrupts, so we don't get an accidental interrupt immediately after enabling interrupts... */
TIFR0 |= (1 << TOV0); /* clear 'Timer OVerflow 0' bit in 'Timer Interrupt Flag Register 0' */
/* enable Timer OVerflow 0 interrupt: */
TIMSK0 |= (1 << TOIE0); /* set 'Timer Overflow Interrupt Enable 0' bit in 'Timer Interrupt MaSK 0' */
}

37
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 23:06:03 »
:)
men den toggler desværre ikke hvert sek. den lyser bare konstant det betyder vel at timeren ikke kører som den skal  :o

Hmm, det kan være den bare er vældig langsom.
Prøv at vente 8-10 sekunder, og se så om den slukker...

Ihvertfald har jeg lige fundet en lille fejl:

Prøv at åbne Timer0.c...
I ISR(TIM0_OVF_vect) står noget med F_CPU / 64, dvs, her regner vi med at vi bruger prescaler clk/64!
Går vi ned i initTimer0, og kigger på TCCR0B = ..., ser vi at CS02, CS01 og CS00 er sat til 010, dvs. prescaler = clk / 8.
Derfor skal vi lige have rettet (0 << CS00) til (1 << CS00), og kommentaren 2 linier ovenover skal hedde PRESCALER64 istedet for PRESCALER8.

Dette burde få timeren til at køre i korrekt hastighed.

38
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 20:17:17 »
tusind tusind tak  :P

Bare hyggelig (dette er den norske måde at sige velbekomme)

39
Strømforsyninger - Omformer - Inverter / Sv: Blæser+LED
« Dato: November 19, 2011, 20:00:46 »
Tar vel omkring de 3 volt, og 10mA?

Ikke fordi det er vigtigt i denne sammenhæng, men det kan være en god idé at regne som standard at en LED tager 20mA (eller op til 30mA i dagens Danmark).
Jeg ved godt, at der er stor forskel, men som grundregel har jeg altid brugt 20mA; dog kan det være jeg skal til at tænke at de ofte sluger 30mA.

Dette er jo nødvendigt at tænke på, når man sætter dem direkte til benene på en IC som fx. AVR.

40
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 19:47:18 »
lige et spørgsmål mens jeg pakker og sender.

Du skulle på nuværende tidspunkt have modtaget en mindre modifikation af koden - ikke noget afsindig vigtig, men bare 'housekeeping', og så en rettelse af Makefile, som havde en fejl i 'clean' funktionen.

Citér
er der en hurtig måde man kan toggle et led så den tænder og slukker hver gang sekund skifter ? noget bit shift eller noget

AVR har sådan en smart feature (som jeg mener at PIC også har, for den sags skyld), at skriver man til INPUT porten, vil alle de bits, man skrive, blive togglet til det modsatte.

Så du kan...
Kode:
    PINA |= (1 << PA4);  /* toggle LED on/off */

(PINA - også kaldet PORTINA - er dér, hvor du læser værdier, mens PORTA er dér, hvor du normalt skriver værdier)

Den stump kode kan du prøve at sætte ind i ISR(TIM0_OVF_vect), lige efter sSeconds++;

41
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 17:47:55 »
gg så prøver jeg lige den her istedet
GIMSK  |= (1<<PCIE0);

Meget bedre. :)

Citér
Hvis GIMSK kun har 3 muligheder int0 PCIE1 og PCIE0 hvorfor melder compiler så ikke fejl når jeg skriver andet.

Dette skyldes at PCIE1 og PCIE1 kun er talværdier.
Du kunne i teorien også skrive...

GIMSK = 172;

Men det er noget mere forståeligt at bruge de macroer / definitioner, som tilhører GIMSK ifølge databladet.


Citér
WEEEEEEEE der sker noget. men den mangler at registrerer led 3. men den tænder godt nok led 4 i startDosing();   (dog ikke altid. men 90% af gangene) og altid 2. gang hvis ikke første

Lyder godt. Fejlene må vi lige kigge på, den er nødt til at gøre det samme hver gang, så man kan stole på den. ;)

Hvis nu din programmerings-enhed er koblet på, samtidig med at du tester, kan den være årsag til at den ene LED ikke tændes.
Prøv at koble programmerings-enheden fra, for lige at afprøve teorien. ;)

Citér

pinValue = PINA & (1 << PINA3);
if(pinValue)
          {
      setLED3(1);
      setLED2(0);                              /* turn LED1 off */
                startDosing();   
          }

Det kan være det er tid til at du sender mig en opdatering af hvordan filerne ser ud nu.
Det er bedst, hvis du højre-klikker på mappen og vælger at komprimere den til et zip-arkiv.
-På den måde får du også en backup af hvordan det hele ser ud på nuværende tidspunkt, hvis nu der skulle gå ged i et eller andet. :)


42
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 15:51:15 »
skal GIMSK hedde
GIMSK  |= (1<<PCINT0);

Nej. :)

43
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 19, 2011, 06:33:22 »
kan jeg gøre flg.
lave en led.c med flg
{snip}
og en led.h med prototypes på de 4 setLED1(uint8_t aState)
Så laver jeg en #include "led.h" i alle *.c

Ser fint ud.

Det kunne være godt med...
Kode:
void initLED()
{
    DDRA |= (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7);
}

og så kalde denne fra main(), fx. lige efter GPIOR2 = ...;


Citér
for at teste kan jeg så ikke bare redigerer i den *.c hvor der er noget jeg vil teste, og tilføje
{snip}

God idé. :)

Mit forslag til ovennævnte rutine er...

1: undgå at bruge globale variabler, men i stedet giv parametre (argumenter) til rutinen.
2: en smart lille forkortelse:
Kode:
void setLEDs(uint8_t aValue)
{
    PORTA = (PORTA & ~(1 << PA4) | (1 << PA5) | (1 << PA6) | (1 << PA7)) | (aValue << PA4);
}


PA4 har så værdi 1, PA5 har værdi 2, PA6 har værdi 4, PA7 har værdi 8.
Når de lyser, lægger du værdierne for dem sammen, fx. vil...
setLEDs(11);
få PA4 + PA5 + PA7 til at lyse, hvilket giver...
1 + 2 + 8 = 11...
[/quote]

jeg har svært ved at se hvordan keg kan compile og teste 1 modul ad gangen da de alle er vævet sammen og er afhængige af værdier fra andre end sig selv
[/quote]

Forståeligt nok. =)

Hvis jeg selv har rodet mig ud i store problemer, laver jeg et nyt selvstændigt program, og i dette selvstændige program laver jeg den del jeg vil teste.

Fx. til at starte med, ville jeg tage et selvstændigt modul (noget der ikke har andet vævet ind i sig), nemlig ADC'en.
ADC.h og ADC.c er selvstændigt bygget op (det er med vilje at heg har presset dig til at holde det hele modulært opbygget).

ADC.c og ADC.h kan indbygges i et andet program, og når de er testet og virker, så kan man gå videre til næste modul, fx. Timer0.c og Timer0.h.

Citér
Når jeg gør det på den måde, ser det ud til at selve start knap funktionen ikke virker.
jeg kan tænde og slukke led 1 på pa7 ved at skrive setLED1(1); eller setLED1(0); i starten af main.c (som det sidste i init main) men hvis jeg skriver setLED1(1); nede i ISR(PCINT0_vect) funktionen så sker der intet når jeg trykker på start knappen. er dog ikke helt sikker på at min led rutiner er globale

Min main.c ser således ud
Kode:
/* {snip} */
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) | (0 << ISC00); /* interrupt on INT0 pin, falling edge */
GIMSK  |= (1<<PCINT3);
setLED1(1);
while(1)
{
/* we don't really need to do anything here. Everything is handled by the interrupts */
}
    return(0); /* (never reached) */
}
ISR(PCINT0_vect)
{
    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 */
        {
setLED1(0);  /* turn LED1 off */
            startDosing();   
        }
    }
}

Ikke at det er noget der får programmet til ikke at virke, men jeg vil anbefale at rokere lidt om, plus at ændre linien MCUCR = ...:

Kode:
    	PCMSK0 |= (1<<PCINT3);								/*Set PA3 as the pin to use*/
MCUCR = MCUCR & ~((1 << ISC01) | (1 << ISC00)) | (1 << ISC01) | (0 << ISC00); /* interrupt on INT0 pin, falling edge */
GIMSK  |= (1<<PCINT3);
sei(); /* globally enable interrupts */

linien som skriver i MCUCR ændrer nu ikke ved de andre bits i dette register (de var 0 i forvejen, men hvis du en dag kigger tilbage på koden, trækker du ikke en ting med over i et nyt progam, som kan give dig bøvl).
sei(); er sat sidst, fordi PCINT0 er et interrupt, og vi vil gerne 'have ro' mens vi sætter interrupts op.

Når så det er gjort, skal du vide at....
MCUCR registret har intet med Pin Change interrupt at gøre.
Den har kun med INT0, altså Pin B2 at gøre, så fjern den linie fuldstændig. :)

Derudover...
Kode:
	GIMSK  |= (1<<PCINT3);
[code]

Se side 50 i databladet. :)
Derefter se side 52.

(Den slags har jeg selv haft meget bøvl med, [fnis])

Prøv så følgende...

I main's while(1):
[code]while(1)
{
    setLED0(0);
    setLED1(0);
    setLED2(0);
    setLED3(0);
}

...i PCINT0:
Kode:

ISR(PCINT0_vect)
{
    uint8_t pinValue;
    pinValue = PINA & (1 << PINA3);                             /* read value of input-pin */
    setLED0(1);
    if(pinValue) /* we're only interested if button is pressed */
    {
        setLED1(1);
        _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 */
        {
            setLED2(1);
            startDosing();   
        }
    }
}

44
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 18, 2011, 18:56:47 »
Citér
Timer0.c:39: warning: 'SIG_OVERFLOW0' appears to be a misspelled signal handler
Prøv i Timer0.c at ændre... {snip}
Har ikke en SIGNAL (SIG_INT0), men en SIGNAL (SIG_OVERFLOW0) /*This interrupt occurs when TCNT0 wraps to 0*/
hvis jeg ændre den til ISR(INT0_vect) får jeg stadig samme fejl.

Alle gode gange to-og-en-halv...

-Jeg forvirrede mig selv med at jeg på et tidspunkt havde brugt INT0 til start-knap. :D

Prøv TIM0_OVF_vect - den er måske bedre... ;)
Citér

De andre fejl er rettet og fungerer fint.
lavede en void waitSeconds(uint8_t aSeconds); i timer0.h
waitSeconds er jo en del at timerfunktionen der holder øje med døgnet så syntes ikke den skulle fjernes fra timer0.c hvor den bruges.
og fejlen forsvandt da jeg lavede linjen i timer0.h

Dette er det korrekte sted. :)

Du kan se en oversigt over interrupt-vektorer og navne på AVR-GCC's side.

45
Generel Elektronik / Sv: hjælp til servo kontrol med timer
« Dato: November 18, 2011, 07:20:17 »
så fik jeg den compilet
og nu laver den da hex filen men stadig lidt problemer med nogle warnings.
prøvede alligevel at smide den på avr men virkede self ikke  :P

Når jeg programmerer en AVR, har jeg slet ikke nogle simulator-værktøjer.
Min fremgangsmåde er cirka følgende:
1: Skriv et lille program, som gør en simpel ting.
2: Få det til at compile.
3: Brænd det over på AVR'en.
4: Se om det fungerer som jeg forventede.
5: Hvis der er fejl, ret fejlene, tilbage til 2
6: Ingen fejl, udvid med næste funktion, tilbage til 2.

I andre tilfælde, når jeg har et større program, hvor jeg skal lave ny funktionalitet, skriver jeg et lille prøve-program, som kun gør den ene ting, og når det virker, fører jeg princippet over i det større program.

Citér
avr-gcc -Wall -Os -DF_CPU=1000000 -mmcu=attiny44a -c Main.c -o Main.o
Main.c:36: warning: 'SIG_PCINT0' appears to be a misspelled signal handler

Ups, min fejl; jeg fik blandet interrupt-navnene sammen, fordi hvis man bruger den ene type erklæring, skal de navngives i én stil, hvis man bruger en anden type erklæring, skal de navngives i en anden stil.
ISR( ... ) er den anbefalede type erklæring, så den vil jeg så lære fra mig... ;)

Prøv i Main.c, at ændre...
Kode:
SIGNAL (SIG_PCINT0)
...til...
Kode:
ISR(PCINT0_vect)

Citér
ADC.c:54: warning: 'SIG_ADC' appears to be a misspelled signal handler

Prøv i ADC.c, at ændre...
Kode:
SIGNAL (SIG_ADC)
...til...
Kode:
ISR(ADC_vect)

Citér
Dosing.c:67: warning: implicit declaration of function 'waitSeconds'

Hvor ligger funktionen 'waitSeconds' ?
-Det kunne være en god idé at lægge den ud i sin egen fil, fx. "Wait.c", og så lave prototypen på funktionen i "Wait.h"


Citér
Timer0.c:39: warning: 'SIG_OVERFLOW0' appears to be a misspelled signal handler

Prøv i Timer0.c at ændre...
Kode:
SIGNAL (SIG_INT0)
...til...
Kode:
ISR(INT0_vect)

Forklaring:
Da ingen af disse interrupt-navne er genkendt, vil de ikke køre.
Derfor vil programmet ikke kunne virke...
1: Timer0-interruptet kører ikke; dvs. sekunderne tæller ikke.
2: ADC-interruptet kører ikke, dvs. vi får ikke værdien fra ADC'en beregnet/opdateret
3: Interrupt0 er ikke installeret, hvilket vil sige at vores start-knap ikke bliver aflæst.

-Med de korrekte navne, skulle det dog have en chance for at blive lidt bedre. :)

Citér
   text      data       bss       dec       hex   filename
   1188         2        32      1222       4c6   aquadose.elf
[/quote]

TEXT + DATA = 1190 bytes: Selve programmet kan fint ligge i Flash hukommelsen.
DATA + BSS = 34 bytes: Der er SRAM nok på chippen til både data og stack.

TEXT bliver lagt kun i Flash-hukommelsen.
DATA bliver lagt i Flash-hukommelsen, men når programmet starter op, kopierer det DATA fra Flash over i SRAM'en.
BSS er værdier der starter på 0. Der bliver reserveret plads til dem i SRAM'en.

Citér
Har sådan et multimeter
http://australianrobotics.com.au/products/dm830d-lcd-digital-multimeter
så kan ikke rigtigt måle frekvensen "tror jeg"
Citér

Hvis du kigger mellem 'diode-symbolet' og 'hFE', er dette så ikke 'frekvens' ? - Det
Sjovt, jeg har selv et DT830B, jeg bruger en del, men det har ikke det symbol.
...Men jeg vil nok prøve at holde udkig og se om jeg kan få fat i et DM830D, da det jo er lidt bedre end mit nuværende (jo, jeg har en Fluke, men den fylder og vejer cirka det dobbelte).

Citér
Desuden har jeg konstateret at servoen skal have strøm fra samme enhed som leverer til microcontroleren.

Det kan være jeg tager fejl, men jeg mener det ikke burde være nødvendigt. Hvad der er vigtigt, er at du har sat microcontrolleren's GND til servoens GND. :)

Citér
jeg troede at jeg kunne smide en anden strømforsyning på servoen og så bare få impulserne fra avr men det har jeg testet med en servotester og det kan tilsyneladende ikke lade sig gøre. ved ikke lige hvorfor.

...Hvis man ikke kan, så kan man ikke, men det ville undre mig hvis det er sådan... ;)

Men skaber det problemer når servoen går igang? jeg mener vil det ikke lave en lille forstyrrelse på strømmen til avr, når servo lige pludselig trækker 5 volt?
med mindre jeg kan lave et eller andet trick med f.eks at samle alle gnd

Det kommer helt an på hvor mange Ampere servoen trækker.
Du bør dimensionere din strømforsyning, så den har ampere nok til at trække servoen plus microcontroller.
Et hurtigt gæt er det antal Ampere servoen trækker plus 50 mA til microcontrolleren, plus 50 mA ekstra til dårlige tider. ;)
-Og så skal du nok have en elektrolyt kondensator på før din spændings-regulator, og en efter din spændings-regulator.
Hvis jeg trækker 50 mA på mit board, plejer jeg at bruge 33uF før spændings-regulatoren, og 10uF efter.
Men det vil nok være en god idé at sætte nogle større på.
Hvad jeg ville gøre, er noget i stil med... Start med to stk. 10uF. Det burde ikke være nok til at trække apparatet.
Skift værdien på kondensatorerne op til 33uF, derefter 56 uF, så 82uF, 100uF, ... med lidt spring ind imellem.. Når den så begynder at kunne trække, så hop nogle værdier op, det gør ikke noget du dobler op, med mindre, selvfølgelig at kondensatorerne kommer til at fylde 10 cm i højden og vejer en bondegård. ;)

Sider: 1 2 [3] 4 5 ... 21