How to perform calculations with data from micros()?

The omission is that started should be set to true inside each of these ISR, not inside loop.

void s3Det() {
  s3Time = micros();
  if ( !started ) startTime = s3Time;
  pinState3 = true;
  started = true;

Same for s1Det() and s2Det(). This starts the timer to track the timeout at the first detection.

I see. I was tempted to do that but I remember reading that keeping ISR's at a minimum was important and was not sure how much time would be left on the timer if I added it.

I couldn't isolate the problem causing the machDistance() function to not calculate the distances. Also, I noticed that the NoDetect() function gets triggered often during debug testing. Perhaps this is because of the noInterrupts/interrupts issue but as it sits right now the "pared down" code is unusable.

And only you know what the "pared down" code is. Nobody can help if you don't share.

I was referring to the nicely streamlined code that you posted. I tried to isolate why it's not fully functional but was unsuccessful. What code does work is already what I posted. If your hinting that I should repost it with the changes that you suggested, then I will do that when I get back to my computer.

That doesn't look anything like the code I posted - much more like the original.

Anyway, if you want to disable interrupts on the Cortex M4
#define noInterrupts __disable_irq #define interrupts __enable_irq

Then noInterrupts() and interrupts() will work. Or just use the functions directly.

Thanks' for that #define statement. Yeah, I'm confused. Let's just move on.

I was finally able to isolate and correct the issue with the code that was graciously provided by @blh64. The problem was with the getTemperature function. It was taking about 45 seconds to register the temperature from the void loop. So, the calculations were wrong or showed zeros during testing. I didn't catch it for a while because each time I tested and saw zeros, I quickly moved on to the next troubleshooting point. I realized the situation after returning from a break when I noticed that some background noise had triggered the sensors and showed that the calculations were working. So, I suspected a delay was the culprit and worked out the problem from there. In my original code I placed the function where it would get the temperature before the sensors could be tripped. This is where it needed to be, so I moved it to the resetSensors function where it works perfectly. :slightly_smiling_face:

So here is the full modified code.

// Take advantage of Apollo3 feature
#include "BurstMode.h"

// Use Temperature Sensor.
#include "SimpleDHT.h"

// Enable Cortex M4 interrupt functions
#define noInterrupts __disable_irq
#define interrupts __enable_irq

// Detection Order Vars
const int sensor1_ID = 1; // Var to hold 1st detection Mic number
const int sensor2_ID = 2; // Var to hold 2nd detection Mic number
const int sensor3_ID = 3; // Var to hold 3rd detection Mic number

// Catchall Timing Vars
unsigned long event_Time1;
unsigned long event_Time2;
unsigned long event_Time3;

// Mach Travel Vars
double Mach_Dist_1 = 0.000000;
double Mach_Dist_2 = 0.000000;
int sensorId_1;
int sensorId_2;

// Hardware Interrupt Times
volatile unsigned long s1Time = 0;
volatile unsigned long s2Time = 0;
volatile unsigned long s3Time = 0;
volatile unsigned long startTime;

const unsigned long timeoutPeriod = 250;  // microseconds

// Pin State Variables
volatile bool pinState1 = false;
volatile bool pinState2 = false;
volatile bool pinState3 = false;
volatile bool started = false;

// Mach Variable
double machSpeed = 0.0; // Var to hold calculated speed of sound value

// Temperature Sensor Variables.
const int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);
byte temp1;

//============================ Initialize =============================

void setup() {

  // Pin Interrupts
  pinMode(2, INPUT); // MIC-1
  pinMode(3, INPUT); // MIC-2
  pinMode(4, INPUT); // MIC-3
  pinMode(5, INPUT); // Temp Sensor
  attachInterrupt(2, s1Det, RISING); // Detection Interrupt
  attachInterrupt(3, s2Det, RISING); // Detection Interrupt
  attachInterrupt(4, s3Det, RISING); // Detection Interrupt

  // Enable Serial Comms.
  Serial.begin(115200);

  // Speed it up to 96 Mhz!
  enableBurstMode();

  // Reset used variables
  resetSensors();
}

