Flytande medelvärde i avr

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Njaa, det tycker jag inte. En storlek (bufferlängd) är ju alltid ett bestämt antal. Att sedan pekaren är 0-baserad har egentligen inte med saken att göra.
Användarvisningsbild
Andax
Inlägg: 4379
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Inlägg av Andax »

Nisse skrev:Kanske skall ändra så att buff_length blir "rätt", dvs börjar på noll. Slipper ju dra bort 1 vid ANDI då* Nää nu skall jag sova.
Den börjar ju redan på noll. Och är en 2-potens lång. Det är just därför metoden med andi XL, buff_length-1 funkar.
XL kommer anta värdena 0, 1 .., 6, 7, 0, 1 .. osv dvs en sekvens av 8 olika addresser.

Metoden spårar ur om bufferten inte startar på 0 eller är en 2-potens lång.
Vid 8 värden lång buffer gör du and med 7 som är 00000111 i binärt, dvs man bibehåller de tre nedersta bitarna och får en räknare om går från 0 till 7 om och om igen.
vid 16 värden gör du and med 15 som är 00001111 i binärt, dvs man har kvar de 4 lägsta bitarna och får en räknare som går från 0 till 15 om och om igen.

osv.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Istället för att använda clc och ror, så använd istället lsr.
Sedan kan du använda timmer2 som räknare istället för intrupt (för att räkna pulserna) vilket minskar risken för fel räkning och avlastar cpu.

Sedan så kommer du få problem om summan blir mer än 255 (8*255 = 2040) vilket inbär att den upplösning du igentligigen har är 5bitar.(felet kommer att följa med hela tiden sedan) Vilket man ganska enkelt kan lösa genom att räkna med 16bitars tal.

exemple på 16bitar tals hantering
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Jag var nog lite oklar när jag skrev det där om buff_length-konstanten. Det jag menade är att jag skall sätta konstanten till 7 istället för 8. Då blir den ju rätt och jag behöver inte heller dra ifrån 1 i följande kodrad: andi XL, buff_length - 1

exile -> Att summan inte får bli mer än 255 har vi redan talat om i tråden och att det inte var något problem.

LSR istället för CLC+ROR är ju bra... Hmm, varför missade jag den instruktionen?
Att använda timer2 till att räkna pulserna är ju ingen dum idé. Räknar den externa pulser även när programmet är i en interupt? Gör den det så är det ju en suverän lösning. (tar fram databladet ikväll).

Mvh
Nils
Användarvisningsbild
Andax
Inlägg: 4379
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Inlägg av Andax »

Du har nog missuppfattat något... Buffer length ÄR 8. När XL går från 0 till 7 besöker den 8 addresser i buffern.

Att du drar ifrån 1 spelar ingen roll på exekveringstiden av ditt program. När ditt program assembleras görs beräkningen buff_length-1 då och inte av avr processorn.

Du kan ju alltid byta namn på din buff_length till buff_addr_mask och sätta den till 7 så återspeglar den kanske mer vad den används till.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Sorry, såg inte att ni redan hade diskutera det... (även om jag tycker att det är lite slöhet att inte räkna med 16bitars tal)

Ja, Den räknar även när interupt inträffar.. ^^
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Varför är det slöhet när man inte behöver det? Kommer som mest få en summa på 160. Varför använda 16-bitar då?

Kanon att räknaren räknar även under interupt. Då blir det till att bygga om koden igen.

Andax -> Visste att den beräkningen görs vid assembleringen. Och jag vet att buffern består av åtta värden. Det är ju därför jag delar med åtta med hjälp av tre bitshift. Dock har du en poäng med namnet på konstanten, bättre ändra där.

Nu har jag dock börjat fundera på möjligheten att ha varierande storlek på bufferten. Alltså kunna minska trögheten när pulstalen är högre. Hmmm, får fundera närmare på om den funktionen behövs.

Mvh
Nils
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Nu har jag dock börjat fundera på möjligheten att ha varierande storlek på bufferten.

Eftersom det är rellativt enkelt, så skulle jag implementera ett par olika
bufferts, säg med 4, 8, 16 och 32 positioner (eller något annat liknande/passande).

I princip är det bara att kopiera dina definitioner av start/stop adresser och
skapa ett par "sum" och "avg" till. Samt komplettera koden med en snutt till
för de tre andra bufferterna.

Notera bara att det kan vara svårt att hitta minnesposition som ligger på
en jämt 256 byte gräns (så att XL startar på 0) för alla bufferts. Alltså
måste hanteringen av återställningen av pekaren skötas lite annorlunda.

Man kan naturligtsvis även göra detsamma med *en* 32-pos buffert, men med
lite extra pekare för att hålla reda på de 4, 8 och 16 senaste värderna. Dock
räcker det då inte med en pekare utan det måste vara två som snurrar runt
i bufferten...

