Sida 3 av 4
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 5 maj 2010, 02:08:03
av bearing
Varför bemöter du inte frågor och tips?
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 5 maj 2010, 09:01:14
av barbarossa
En liten reflektion. Varför skall du stänga av motorn när du bromsar? Inga andra fordon gör detta och det normala användarbeteendet är att slå av gasen vid bromsning.
Skall du ha någon form av fartfhållare?
//A
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 9 maj 2010, 23:57:28
av Leon23
Bearing:
Jag lägger alltid ner mycket tid innan jag postar ett inlägg för att göra inläggen så tydliga och professionella som möjligt, dvs att inte folk som ni som hjälper ska behöva gå igenom något onödigt, och om jag missar att svara på någon fråga någon gång får ni ha överseende med det.
Interruptfunktionen fungerar bra, ser inte någon anledning än till att använda capture enheten (dessutom ligger väl den på CCP1, dvs samma som PWM utgången?)
Programmeringen sköts fortfarande via MikroC.
Barbarossa:
Med farthållare tänker jag att man vill kunna döda motorn på ett enkelt sätt när man cyklar. Med ett enkelt knapptryck på resume (efter man bromsat) skall man även kunna komma tillbaka till inställd hastighet.
Får se om jag kan komma vidare imorgon. Varvtalsmätningen var lite klurigare än vad jag först trodde.
MVH
/Oscar
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 00:47:35
av bearing
Ja just det, MicroC har en egen miljö, tänkte inte på det. En del kompilatorer går att integrera i MPLAB så att man får möjlighet att simulera C-koden.
Din processor har två stycken CCP-enheter (om jag minns rätt), så det borde gå att använda på PWM och Capture samtidigt. Anledningen till att jag föreslog Capture var att jag bara ser fördelar - man får både interrupt och periodmätning på en gång.
Fast, ifall jittret är litet i förhållande till avståndet mellan pulserna (som nog är fallet här) har jittret ingen märkbar påverkan på den uträknade hastigheten.
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 10:12:47
av Leon23
Bearing:
Har du någon kunskap gällande reglerteknik? Kommer bli ett reglertekniskt problem att få hastigheten till sitt börvärde med hjälp av farthållaren, exempelvis 20 km/h.
Jag har själv läst en grundkurs motsvarande 7,5 hp i ämnet, men vet inte om det finns något man kan använda sig av som är integrerat i uC eller i mikroC. Ska kika på det lite senare ikväll.
/Oscar
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 10:28:23
av barbarossa
Du behöver inte vara särskilt begåvad för att få en PI algoritm att funka. Ibland kan till och med akademiskt tillvägagångssätt ställa till problem då utvecklaren helt enkelt tänker för mycket och gör för lite. (Personlig reflektion)
MikroC har inget integrerat.
UTny = UTgammal + Kp*(FELny-FELgammal) + Ki*FELny
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 14:37:42
av bearing
Jag har också läst en grundkurs i reglerteknik. Den var fem högskolepoäng (gamla poäng) tror jag, så då borde vi läst samma mängd.
Vi fick lära oss om Ziegler Nichols metod för att ställa in en PID regulator. Den gick ut på att sätta I-faktorn och D-faktorn lika med 0, sedan justera P-faktorn tills systemen självsvänger med konstant amplitud. Utifrån P-värdet och självsvängningsfrekvensen kan man välja utgångsvärden för I- och D-faktorerna enligt en tabell.
http://en.wikipedia.org/wiki/Ziegler%E2 ... ols_method
Vi labbade även en del, och justerade faktorerna för hand. Det var inte jättesvårt att resonera sig fram hur faktorerna skulle justeras för att förbättra systemet, baserat på hur systemet betedde sig.
Jag tror inte heller det är så svårt att få till en PID-regulator. Någon form av loggning, helst med relevant data ur PIC:en själv, kommer nog vara till stor hjälp vid inställning av regulatorn.
Tillägg:
Kolla in AVR221 för exempelkod och PDF om PID-regulator
http://www.atmel.com/dyn/products/app_n ... ily_id=607
Regulatorfunktionen är principiellt uppbyggd såhär:
Kod: Markera allt
error = setPoint - processValue;
sumError += error;
p_term = P_Factor * error;
i_term = I_Factor * sumError;
d_term = D_Factor * (lastProcessValue - processValue);
ret = (p_term + i_term + d_term) / SCALING_FACTOR;
lastProcessValue = processValue;
return((int16_t)ret);
EDIT: ändrade term till faktor
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 20:08:35
av Leon23
Jag skall bemöta inläggen angående reglering så småningom, skall bara se till att få hastighetsmätningen att fungera korrekt först (annars blir det lite svårt att reglera hastigheten).
Har någon, någon idé varför motorn avger ett högfrekvent vinande när jag använder timers i interruptrutinen? Det låter ungefär som motorn får fel PWM frekvens.
Motorn låter bra igen när jag kommenterar bort timerraderna i interruptiniteringen, så felet borde väl rimligen finnas där. Jag är själv lite kluven.
Relevant kod:
Kod: Markera allt
/* Timer2 Settings */
T2CON=0x21; // Prescaler 1:4, postscaler 1:5 (osc/4) dvs 8MHz/4*4*5=100kHz
PR2=100; // Räkna till hundra, dvs detta skapar interrupt varje 1ms
PIR1.TMR2IF=0; // Nollställ interruptflagga?
T2CON.TMR2ON=1; // Timer2 ON
PIE1.TMR2IE=1; // Timer2 interrupt aktiverad
}
void interrupt (void){
if(PORTB.B0==0 && PIR1.TMR2IF==0){ // Kolla om RB0 är 0, i så fall har vi negativ flank
Hastighet=1500/Timer_ms;
if(Hastighet<2)
Hastighet=0;
Timer_ms=0;
}
if(PIR1.TMR2IF){ // Om timer2 interrupt inträffar (varje ms)
Timer_ms++; // Öka variabeln Timer_ms med 1
}
INTCON.INTF=0; // Klarsignalering; Nollställ interruptflagga
PIR1.TMR2IF=0; // Nollställ timer 2 interruptflagga
}
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 20:45:06
av barbarossa
PWM använder TMR2
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 22:06:32
av Leon23
Ja det är ju logiskt! Har sett många exempel på PWM reglering m.h.a. Timer2 funktionen och PWM.
Hopp detta ställer ju till med lite problem eftersom Timer2 kan man jämföra mot ett värde, vilket man i databladet inte kan med Timer0 och Timer1.
Enligt mina beräkningar får jag det till följande (för att generera ett interrupt varje ms)
uC körs i 8MHz. Timer0 ger ett interrupt för varje 256:e clockcykel.
Med en prescaler på 8 borde jag alltså få ett interrupt för varje 2 000 000/ 256*8 = 976 Hz vilket borde ge ett interrupt nästan varje ms.
(intern klockcykel = Fosc/4)
Kan detta stämma?
Saxat från databladet:
"Timer0 will generate an interrupt when the TMR0
register overflows from FFh to 00h. The T0IF interrupt
flag bit of the INTCON register is set every time the
TMR0 register overflows, regardless of whether or not
the Timer0 interrupt is enabled. The T0IF bit must be
cleared in software. The Timer0 interrupt enable is the
T0IE bit of the INTCON register."
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 10 maj 2010, 22:54:56
av barbarossa
PWM biblioteket använder inga interrupt, så du kan mycket väl använda TMR2 till att generera interrupt med frekvensen #, där # sätts av PWM1_Init(#). Du skall däremot vara noga med vad kompilatorn gör med C koden när du använder färdiga bibliotek.
//A
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 11 maj 2010, 00:10:29
av Leon23
Du har helt rätt med att man ska vara försiktig med "färdiga biblotek"
Givetvis kan man använda Timer2 för interrupts, men det känns mer krångligt att skriva en funktion som ändrar registren, än att använda en annan timer för att initiera interrupt!
Nu erhåller jag dock kompileringsfel om jag har med någon av de raderna som är bortkommenterade i denna kod, Det verkar helt ologiskt?! Tycker mig kunna T2CON och OPTION_REG utantill vid det här laget.
Kod:
Kod: Markera allt
/* Interrupt settings */
OPTION_REG.INTEDG=0; // Interrupt Edge Select bit, negativ flank
// OPTION_REG.TOCS=0; // Internal instruction cycle clock (Fosc/4)
OPTION_REG.PSA=0; // Prescaler is assigned to the Timer0 module
OPTION_REG.PS1=1; // Prescalern sätts till 8. (8MHz/4*256*8=1kHz)
INTCON.GIE=1; // Enabla globalt interrupt
// INTCON.T01E=1; // Timer0 Overflow Interrupt Enable bit
INTCON.INTE=1; // Enabla INT/RB0 extern interrupt
INTCON.INTF=0; // Nollställ flaggan
// INTCON.T01F=0; // Timer0 Overflow Interrupt Flag bit
}
void interrupt (void){
if(PORTB.B0==0 /*&& INTCON.T01F==0*/){ // Kolla om RB0 är 0, i så fall har vi negativ flank
Hastighet=1500/Timer_ms; // Ex: 100 ms mellan 2 flanker, ger en Hastighet på cykeln till 15km/h.
if(Hastighet<2)
Hastighet=0;
Timer_ms=0;
}
if(1 /*INTCON.T01F==1*/){ // Om Timer0 interrupt inträffar (varje ms)
Timer_ms++; // Öka variabeln Timer_ms med 1
}
INTCON.INTF=0; // Klarsignalering; Nollställ interruptflagga
// INTCON.T01F=0; // Nollställ Timer0 overflow Interrupt Flag bit
}
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 11 maj 2010, 00:18:10
av bearing
Timer 0 Interrupt Enable = T0IE
inte T01E
Timer 0 Interrupt Flag = T0IF
inte T01F
sen borde du flytta nollställningen av interruptflaggorna till innanför if-satserna, annars kommer ju t.ex. INTF-flaggan nollställas innan interruptet behandlats ifall INTF-sätts medans T0IF-behandlas. Om jag inte minns fel kan man ställa in INTF att bara reagera på nedåtgående flank, så slipper du PORTB.0=0-testet
Den första flaggan ser jag inte spontant felet på, men borde ju synas i dokumentationen för antingen chipet eller kompilatorn.
EDIT: nu ser jag. det står TOCS med stort O, inte en nolla.
Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 11 maj 2010, 10:33:39
av Leon23
Bearing: Tack så oerhört mycket!
Märker att det inte är bra att programmera flera timmar irad, man gör småmisstag som kan vara svåra att se.
Ska se om jag kan komma vidare idag!

Re: PWM utsignal beroende på Analog insignal (PIC16F690)
Postat: 11 maj 2010, 10:44:28
av barbarossa
Byt font till consolas