//============================ ISR Functions ============================

void s1Det() {
  s1Time = micros();
  if ( !started ) startTime = s1Time;
  pinState1 = true;
  started = true;
}

void s2Det() {
  s2Time = micros();
  if ( !started ) startTime = s2Time;
  pinState2 = true;
  started = true;
}

void s3Det() {
  s3Time = micros();
  if ( !started ) startTime = s3Time;
  pinState3 = true;
  started = true;
}

//=========================== Catchall Loop ==============================

void loop() {

  // if no sound detected, nothing to do
  if ( !started ) {
    return;
  }

  // check for timeout
  unsigned long startTimeCopy;
  noInterrupts();
  startTimeCopy = startTime;
  interrupts();

  if ( micros() - startTimeCopy > timeoutPeriod ) {
    NoDetect();
    resetSensors();
    return;
  }

  // check for all sensors tripped
  if (!pinState1 || !pinState2 || !pinState3) {
    // not all sensors tripped so wait
    return;
  }

  // all sensors are tripped, grab the times

  noInterrupts();
  event_Time1 = s1Time;
  event_Time2 = s2Time;
  event_Time3 = s3Time;
  interrupts();

  // do the calculations

  // getTemperature();  // doesn't work properly in void loop() there is a delay of about 45 seconds to report temperature.
  machCalc();           // recalculate speed based on temperature
  colinearArray();      // calculate distances
  DEBUG();              // display it all
  resetSensors();       // start again
}


//=========================== Auxillary Functions ============================

void resetSensors() {
  noInterrupts();
  pinState1 = false;
  pinState2 = false;
  pinState3 = false;
  started = false;
  interrupts();
  getTemperature();   // Needed to have temperature checked before the sensors are tripped. Relocated function to here from void loop. It works! 
  Serial.println("Sensors Ready:"); // show we are ready for detection
  Serial.println("");
}

void machCalc() {
  machSpeed = (331.3 + (.606 * temp1));
}

void NoDetect()
{
  Serial.println("===========================  SONIC ARRAY ERROR  ==============================");
  Serial.println("=     One or more sensors of the array failed to detect the sonic event      =");
  Serial.println("");
}

//============ Calculate mach travel for a colinear sensor array =============

void colinearArray() {

  // Clear Variables
  sensorId_1 = 0;
  sensorId_2 = 0;
  Mach_Dist_1 = 0;
  Mach_Dist_2 = 0;

  // Convert microseconds to seconds then to distance
  double convMS = 1000000.0 * (machSpeed * 0.0254);

  // Determine which sensor was triggered first (TOA) then calculate TDOA of the other two sensors.
  if (event_Time1 < event_Time2) {
    Mach_Dist_1 = (event_Time2 - event_Time1) / convMS;
    sensorId_1 = 2;
    Mach_Dist_2 = (event_Time3 - event_Time1) / convMS;
    sensorId_2 = 3;
  }

  if ((event_Time2 < event_Time1) && (event_Time2 < event_Time3)) {
    if (event_Time1 < event_Time3) {
      Mach_Dist_1 = (event_Time1 - event_Time2) / convMS;
      sensorId_1 = 1;
      Mach_Dist_2 = (event_Time3 - event_Time2) / convMS;
      sensorId_2 = 3;
    }
    else if (event_Time1 > event_Time3) {
      Mach_Dist_1 = (event_Time3 - event_Time2) / convMS;
      sensorId_1 = 3;
      Mach_Dist_2 = (event_Time1 - event_Time2) / convMS;
      sensorId_2 = 1;
    }
  }

  if (event_Time3 < event_Time2) {
    Mach_Dist_1 = (event_Time2 - event_Time3) / convMS;
    sensorId_1 = 2;
    Mach_Dist_2 = (event_Time1 - event_Time3) / convMS;
    sensorId_2 = 1;
  }
}

//============== Calculate mach travel for a delta sensor array ==============

