Frågor kring Tidmätning (rpm) med AVR
Frågor kring Tidmätning (rpm) med AVR
Hej.
Bakgrund…
Nu ska jag ge mig på att bland annat bygga en varvräknare till paramotorn.
Varvtalet & övrig info så som Topplocks/Avgas & Ute temperaturerna ska en Attiny2313 få jobba med. Och Presentationen ska ske på en liten alfanumerisk dogm-162 LCD-display via SPI interfacet, för att minska antalet ledningar mellan displayen & elektronikboxen.
Mätmetoder…
Enklast är väll att mäta antalet inkomna pulser under en viss tid, t.e.x 0,6sek, & sedan multiplicera antalet pulser med 100 = rpm. Men upplösningen blir ju ingen vidare om man samlar pulser under denna korta tiden. Och jag vill ju att värdena ska uppdateras minst ca 2ggr/ sek.
Det andra alternativet är då att mäta tiden mellan 2 pulser & sedan mattematiskt räkna fram frekvensen/varvtalet.
Men tidmätning i avr’n har jag aldrig varit i kontakt med, så nu behöver jag er hjälp.
Helst vill jag att varvräknaren ska vara lagom noggrann inom följande intervall 400-12’000rpm.
Och tiden mellan pulserna som ska mätas kommer då att variera mellan 150ms – 5ms
Frågorna…
Är det någon som har ett kodexempel (asm) på hur man bör konfigurera & använda dom olika timer/counter registren för att kunna mäta tid?.
Räcker det med 8 bitars räknaren, eller är det 16bitars räknaren som gäller?.
Och ju högre klock-frekvens desto noggrannare mätning antar jag, men jag antar även att det finns en optimal klockfrekvens som avsevärt underlättar den mattematiska beräkningen om man prickar rätt?.
Är den inbyggda oscillatorn tillräckligt noggrann för detta, eller bör man direkt satsa på att driva processorn med en extern kristall. Eftersom enheten ska jobba utomhus under varierande temperaturer?.
/Fagge
Bakgrund…
Nu ska jag ge mig på att bland annat bygga en varvräknare till paramotorn.
Varvtalet & övrig info så som Topplocks/Avgas & Ute temperaturerna ska en Attiny2313 få jobba med. Och Presentationen ska ske på en liten alfanumerisk dogm-162 LCD-display via SPI interfacet, för att minska antalet ledningar mellan displayen & elektronikboxen.
Mätmetoder…
Enklast är väll att mäta antalet inkomna pulser under en viss tid, t.e.x 0,6sek, & sedan multiplicera antalet pulser med 100 = rpm. Men upplösningen blir ju ingen vidare om man samlar pulser under denna korta tiden. Och jag vill ju att värdena ska uppdateras minst ca 2ggr/ sek.
Det andra alternativet är då att mäta tiden mellan 2 pulser & sedan mattematiskt räkna fram frekvensen/varvtalet.
Men tidmätning i avr’n har jag aldrig varit i kontakt med, så nu behöver jag er hjälp.
Helst vill jag att varvräknaren ska vara lagom noggrann inom följande intervall 400-12’000rpm.
Och tiden mellan pulserna som ska mätas kommer då att variera mellan 150ms – 5ms
Frågorna…
Är det någon som har ett kodexempel (asm) på hur man bör konfigurera & använda dom olika timer/counter registren för att kunna mäta tid?.
Räcker det med 8 bitars räknaren, eller är det 16bitars räknaren som gäller?.
Och ju högre klock-frekvens desto noggrannare mätning antar jag, men jag antar även att det finns en optimal klockfrekvens som avsevärt underlättar den mattematiska beräkningen om man prickar rätt?.
Är den inbyggda oscillatorn tillräckligt noggrann för detta, eller bör man direkt satsa på att driva processorn med en extern kristall. Eftersom enheten ska jobba utomhus under varierande temperaturer?.
/Fagge
Re: Frågor kring Tidmätning (rpm) med AVR
Är det mekanisk brytare till tändsystemet?
I så fall kanske du måste tänka på kontaktstuds också.
Jag vet inte själv hur man bäst avstudsar en tändningsbrytare men gissar att man ignorerar förändringar på ingången under en viss tid. Hur lång tid är jag själv intresserad av att veta
I så fall kanske du måste tänka på kontaktstuds också.
Jag vet inte själv hur man bäst avstudsar en tändningsbrytare men gissar att man ignorerar förändringar på ingången under en viss tid. Hur lång tid är jag själv intresserad av att veta

