Topic: dynamic array? or varrying the size of the array based on something? (Read 2064 times)previous topic - next topic

My project measures wheel speed by measuring time between interrupts. At low speed (<20hz) its fairly accurate and i can use a small array of 1 or 2 readings for fast response; but at 800hz and up i need a bigger array (8-10) to smooth out the readings.

is it possible to have an array that changes size dynamically? if i tru declaring the array as anything but constant i get errors.

right now the ISR changes the position of itself in the array and i want to keep that code small so i dont possibly miss any other interupts.

right now the ISR changes the position of itself in the array and i want to keep that code small so i dont possibly miss any other interupts.

No, it doesn't. The ISR is a function. It is not an array element, so it can't move itself in the array.

There are ways to dynamically define arrays. You are advised not to use them. The Arduino (328-based, anyway) has little memory. Fragmenting that doing dynamic memory allocation is not advised. Clearly, you are not using a 328 based Arduino, since it does not have 4 interrupt pins. Still, small, static arrays are best.

My project measures wheel speed by measuring time between interrupts. At low speed (<20hz) its fairly accurate and i can use a small array of 1 or 2 readings for fast response; but at 800hz and up i need a bigger array (8-10) to smooth out the readings.

You do not need such (large) arrays to measure wheel speed. Maybe you want to rethink your approach instead.

Just allocate space for the largest eventuality and save yourself some heartache.

Sounds like the best idea to me. I guess you are using the array as a FIFO buffer to work out a rolling average. In that case you would presumably be using it as a circular buffer. You can change the capacity of a circular buffer very easily, just by subtracting a value from the capacity calculation to prevent the buffer from filling beyond a threshold. If it's really just being used as an array then of course you can change the effective size even more easily, just pretend the array is the size you need and ignore any excess elements.

A less precise but much easier approach would be to calculate a decaying average, in which case you don't need to remember historical results at all.

I only provide help via the forum - please do not contact me for private consultancy.

right now the ISR changes the position of itself in the array and i want to keep that code small so i dont possibly miss any other interupts.

No, it doesn't. The ISR is a function. It is not an array element, so it can't move itself in the array.

There are ways to dynamically define arrays. You are advised not to use them. The Arduino (328-based, anyway) has little memory. Fragmenting that doing dynamic memory allocation is not advised. Clearly, you are not using a 328 based Arduino, since it does not have 4 interrupt pins. Still, small, static arrays are best.

My project measures wheel speed by measuring time between interrupts. At low speed (<20hz) its fairly accurate and i can use a small array of 1 or 2 readings for fast response; but at 800hz and up i need a bigger array (8-10) to smooth out the readings.

You do not need such (large) arrays to measure wheel speed. Maybe you want to rethink your approach instead.

care to elaborate on this? i need fairly high resolution (measure slip in 1/10 of a percent) so i'm measruring time between pulses. the way i have it setup works great but at high speed the small size of the array leads to some big jumps; upping the size makes it happier.

/edit: my first attempt was just counting pulses but at low speed the reaction was way too slow; i need to update the output based on slip at least every 10ms (100hz). even at 20hz there wasn't enough pulses to have enough resolution to have useful data. this timing of pullses works much better.

i think i have an idea though; leave the array with 8 spaces but at low speed only use the first 2 then at higher speed maybe 4 then highest speed use all 8. i'll have to try it but i think it'll work better than trying to reallocate memory

Two techniques are described near the start of that thread. Counting (getting the frequency directly) and measuring the period and inverting it. One is better for low frequencies and one is better for high frequencies.

Please post technical questions on the forum, not by personal message. Thanks!

populating the various slots in the array. if i change the sample size it makes a difference.

Two totally different things.

Quote

eave the array with 8 spaces but at low speed only use the first 2 then at higher speed maybe 4 then highest speed use all 8. i'll have to try it but i think it'll work better than trying to reallocate memory

Two techniques are described near the start of that thread. Counting (getting the frequency directly) and measuring the period and inverting it. One is better for low frequencies and one is better for high frequencies.

the frequencies i'm dealing with are much slower; from about 10hz-2000hz so i'd have to have a huge window for it to count in which would make the response of the output unuseable. the method i have works and with enough smoothing seems to work well.

i played with the variable sized index for a 8 space array and got it to work but i think my math is broke somewhere. i'll have to spend more time on it.

populating the various slots in the array. if i change the sample size it makes a difference.

Two totally different things.

Quote

eave the array with 8 spaces but at low speed only use the first 2 then at higher speed maybe 4 then highest speed use all 8. i'll have to try it but i think it'll work better than trying to reallocate memory

Sounds like a better plan.

_____Rob

i meant the latter; the isr changes the index position for the array or resets it to 0 if +1 is too many

anyone have any bright ideas why my math isn't working? if i go over 30hz the rate0 jumps. i know its adding another value in there but if i fix the math in the loop (SnumRread + 1) then its wrong if i go under 30hz.....

i still dont think its quite right; SnumRead is set to 5; which is 6 spots in an array.

for that bit of code in the loop i should have a sample size of 6 samples but then to figure the avage its dividing by SnumRead which is set to 5. but the frequency is right (output matches my function gen)?

for (i1 = 0; i1 <= (SnumRead + 1); i1++)Why does this loop loop a different number of times?

You really need to start using arrays and functions. Nothing about those 4 blocks of code (expect the bizarre discrepancy in the number of times each loops) is different, except which array is read from. There is, for instance, absolutely no reason to use four different loop index variables or 4 different accumulators.

Casting 1000000 to a float may not be achieving the result you expect. Using 1000000.0 instead would eliminate the need for the cast. Also, the compiler knows that a literal with a decimal place in it is not an int. Without that decimal point, it assumes that the value IS an int (which it isn't). What happens when that value is cast to a float is anyone's guess.

I wouldn't write code that requires guessing. Your mileage may vary.

Your ISRs are theoretically all firing at different times. Yet, SnumRead is the same for all 4 situations. Why?