Diskret tid kompensering

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Diskret tid kompensering

Inlägg av Korken »

Godagens!

Jag har ett programmeringsproblem jag funderat lite på, men är lite osäker på hur jag ska gå vidare med det.
Jag har en kod där man ställer in i vilken repititionshastighet något ska hända i, tex 80 Hz.

Men detta ska konverteras till hur många "system ticks" det är och då får man avrundningsfel över tiden.
Tex säg att systick är 1000 Hz så blir tiden mellan exekveringar 1000 / 80 = 12.5 vilket blir avrundat till 12 ticks. Det är nu istället ca 83.3 Hz.

Det jag vill är kompensera för detta genom att "vid rätt tillfälle" vänta 13 ticks istället för att kompensera för detta så medelfelet över lång tid blir noll.
Hur skulle ni lösa detta? Ända kravet är att man inte får använda flyttal.


Idén jag har är typ såhär (psuedo-kod):

Kod: Markera allt

/* Hitta akumuleringserrorn som blir */
const division_error = systick_frequency % desired_frequency;
.....
/* När man kör */
static accumulation_error = 0;

/* Integrera errorn */
accumulation_error += division_error;

/* Kolla om errorn har blivit nog stor */
if (accumulation_error >= deisred_frequency)
{
  accumulation_error -= desired_frequecy;
  delay(time + 1);
}
else
  delay(time);
Finns det något annat sätt att göra det på?
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Diskret tid kompensering

Inlägg av blueint »

Addera ihop avrundningsfelen och korigera när de uppnåt ett absolut värde på minst ett.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Diskret tid kompensering

Inlägg av mri »

Principen du använder är rätt, men du kan bli kvitt if/else om du vill. Kör med nån variant med fixed point i ackumulatorn, då kan du använda högershift för att få den där extra 1-an till delay() funktionen när det blir spill over till heltalsdelen...
superx
Inlägg: 1127
Blev medlem: 19 juni 2012, 23:28:16
Ort: Linköping

Re: Diskret tid kompensering

Inlägg av superx »

En annan variant är att i förväg skapa en array med fördröjningar som ger rätt medelvärde, t.ex. {12, 13} och sedan i varje steg plocka värden för fördröjningen ur denna array.

Den lösningen blir inte flexibel, men kanske marginellt snabbare i något fall.

Ditt förslag är nog bästa sättet att göra detta!
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Diskret tid kompensering

Inlägg av Korken »

mri:
Jag satt och funderade på det du sa om fixed point, men det kommer bara bli en approximation i slutändan?
Jag tänkte göra detta mycket generiskt så att man den ska inte ha drift eller så, men skulle vara skönt att inte ha if-satser.

superx:
Array principen tror jag skulle kunna bli mer effektiv, dock så kan man inte ha en statisk array för alla fall - den blir dynamisk beroende på vilken "fraction" man får.
Så exekveringsmässigt skulle den nog va snabbare men hårdare på minnet, en avvägning.


Ser något ett vis att göra detta utan fixed point och utan if-satser?
Jag kunde byta ut det mot två extra divisioner, men en division är segare än att evaluera en if-sats i ARM (Cortex-M4).
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Diskret tid kompensering

Inlägg av blueint »

Kanske du kan få lite inspiration från Floyd-Steinberg dithering?
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Diskret tid kompensering

Inlägg av Korken »

Mycket snyggt system!
Det är typ vad jag redan gör dock, man kan se min "utjämning" att bara arbeta i positiv t-led och om man inte tillåter avrundningsfel så kommer man tillbaka till min lösning. :humm:
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4745
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Diskret tid kompensering

Inlägg av Swech »

1000/80 = 12.5
12.5 * 256 = 3200
Ditt börvärde är då 3200
Räkna upp ett word med 256 i varje tick.
Om resultatet >= 3200 så utför din 80Hz rutin och ta även och subtrahera 3200 från
ditt word.

Swech
Skriv svar