Re: Frågor kring Tidmätning (rpm) med AVR
Kan bara svara på val om mätmetod, frekvens eller periodtid.
Man får alltid ett kallat +-1 fel då man kan missa en puls beroende på hur insignalen ligger i fas med räknaren.
Vid frekvensmätning blir +-1 felet:
+-1/(fx*tg)
där fx är frekvensen hos mätsignalen och tg är grindtid, dvs tiden för räkningen.
Vid periodtidsmätning blir +- 1 felet:
+-1/(fk*tg)
där fk är klockfrekvensen för räknaren och tg grindtiden igen.
Vid multipelperiodtidsmätning blir +- 1 felet:
fx/(fk*N)
där N antal perioder som man mäter över, sedan får man då beräkna medelvärdet.
Man får alltid ett kallat +-1 fel då man kan missa en puls beroende på hur insignalen ligger i fas med räknaren.
Vid frekvensmätning blir +-1 felet:
+-1/(fx*tg)
där fx är frekvensen hos mätsignalen och tg är grindtid, dvs tiden för räkningen.
Vid periodtidsmätning blir +- 1 felet:
+-1/(fk*tg)
där fk är klockfrekvensen för räknaren och tg grindtiden igen.
Vid multipelperiodtidsmätning blir +- 1 felet:
fx/(fk*N)
där N antal perioder som man mäter över, sedan får man då beräkna medelvärdet.
Re: Frågor kring Tidmätning (rpm) med AVR
Då jag byggt 2st shiftlights till min brors rallybilar (AT90S2313 resp. AT90CAN128), kan jag bara svara på hur jag löst det. Det senaste systemet jag konstruerat har dessutom även varvtal med. Jag använder mig av ICP-pinnen (PD6 i ditt fall), den är kopplad till Timer1. Visst går det att använda 8b-timer, men då behöver man troligtvis räkna massor med overflow till en variabel vilket i stort sett betyder att man gjort en 16b-timer i mjukvara. Vilken upplösning har du tänkt dig förresten på varvräknaren? Av dina tidsangivelser antar jag att du har en encylindrig 2-taktare. Vare sig det gäller brytare- eller brytarlöst tändsystem tycker jag att du ska lågpassfiltrera signalen från tändspolen. Sedan kopplar du in den filtrerade signalen på ICP, och aktiverar ICIE1 i TIMSK (och SREG givetvis). Då får du "SIG_INPUT_CAPTURE1"-interrupt på varje tändpuls, kopierar värdet i ICR1 och nollställer. Värdet från ICR1 ska du sedan bara omvandla till rpm via lämplig skalfaktor. Dock bör du även hålla koll på overflow, då du får det vid låga varvtal, och bör skippa första CAPTURE-interruptet efter ett overflow. När det gäller intern osc, har jag aldrig övervägt det. Jag har velat ha det så exakt som möjligt.
Det här var väl inte direkt svar på dina frågor, men kan förhoppniingsvis ge dig lite idéer iaf.
Lycka till!
Det här var väl inte direkt svar på dina frågor, men kan förhoppniingsvis ge dig lite idéer iaf.
Lycka till!
Re: Frågor kring Tidmätning (rpm) med AVR
Det står i databladet hur Capture-enheten ska användas. Ställ in prescalern så att 16bit-timern inte slår över vid lägsta varvtalet.
Sen är det bara att räkna.
Varvtalet = antal timertick under 1 minut / capture-värdet.
Med 16MHz verkar det lämpligt med prescaler 64.
Det går även att köra prescalern på 1 och låta timern slå runt. I overflowinterruptet adderas 65536 till en 32bit-variabel. Sedan vid capture adderas capture värdet till 32-bitarsvariabeln. 32bitarsmätning ger högre precision samt klarar motorer som tar över en timme per varv.
Sen är det bara att räkna.
Varvtalet = antal timertick under 1 minut / capture-värdet.
Med 16MHz verkar det lämpligt med prescaler 64.
Det går även att köra prescalern på 1 och låta timern slå runt. I overflowinterruptet adderas 65536 till en 32bit-variabel. Sedan vid capture adderas capture värdet till 32-bitarsvariabeln. 32bitarsmätning ger högre precision samt klarar motorer som tar över en timme per varv.
Re: Frågor kring Tidmätning (rpm) med AVR
Iofs C kod, men du kanske kan läsa något nyttigt här.
Det är inte så svårt att använda Capture enheten för att mäta tiden mellan 2 pulser.
Det är inte så svårt att använda Capture enheten för att mäta tiden mellan 2 pulser.
Re: Frågor kring Tidmätning (rpm) med AVR
Japp det är en 2 taktare & pulserna hade jag tänkt att plocka via induktion genom att linda några varv runt tändkabeln. & sen via något filter & kanske en schmittrigger.
Nu så har jag samlat ihop infon av er & tillslut fått igång 16bitars räknaren som startar på positiv flank & stannar vid nästa positiva flank.
Men jag har kört fast vid den matematiska biten nu…
Jag har ju full frihet än att välja klockfrekvens & prescalervärden, men kan inte direkt hitta någon optimal sådan. Å det måste väll ändå finnas smidigare lösningar än att multiplicera & dividera 16bitars tal med massvis med decimaler?.
t.ex.
Timer räknarens värden * ”tiden” typ 0,000008 = Periodens tid
1 / Periodens tid = Frekvensen
Frekvensen *60 = rpm
Någon som har ett bra förslag?.
En liten bild på labben…