void deltaArray() { ::::TODO:::: create selection function for sensor Array type in use

  double convMS = 1000000.0 * (machSpeed * 0.0254); // conversion to inches

  // Determine which sensor was triggered first (TOA) then calculate TDOA of the other two sensors.
  if (event_Time1 <= event_Time2 && event_Time1 <= event_Time3) {
    // time1 is the smallest, check time2 & 3
    if ( event_Time2 <= event_Time3 ) {
      // order is 1,2,3
      Mach_Dist_1 = (event_Time2 - event_Time1) / convMS;
      Mach_Dist_2 = (event_Time3 - event_Time1) / convMS;
      sensorId_1 = 2; sensorId_2 = 3;
    }
    else {
      // order is 1,3,2
      Mach_Dist_1 = (event_Time3 - event_Time1) / convMS;
      Mach_Dist_2 = (event_Time2 - event_Time1) / convMS;
      sensorId_1 = 3; sensorId_2 = 2;
    }
  }
  else if (event_Time2 <= event_Time1 && event_Time2 <= event_Time3) {
    // time2 is the smallest
    if (event_Time1 <= event_Time3) {
      // order is 2,1,3
      Mach_Dist_1 = (event_Time1 - event_Time2) / convMS;
      Mach_Dist_2 = (event_Time3 - event_Time2) / convMS;
      sensorId_1 = 1; sensorId_2 = 3;
    }
    else {
      // order is 2,3,1
      Mach_Dist_1 = (event_Time3 - event_Time2) / convMS;
      Mach_Dist_2 = (event_Time1 - event_Time2) / convMS;
      sensorId_1 = 3; sensorId_2 = 1;
    }
  }
  else {
    // time3 is the smallest
    if (event_Time1 <= event_Time2) {
      // order is 3,1,2
      Mach_Dist_1 = (event_Time1 - event_Time3) / convMS;
      Mach_Dist_2 = (event_Time2 - event_Time3) / convMS;
      sensorId_1 = 1; sensorId_2 = 2;
    }
    else {
      // order is 3,2,1
      Mach_Dist_1 = (event_Time2 - event_Time3) / convMS;
      Mach_Dist_2 = (event_Time1 - event_Time3) / convMS;
      sensorId_1 = 2; sensorId_2 = 1;
    }
  }
}

void getTemperature() {
  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    // Serial.print("Read DHT11 failed, err="); Serial.print(SimpleDHTErrCode(err)); // Not Needed
    // Serial.print(","); Serial.println(SimpleDHTErrDuration(err));                 / /Not Needed
    return;
  }
  temp1 = temperature;
  //Serial.print((int)temperature); Serial.print(" *C, ");
  //Serial.print((int)humidity); Serial.println(" H");

  // DHT11 sampling rate is 1HZ.
  delayMicroseconds(25);
}

void DEBUG()
{
  Serial.print("Sensor #");
  Serial.print(sensor1_ID);
  Serial.print(" ");
  Serial.print(event_Time1);
  Serial.print(" ");
  Serial.print("#");
  Serial.print(sensor2_ID);
  Serial.print(" ");
  Serial.print(event_Time2);
  Serial.print(" ");
  Serial.print("#");
  Serial.print(sensor3_ID);
  Serial.print(" ");
  Serial.print(event_Time3);
  Serial.print(" ");
  Serial.print(" ");
  Serial.print("Temp: ");
  Serial.print("");
  Serial.print(temp1);
  Serial.print("C");
  Serial.print(" -> ");
  Serial.print("Mach Speed = ");
  Serial.print(machSpeed);
  Serial.print("  MPS");
  Serial.print(" Sensor #");
  Serial.print(sensorId_1);
  Serial.print(" ");
  Serial.print("Distance: ");
  Serial.print(Mach_Dist_1, DEC);
  Serial.print('"');
  Serial.print("  Sensor #");
  Serial.print(sensorId_2);
  Serial.print(" Distance: ");
  Serial.print(Mach_Dist_2, DEC);
  Serial.println('"');
  Serial.println("____________________________________________________________________________________");
  Serial.println("");
  Serial.println("");
}

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