High-speed break-beam velocity flatlining on Teensy

sophiemor

New member
Hello everyone,

I am using a Teensy to measure high-speed projectile velocity with two break beams. At lower speeds, the calculations work perfectly. However, at higher speeds, the calculated velocity flatlines and returns identical values.

I have confirmed that my hardware interrupts are capturing timestamps using micros(), and I found the live formula doing the math. I need help upgrading this system to a higher resolution to prevent the flatlining.

Here are my variable declarations:
volatile unsigned long breakBeam1Count = 0; // Volatile variable to store the time for break beam 1 when it triggers in the external interrupt
volatile unsigned long breakBeam2Count = 0; // Volatile variable to store the time for break beam 2 when it triggers in the external interrupt
unsigned int acquireImpactSpeedFlag = 0; // Flag for indicating that we are acquiring vertical impact speed
unsigned int impactSpeedType = 0; // Int variable for indicating vertical or horizontal type
unsigned int calculateSpeedFlag = 0; // Flag for indicating to the main loop that a speed calculation needs to be done
float verticalSpeed = 0.00;
float horizontalSpeed = 0.00;
float verticalSensorCorrection = 1.00; // Correction factor for computing speed
float horizontalSensorCorrection = 1.00; // Correction factor for computing speed

Here is how my physical pins are linked to the interrupts in my setup code:
// Enable the external interrupts to trigger on a rising edge
attachInterrupt(EXT_INT_0, breakBeam1Trigger, RISING);
attachInterrupt(EXT_INT_1, breakBeam2Trigger, RISING);

Here are the trigger functions that run when those interrupts fire:
void breakBeam1Trigger()
{
if (acquireImpactSpeedFlag == 1)
{
breakBeam1Count = micros();
}
}

And here is the live calculation loop that calculates the speed and updates my EEPROM counters:
// Calculate speed as a float, multiplied by 100 and stored as an unsigned int then return speed value through serial
if (impactSpeedType == VERTICAL)
{
if (breakBeam2Count - breakBeam1Count > 0)
{
verticalSpeed = (SENSOR_DISTANCE_UM / (breakBeam2Count - breakBeam1Count))*verticalSensorCorrection*SPEED_PACKET_MULTIPLICATION;

// Increament the number of vertical impacts made by 1
increamentCountImpacts = readIntValueFromAddressEEPROM(vertImpactCountCurrentAddressStartEEPROM);
writeIntValueToAddressEEPROM(vertImpactCountCurrentAddressStartEEPROM, increamentCountImpacts+1);
}
Serial.println(F("Speed is (m/s): "));
}

How can I switch my hardware interrupts and variables over to a higher-resolution clock to achieve the sub-microsecond precision needed for faster velocities? Which variables need to change data types to support it?

Thank you!
 
You could try using the cycle count register ARM_DWT_CYCCNT instead of micros(), but you would do better to do input capture with one of the timers. With input capture, the rising edge triggers the timer to save its counter value, so you get an exact measurement. If both of your signals were going into two channels of the same timer, you could get a measurement with a 150-MHz timer instead of your 1-MHz micros().

Please show your code.
 
Back
Top