Nu så har jag samlat ihop infon av er & tillslut fått igång 16bitars räknaren som startar på positiv flank & stannar vid nästa positiva flank.
Men jag har kört fast vid den matematiska biten nu…
Jag har ju full frihet än att välja klockfrekvens & prescalervärden, men kan inte direkt hitta någon optimal sådan. Å det måste väll ändå finnas smidigare lösningar än att multiplicera & dividera 16bitars tal med massvis med decimaler?.
t.ex.
Timer räknarens värden * ”tiden” typ 0,000008 = Periodens tid
1 / Periodens tid = Frekvensen
Frekvensen *60 = rpm
Någon som har ett bra förslag?.
En liten bild på labben…

Re: Frågor kring Tidmätning (rpm) med AVR
400-1200 rpm tolkar jag som en frekvens in på mellan 6 och 20 Hz.
Jag började spåna på ett försök att räkna, men det är för sent nu och det kan tänkas att jag var fel ute. Här är i alla fall mina anteckningar: (vill du ha koden till "binaldiv" så kan jag klistra in den här)
Jag började spåna på ett försök att räkna, men det är för sent nu och det kan tänkas att jag var fel ute. Här är i alla fall mina anteckningar: (vill du ha koden till "binaldiv" så kan jag klistra in den här)
med räknarklocka på 1MHz/4 ( = 250 kHz) blir det
vid 400 RPM - 37500 steg på räknaren.
vid 1200 RPM - 12500 steg.
Det är den mest optimala inställningen för en 16-bitars räknare. Lägsta värdet (vid 1200 rpm) har då en upplösning på 13 bitar, dvs ca 0.01% noggrannhet. Sedan försvinner lite noggrannhet i beräkningarna då sista biten avrundas, så säg ca 12 bitar.
hmmm... jag har gjort en binaldivisionsrutin i assembler för 16-bitars tal.
A/B = C där C är ett binaltal där bit 15 har värdet 1, bit 14 värdet ½, bit 13 värdet 1/4 osv.... dvs binärt 1.111 1111 1111 1111
minvärde är 0 och maxvärde är 2 (eller nästan 2)
du ska få svaret 1200 RPM när du har 16-bitars talet X = 12500.![]()
K / 12500 = 1200
K är en konstant.
Men med "binaldiv" kan du få maxvärde 2. alltså justerar vi:
K / 12500 < 2![]()
K <= 25000
25000/X
X=37500 => K / X = 0.66667 (motsvarar 400 rpm)
X=12500 => K / X = 2.00000 (motsvarar 1200 RPM)
multiplicera svaret med 6 så får du RPM![]()
gör om gör rätt.
Sätt K=18311
K/12500 = 1.46488
1.46488 binalt blir som 16-bitars heltal (x32768) = 48001.
shifta det talet 2 bitar åt höger så får du 12000, dvs varvtalet i RPM x 10.
yes, det stämmereehh... eller
![]()
dags att sova !
Re: Frågor kring Tidmätning (rpm) med AVR
Jag har gjort det här flera gånger. Det är enkelt.
16MHz oscillator
Räkna ut optimal prescaler för 400 varv/minut, 16bit timer.
16000000*60 / (400 * 2^16) = 36
Närmast högre värde är 64.
Exempel:bearing skrev:Varvtalet = antal timertick under 1 minut / capture-värdet.
16MHz oscillator
Räkna ut optimal prescaler för 400 varv/minut, 16bit timer.
16000000*60 / (400 * 2^16) = 36
Närmast högre värde är 64.
Kod: Markera allt
period=ICR1; //Spara capture-värdet
varvtal = (16000000*60/64) / period; //Räkna ut varvtalet.
Re: Frågor kring Tidmätning (rpm) med AVR
Hmm jag hänger inte riktigt med i alla uträkningar.
v-g: du nämner inget under vilka förutsättningar ”frekvenser”?
Jesse: inte 1200rpm utan 12000rpm, om det har någon betydelse..
Men det ser ut som att följande fungerar vid 8Mhz & 64/prescaler.
Konstanten 7500000 dividerat med räknade timer tick = RPM
Då gäller det bara att hitta en kodsnutt som kan dividera ett 24bitars tal med ett 16bitars…
Ingen som har ett på lager?.
v-g: du nämner inget under vilka förutsättningar ”frekvenser”?
Jesse: inte 1200rpm utan 12000rpm, om det har någon betydelse..
Men det ser ut som att följande fungerar vid 8Mhz & 64/prescaler.
Konstanten 7500000 dividerat med räknade timer tick = RPM
Då gäller det bara att hitta en kodsnutt som kan dividera ett 24bitars tal med ett 16bitars…
Ingen som har ett på lager?.
