Go Down

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

computerjlt

is it possible?

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.

anyway here is my in progress code:

Code: [Select]

const int SnumRead = 8;
const int pot = A0;

volatile unsigned long pulse0[SnumRead];
volatile unsigned long pIndex0 = 0;
volatile unsigned long nowPulse0 = 0;
volatile unsigned long lastPulse0 = 0;
volatile unsigned long i0, sum0, average0 = 0;
float rate0;

volatile unsigned long pulse1[SnumRead];
volatile unsigned long pIndex1 = 0;
volatile unsigned long nowPulse1 = 0;
volatile unsigned long lastPulse1 = 0;
volatile unsigned long i1, sum1, average1 = 0;
float rate1;

volatile unsigned long pulse2[SnumRead];
volatile unsigned long pIndex2 = 0;
volatile unsigned long nowPulse2 = 0;
volatile unsigned long lastPulse2 = 0;
volatile unsigned long i2, sum2, average2 = 0;
float rate2;

volatile unsigned long pulse3[SnumRead];
volatile unsigned long pIndex3 = 0;
volatile unsigned long nowPulse3 = 0;
volatile unsigned long lastPulse3 = 0;
volatile unsigned long i3, sum3, average3 = 0;
float rate3;

float slip;
float threshold;
float overslip;
float overslipscale = 25;


void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  attachInterrupt(0, count0, FALLING);
  attachInterrupt(1, count1, FALLING);
  attachInterrupt(2, count2, FALLING);
  attachInterrupt(3, count3, FALLING );
}

void loop() {
  average0 = 0;
  sum0= 0;
  for (i0 = 0; i0 <= SnumRead; i0++)
  {
    sum0 +=pulse0[i0];
  }
  average0 = sum0 / SnumRead;
  rate0 =  (float)1000000 / average0;
 
 
  average1 = 0;
  sum1= 0;
  for (i1 = 0; i1 <= SnumRead; i1++)
  {
    sum1 +=pulse1[i1];
  }
  average1 = sum1 / SnumRead;
  rate1 =  (float)1000000 / average1;
 
 
 
  average2 = 0;
  sum2= 0;
  for (i2 = 0; i2 <= SnumRead; i2++)
  {
    sum2 +=pulse2[i2];
  }
  average2 = sum2 / SnumRead;
  rate2 =  (float)1000000 / average2;
 
 
  average3 = 0;
  sum3= 0;
  for (i3 = 0; i3 <= SnumRead; i3++)
  {
    sum3 +=pulse3[i3];
  }
  average3 = sum3 / SnumRead;
  rate3 =  (float)1000000 / average3;


  threshold = analogRead(pot);
  threshold = threshold / 48.71;
  slip = max(rate0, rate1) / max(rate2, rate3);
  slip = 100 * (slip - 1);
  overslip = slip - threshold;
  if (overslip < 0)
  {
  overslip = 0;
  }
  else if (overslip > overslipscale)
  {
  overslip = overslipscale;
  }
 
  Serial.println("");
  Serial.print(rate0,2);
  Serial.print(" / ");
  Serial.print(rate1,2);
  Serial.print(" / ");
  Serial.print(rate2,2);
  Serial.print(" / ");
  Serial.print(rate3),2;
  Serial.print(" --- ");
  Serial.print(threshold),2;
  Serial.print(" / ");
  Serial.print(slip),2;
  Serial.print(" / ");
  Serial.print(overslip),2;
 
  if (threshold < 21)
  {
  overslip = map(overslip, 0, overslipscale, 0, 255);
  analogWrite(11, overslip);
  digitalWrite(13, HIGH);
  }
  else
  {
  analogWrite(11, 0);
  digitalWrite(13, LOW);
  }
 
 
  delay(5);
}

void count0()
{
  nowPulse0 = micros();
  pulse0[pIndex0] = nowPulse0 - lastPulse0;
  pIndex0++;
  if (pIndex0 > SnumRead)
    pIndex0 = 0;
  lastPulse0 = nowPulse0;
  }
void count1()
{
  nowPulse1 = micros();
  pulse1[pIndex1] = nowPulse1 - lastPulse1;
  pIndex1++;
  if (pIndex1 > SnumRead)
    pIndex1 = 0;
  lastPulse1 = nowPulse1;
  nowPulse1 = 0;
}
void count2()
{
  nowPulse2 = micros();
  pulse2[pIndex2] = nowPulse2 - lastPulse2;
  pIndex2++;
  if (pIndex2 > SnumRead)
    pIndex2 = 0;
  lastPulse2 = nowPulse2;
  nowPulse2 = 0;
}
void count3()
{
  nowPulse3 = micros();
  pulse3[pIndex3] = nowPulse3 - lastPulse3;
  pIndex3++;
  if (pIndex3 > SnumRead)
    pIndex3 = 0;
  lastPulse3 = nowPulse3;
  nowPulse3 = 0;
}


PaulS

Quote
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.

Graynomad

You can, but reallocating memory is probably not for a beginner. Just allocate space for the largest eventuality and save yourself some heartache.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

dhenry

Quote
is it possible?


Yes.

Quote
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.

PeterH


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.

Go Up