Measure of speed, a beginer needs (more) help

In continuation of my previous 2 posts, I still am stuck on some few things without any idea how to solve them.

I would like to measure the speed and jerk of a rotating cylinder. I am using a optical sensor.
I need to have the speed measures in a table in order to calculate the 2nd derivative i.e. jerk but I'm unable to do so.

Here's the program :

#define SO 18 //Optical sensor
#define HT 19 // Clock

float vitesse = 0.0 ; //speed in french


volatile unsigned long T1;
volatile unsigned long T2;
unsigned long T2_c;
unsigned long T1_c;
unsigned long dT_op;

volatile byte b=0;
int b_c=0;

int NbMesures = 9;
float Vitesse[9];
int MesIndex=0;
long total=0;

float Temps[9]; //Temps is time in french
float Jerk_tab[9];

int i;
int j;
long DT;


void setup() {
  Serial.begin(9600);
  
  pinMode(HT, INPUT);
  attachInterrupt(digitalPinToInterrupt(HT), Clock, RISING);
  pinMode(SO, INPUT);
  attachInterrupt(digitalPinToInterrupt(SO), readSO, RISING);
  pinMode(motor,OUTPUT);

}


void  Clock(){
  b = b+1;
}

void readSO(){
  T1=T2;
  T2=micros();

}

void loop() {
  noInterrupts();
  T2_c = T2;
  T1_c = T1;
  b_c = b;
  interrupts();
  dT_op = T2_c-T1_c;
  vitesse = (1e6)/ (16*dT_op);

  Vitesse[MesIndex] = vitesse;
  Temps[MesIndex] = T2_c;
 
  
  if (MesIndex==0){
    i = 9;
    j = 8;
  }
  else if (MesIndex==1){
    i=0;
    j=9;
  }
  else{
    i = MesIndex-1;
    j = MesIndex-2;
  }
  
  //2nd derivative i.e. Jerk :
  DT = Temps[MesIndex] - Temps[i];
  Jerk_tab[MesIndex] = (Vitesse[j] - 2*Vitesse[i] + Vitesse[MesIndex])*1e12 / (DT*DT);

 
  if (b_c>2){
    Serial.print(" vitesse : ");
    Serial.print(Vitesse[MesIndex]);
    Serial.print(",");
    Serial.print(" Temps : ");
    Serial.print(Temps[MesIndex]);
    Serial.print(",");
    Serial.print(" jerk : ");
    Serial.print(Jerk_tab[MesIndex]);
    Serial.print(",");
    Serial.print(" DT : ");
    Serial.print(DT);
    Serial.print(" MesIndex : ");
    Serial.print(MesIndex);
    Serial.println();
    noInterrupts();
    b=0;
    interrupts();
    b_c=0;
  }
  
  MesIndex = MesIndex+1;
  if (MesIndex>9){
    MesIndex=0;
  }
  
}

Here's the assembly, the wiring is not the one I'm using it was for another issue..

image


White is the optical sensor, blue and black ground of generator and optical sensor, red is 5V of optical sensor and green is the 10Hz signal recieved by generator.
image

Here's what's printed :

The moment I start rotating the cylinder, the printing stops...
I don't understand a thing

If any of you guys have any idea, i would love to hear it!

So continue those posts. Do not start a new one.

Please ask a moderator to merge this with another.

Mesindex can reach nine, which means that you're writing off the end of your arrays.

The calc for vitesse has potential for a division by zero. I assume that you're getting away with it though and that's where the inf comes from.

In the rest of the world, that is know as acceleration!
Is your time interval fixed or variable? To measure speed it need to be a fixed, known value.
Do you know how to use an array of values? How many values do you need? Does your Arduino have enough spare memory for the array?

Jerk is the third derivative.

The 2nd derivative of speed is jerk
The 3rd of position is jerk
right?
I meant the 2nd derivative relative the speed.

I meant 2nd derivative of speed, the 3rd of position

OK thx

Maybe not... I'd like to have a table/array of 10 values from which I can calculate the jerk in a table as well to then send it to python (via putty) to trace its graphs
I'm using and arduino mega so i believe it does, doesn't it?

Could saving 3 values of the speed to calculate the jerk and not use an array/table be a better idea?

You could, if you know the three values contain the acceleration you are looking for. Remember! For every + acceleration there will be a corresponding - acceleration. So likely you will need many more speed values than three.

