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!
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!