Igentligen är jag inte speciellt förtjust i lösningen som den blev nu, eftersom
det hela bygger på att bufferten ligger på en speciell plats i minnet. Om jag hade
skrivit något liknande (för PIC i och för sig), så hade jag gjort det mer generellt
och låtit länkaren välja *var* bufferten (eller bufferterna) skulle
placeras i minnet. På så sätt är de aldrig "i vägen" utan länkaren flyttar
runt buffertar mellan asembleringarna från fall till fall.

Och självklart ska man inte köra 16-bitars tal *i onödan*. D.v.s om applikationen
*per design* inte behöver det. Bara man vet vad man håller på med... :-)
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Sodjan -> Måste läsa på lite mer hur man hanterar SRAMet i assemblatorn så att länkaren kan välja adresser själv. Vet helt enkelt inte hur man skriver koden (ännu).

Idén med separata bufferts kommer nog inte bli helt bra. Skall jag överhuvudtaget använda idén med olika storlek på bufferten så måste det gå att byta "on the fly" utan att medelvärdet blir galet. Så om den buffert man byter till innehåller bara nollor eller bara höga värden är det kört. Istället skulle bufferten behöva utökas respektive minskas med ett värde i taget tills önskad storlek uppnåts. Men det ställer till andra problem som att buffertens längd inte alltid är en potens av två. Vilket i sin tur kräver en divisionsfunktion. Nja, det får komma i framtida revisioner, kan vara läge att försöka få ihop något fungerande först.

Mvh
Nils
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Notera att det jag skrev gäller PIC assembler.
Jag har inte en aning om AVR assembler stödjer programmering
med relokerbar kod, eller om AVR har en länkare till assembler
med automatisk allokering av RAM...

Men hur som helst, det är inte avgörande på något sätt...

Min tanke var alltså att man hela tiden håller (t.ex) 4 buffertar
aktuella, så att du visst kan byta on-the-fly och alltid ha aktuella
värden. Så alla 4 (i detta exempel) medelvärdar är hela tiden aktuella.
"Bytet" av medelvärde behöver inte ske förrens vid presentationen
på PC'n. Eller också lägger du ut alla 4 kurvorna i samma diagram.

> Vilket i sin tur kräver en divisionsfunktion...

Om alla värden *alltid* ska över till en PC för vidare bearbetning,
så kan du lägga divisionen där. För bara över buffert-summan (vilken
ju är enkal att beräkna även med "udda" längder"...).
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Nu kommer denna vecka tyvärr till stor del vara vikt till annat. Men som sagt, jag skall läsa på lite vad det gäller själva assemblatorns funktioner i AVR-studio framöver.

Aha, hålla alla bufferterna uppdaterde hela tiden, smart. Så långt tänkte ju inte jag.

Överföring till PC för presentation kommer enbart vara en rent diagnostisk funktion. Som jag skrev någonstans tidigare, när vi talade om hur mycket processortid det bränner, så kommer utmatningen som seriedata förmodligen styras att bara vara på när det behövs. En jumper i hårdvaran som styr en ingång.

Mvh
Nils
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK, det stämmer att du skrev det...
Så "apparaten" har en egen predentation ?
Tja, du kanske har skrivit det också tidigare... :-)
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Apparaten kommer inte ha någon egen presentation heller. Enda sätter den kommer meddela sig med omvärlden (förrutom diagnostiskt via RS232) är med ett relä.

Mvh
Nils
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Nisse skrev:Varför är det slöhet när man inte behöver det? Kommer som mest få en summa på 160. Varför använda 16-bitar då?
Så länge du inte kan garantera ( delvis exempel vis kollar att det inte är störe än 31 för varje "samplad" värde) så finns det risk att det kan bli fel, även om givaren ska ge betydligt mindre pulser...
Användarvisningsbild
Nisse
Inlägg: 908
Blev medlem: 9 juli 2006, 23:25:46
Ort: Kumla

Inlägg av Nisse »

Vad skall jag då göra om jag inte kan garantera att det inte blir fler pulser än vad 16-bitars klarar av då? :)

Planer finns faktiskt på att göra som du skriver, att kontrollera varje "sample" och varna om det blir för mycket. Istället för att skicka pulstalen via serieporten skickas ett varningsmeddelande av något slag.

Grejen är att apparaten behöver inte fungera om pulserna blir för många. Får man för höga värden så har strålkällan för stor aktivitet. Det felet löser man inte i mjukvara tyvärr. Anlednignen till att man inte vill ha högre pulstal är för att ge röret maximal livslängd. Av samma anledning kör man också röret på ungefär halva arbetsspänningen.

Mvh
Nisse
Skriv svar