I don't think we understood each other.
My idea is :
speed1=0
speed2=0
speed3=0
measure the speed then
speed1=speed2
speed2=speed3
speed3=speed
etc...

and then, because to calculate the 2nd derivative of speed : jerk you only need 3 values of speed you can calculate it...

But then the issue is that jerk is even more sensible to acceleration to small changes in speed, cause it's the 2nd derivative, it would be unintelligible. Therefore, i wanted to do the moving average of the speed prior to calculate the jerk, but then i need more than 3 values to do so...

Good luck, then. Have fun with the Arduino.

Ok i'm just dumb with my MesIndex... I just had to have each array be of lenght 10..

Now at least I get my speed and time but when I calculate my jerk the problem remains.

DT = 1e-3;
Jerk_tab[MesIndex] = (Vitesse[j] - 2*Vitesse[i] + Vitesse[MesIndex]) / (DT*DT);

but it seems it's overflowing :

Print the components of the calc beforehand.

Yep there's seem to be an issue :


I don't understand why the speed doesn't change with the index...

Here's the code, some few modifications made for the arrays to function as I want to :

#define SO 18 //Optical sensor
#define HT 19 // Clock

float vitesse = 0.0 ; //speed in french

volatile unsigned long T1;
volatile unsigned long T2;
unsigned long T2_c;
unsigned long T1_c;
unsigned long dT_op;

volatile byte b=0;
int b_c=0;

volatile float target;

int NbMesures = 9;
float Vitesse[10];
int MesIndex=0;
long total=0;

float Temps[10];
long Jerk_tab[10];

int i;
int j;
unsigned long DT;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  pinMode(HT, INPUT);
  attachInterrupt(digitalPinToInterrupt(HT), Clock, RISING);
  pinMode(SO, INPUT);
  attachInterrupt(digitalPinToInterrupt(SO), readSO, RISING);

}


void  Clock(){
  b = b+1;
}

void readSO(){
  T1=T2;
  T2=micros();

}

void loop() {
  // put your main code here, to run repeatedly:
  noInterrupts();
  T2_c = T2;
  T1_c = T1;
  b_c = b;
  interrupts();
  dT_op = T2_c-T1_c;
  vitesse = (1e6)/ (16*dT_op);

  Vitesse[MesIndex] = vitesse;
  Temps[MesIndex] = T2_c;
 
  
  if (MesIndex==0){
    i = 9;
    j = 8;
  }
  else if (MesIndex==1){
    i=0;
    j=9;
  }
  else{
    i = MesIndex-1;
    j = MesIndex-2;
  }
  
  //Dérivée seconde i.e. Jerk :
  DT = 1e-3;
  Jerk_tab[MesIndex] = (Vitesse[j] - 2*Vitesse[i] + Vitesse[MesIndex]) / (DT*DT);

 
  //Print de vitesse
  if (b_c>2){
    //Serial.print(pwr);
    Serial.print(" vitesse_ind : ");
    Serial.print(Vitesse[MesIndex]);
    Serial.print(",");
    Serial.print(" vitesse_ind-1 : ");
    Serial.print(Vitesse[i]);
    Serial.print(",");
    Serial.print(" vitesse_ind-2 : ");
    Serial.print(Vitesse[j]);
//    Serial.print(" Temps : ");
//    Serial.print(Temps[MesIndex]);
    Serial.print(",");
//    Serial.print(" jerk : ");
//    Serial.print(Jerk_tab[MesIndex]);
//    Serial.print(",");
//    Serial.print(" DT : ");
//    Serial.print(DT);
    Serial.print(" Index (MesIndex,i,j) : ");
    Serial.print(MesIndex);
    Serial.print(",");
    Serial.print(i);
    Serial.print(",");
    Serial.print(j);
    Serial.println();
    noInterrupts();
    b=0;
    interrupts();
    b_c=0;
  }
  
  MesIndex = MesIndex+1;
  if (MesIndex>9){
    MesIndex=0;
  }
}

That's very confusing... I mean I got it but it doesn't surprise me other's didn't.

Are you intending to use finite differences to measure discrete equivalents of these derivatives? If so you have take care of the issue you are not sampling at a constant rate.
Or are you intending to curve-fit a polynomial to the datapoints?

The latter might be easier done on a host computer.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.