Time measurement issue when using SPI protocol

Hi, I'm trying to use potentiometer to measure angle and differentiate it to angular velocity. I can easily do it by using micros to measure time at each point but the result is look strange when I'm using SPI communication in the same file. How does the large value occur? and How can I solve this?

Thanks for your attention,
Title

Haven't you forgotten something?

I'm not sure. This is my code if you want to see. Many lines are not related to this issue but it is in my project.

#include <SPI.h>
SPISettings settingsA(16000000, MSBFIRST, SPI_MODE0);  // At 16 = SPI Clock = 8MHz.

int RCLKPin  = 53;   // pin 12 on the 74hc595 latch - nSS
int SRCLKPin = 52;  // pin 11 on the 74hc595 shift register clock - SCK
int SERPin   = 51;    //  MOSI
int POT = A4; // Potentionmeter
float theta = 0, previous_theta = 0, theta_filter = 0, previous_theta_filter = 0;
float vel = 0, previous_vel = 0,  acc = 0, theta_d = 30.0 * PI / 180.0, min_theta = 212.32;
unsigned long Time = 0, previous_Time = 0;
float M, N, e, edot, dt, a;
float A = 3e-3, r = 0.075, g = 9.81;
float H = 1.65, m = 65, ms = 0.0465 * m, mf = 0.0145 * m, ls = 0.246 * H, zs = 0.433 * ls, lf = 00.152 * H, zf = 0.5 * lf;
float Ix = 0.126, Is = ms * (0.528 * ls) * (0.528 * ls) , If = mf * ls * ls;
int Kd = 4, Kp = 4, k = 4000, P_d;
float m2 = 0.107, m5 = 0.277, m7 = 0.584, m8 = 0.263;
float z2 = 0.13,  z5 = 0.386, z7 = 0.192, z8 = 0.46;
float xn1 = 0;
float yn1 = 0;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  pinMode(RCLKPin,  OUTPUT);
  pinMode(SRCLKPin, OUTPUT);
  pinMode(SERPin,   OUTPUT);
  pinMode(POT, INPUT);
  SPI.begin();
  noInterrupts();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  theta = analogRead(POT);
  theta_filter = 0.969 * previous_theta_filter + 0.0155 * theta + 0.0155 * previous_theta;
  Time = micros();
  dt = Time - previous_Time;
  Serial.println(dt);

  vel = (theta_filter - previous_theta_filter) / dt * 10e6;
  //  P_d = Cal_Pressure_d(false);

  //  Serial.println(theta_filter);
  //  Serial.print(",");
  //  Serial.println(vel);

  //  a = (P_d - 1.0) / 99.0 * 4095.0;
  //  if (a > 4095.0) a = 4095.0;
  //  writeMCP4922_AB( 0, a );
  previous_theta = theta;
  previous_theta_filter = theta_filter;
  previous_vel = vel;
  previous_Time = Time;
  //  delay(1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 0 - A, 1 - B

void writeMCP4922_AB(byte AB, uint16_t v) {

  v |= 0xf000;            // B15(A/B)=1 B, B14(BUF)=1 on, B13(GAn) 1=x1  B12(SHDNn) 1=off
  if (!AB)  v &= ~0x8000; // When zero clear B15 for A.

  SPI.beginTransaction(settingsA);
  digitalWrite(RCLKPin, LOW);
  SPI.transfer( (0xff00 & v) >> 8 );
  SPI.transfer(      0x00ff & v );
  digitalWrite(RCLKPin, HIGH);
  SPI.endTransaction;
}


int Cal_Pressure_d(bool include_leg) {
  float thetadot_d = 0, theta2dot_d = 0, thetadot = vel;
  M = (Is + If + Ix) / (A * r);
  if (include_leg) {
    N = (ms * g * zs * sin(theta) + mf * g * (ls * sin(theta) + zf * cos(theta)) + (m2 * z2 + m5 * z5 + m7 * z7) * g * sin(theta) + m8 * g * z8 * sin(theta + 0.124)
         + k * theta * r * r) / (A * r);
  }
  else {
    N = ((m2 * z2 + m5 * z5 + m7 * z7) * g * sin(theta) + m8 * g * z8 * sin(theta + 0.124) + k * theta * r * r) / (A * r);
  }
  e = theta_d - theta;
  edot = thetadot_d - thetadot;
  return M * (theta2dot_d + Kd * edot + Kp * e) + N;
}


float filter(float x, int d) {
  //  if ()
  return x;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

How do you measure and calculate the time difference?
(code example)
Is it in micro-seconds or milli-seconds?

I suggest to think about if the time value, e.g. a tick value, rolls-over.
You get a value for start which is almost before a roll-over. After the call the end time is after it has rolled over. If you substract now as end minus start - it is too large (a small value minus a large value gives you a negative value but taken as unsigned it will be a large value).

Which Arduino are you using?
Which pot are you using?
How have you wired it up?

How big is the angular velocity are you expecting to measure?

Including timer interrupts?

I use micro-seconds as above code and you're right. The large number actually is negative number but I use unsigned long. However, I found that negative number occur because 'nointerrupt' according to [TheMemberFormerlyKnownAsAWOL] reply.

You're completely collect. This is the problem line and after remove this line, time difference looks good.

Thanks for your attention. I removed 'nointerrupt' line and every thing look good.

if ( abs( value ) < some_giant_unreasonable_number) )
  {
  // Only process legit looking data 
  }

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