How to perform calculations with data from micros()?

I am trying to do some TDOA calculations with data received from three microphones. I am getting the time values from micros() after generating a sound e.g., a clap. I receive all the data I need but now when I try to calculate the TDOA with the speed of sound; I am not getting the expected values. Most of the time I just get zero but occasionally I get some random number.

How should I code this function properly?

The Function follows:

//=== The following variable are declared in the general variable area atop this program
volatile unsigned long Mach_Dist_1;
volatile unsigned long Mach_Dist_2
volatile double machInch = (machSpeed * .0254); 

void machDistance() {

  sensorId_1 = 0;
  sensorId_2 = 0;
  Mach_Dist_1 = 0;
  Mach_Dist_2 = 0;
    double convMS = 1000000;
    
    // 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 * machInch;
    Mach_Dist_2 = ((event_Time3 - event_Time1)) / convMS * machInch;
     sensorId_1 = 2; 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 * machInch;
      Mach_Dist_2 = ((event_Time3 - event_Time2)) / convMS * machInch;
       sensorId_1 = 1; sensorId_2 = 3;
    }
    else if (event_Time1 >> event_Time3) {
      Mach_Dist_1 = ((event_Time3 - event_Time2)) / convMS * machInch;
      Mach_Dist_2 = ((event_Time1 - event_Time2)) / convMS * machInch;
       sensorId_1 = 3; sensorId_2 = 1;
    }
  }

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

What do you think that statement is doing? << is the left shift operator, not less-than

Yep, I'm a dope!

Thank you for confirming that! :neutral_face:

I corrected the code and I am receiving the "sensorId_n" changes but no distance calculations. I have to comment out the the

// / convMS) * machInch;

to see the TDOA feedback which i didn't have before. This shows the delta of the two times.

Please post the revised code. All of it, not just the function.

To test the timing calculation, don't start with real sensor data. Instead, start with some fictional numbers that represent valid sensor data, and make sure that you get the expected answers.

Here is the complete modified code. Sorry for the size.

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

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

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

// Sensor Read Values
bool check_Mic_State; // Var to hold Sound Value
volatile bool micValue1; // Var to hold detected Value of Mic 1
volatile bool micValue2; // Var to hold detected Value of Mic 2
volatile bool micValue3; // Var to hold detected Value of Mic 3
volatile bool micState = HIGH; // PWM State

// Catchall Timing Vars
volatile unsigned long noDetect;
volatile unsigned long event_Time1;
volatile unsigned long event_Time2;
volatile unsigned long event_Time3;
volatile int sensorId_1;
volatile int sensorId_2;

//Mach Travel Vars
volatile double Mach_Dist_1 = 0.0000000000;
volatile double Mach_Dist_2 = 0.0000000000;

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

// Pin State Variables
volatile bool pinState1 = LOW;
volatile bool pinState2 = LOW;
volatile bool pinState3 = LOW;

// Mach Variable
volatile double machSpeed = 0.0000000000; // Var to hold calculated speed of sound value
volatile double machInch = (machSpeed * .0254);

// Temperature Sensor Variables.
int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);
volatile 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, HIGH); // Detection Interrupt
  attachInterrupt(3, s2Det, HIGH); // Detection Interrupt
  attachInterrupt(4, s3Det, HIGH); // Detection Interrupt

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

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

  // Reset used variables
  resetTemp();
  resetMachVar();
  resetIntVar();
}

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

void s1Det() {
  s1Time = micros();
  pinState1 = HIGH;
}

void s2Det() {
  s2Time = micros();
  pinState2 = HIGH;
}

void s3Det() {
  s3Time = micros();
  pinState3 = HIGH;
}

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

void loop() {
  while (pinState1 && pinState2 && pinState3 != LOW) {

    // Set Interrupt Timing Vars
    event_Time1 = s1Time;
    event_Time2 = s2Time;
    event_Time3 = s3Time;

    // Reset noDetect
    noDetect = 0;

    if (event_Time1 && event_Time2 && event_Time3 != 0) {
      getDetectSensors();
    }
  }
}

//================== COMMENCE SENSOR DETECTION SEQUENCE ===================

void getDetectSensors() {
  // Reset Digital Read Vars
  micValue1 = LOW;
  micValue2 = LOW;
  micValue3 = LOW;
  check_Mic_State = LOW;

  while (check_Mic_State != micState) {

    //=== Check Mic #1 ===

    check_Mic_State = LOW;
    check_Mic_State = pinState1;
    if (event_Time1 > 0) {
      s1Time = 0; // Kill the interrupt time value flag
      micValue1 = check_Mic_State;
      check_Mic_State = LOW;
      pinState1 = LOW; // Kill the interrupt pin state flag.

      //=== Test For Timeout ===

      while (micValue1 == micState && check_Mic_State != micState) {
        noDetect = micros() - event_Time1;
        if (noDetect > 250) // Check if 1st detection is timed out loop if true
        {
          micValue1 = LOW;
          pinState1 = LOW;
          NoDetect();
        }

        //=== Check Mic #2 ===

        check_Mic_State = LOW;
        check_Mic_State = pinState2;
        if (event_Time2 > 0) {
          s2Time = 0;
          micValue2 = check_Mic_State;
          check_Mic_State = LOW;
          pinState2 = LOW;

          //=== Check Mic #3 ===

          check_Mic_State = LOW;
          check_Mic_State = pinState3;
          if (event_Time3 > 0) {
            s3Time = 0;
            micValue3 = check_Mic_State;
            check_Mic_State = LOW;
            pinState3 = LOW;

            //calculate mach travel
            machDistance();

            //Troubleshooting Tool
            DEBUG();
          }
        }
      }
    }
  }
}

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

void getDetections() {
}

void resetIntVar() {
  event_Time1 = 0;
  event_Time2 = 0;
  event_Time3 = 0;
  s1Time = 0;
  s2Time = 0;
  s3Time = 0;
  Serial.println("Sensors Ready:"); // show we are ready for detection
  Serial.println("");
}

//=== Debugging Tool

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("mach-Inch: ");
  Serial.print(Mach_Dist_1);
  Serial.print("  Sensor #");
  Serial.print(sensorId_2);
  Serial.print(" mach-Inch: ");
  Serial.println(Mach_Dist_2);
  Serial.println("____________________________________________________________________________________");
  Serial.println("");
  Serial.println("");
  check_Mic_State = LOW;
  distCalc();
  resetTemp();
  resetIntVar();
  resetTDOA();
  loop();
}

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

void resetTemp() {
  getTemperature();
}

void resetMachVar() {
  distCalc();
}

void machDistance() {
  sensorId_1 = 0;
  sensorId_2 = 0;
  Mach_Dist_1 = 0;
  Mach_Dist_2 = 0;
  long convMS = 1000000;

  // 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 * machInch);
    Mach_Dist_2 = ((event_Time3 - event_Time1) / convMS * machInch);
    sensorId_1 = 2; 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 * machInch);
      Mach_Dist_2 = ((event_Time3 - event_Time2) / convMS * machInch);
      sensorId_1 = 1; sensorId_2 = 3;
    }
    else if (event_Time1 > event_Time3) {
      Mach_Dist_1 = ((event_Time3 - event_Time2) / convMS * machInch);
      Mach_Dist_2 = ((event_Time1 - event_Time2) / convMS * machInch);
      sensorId_1 = 3; sensorId_2 = 1;
    }
  }

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

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

void resetTDOA() {
  Mach_Dist_1 = 0;
  Mach_Dist_2 = 0;
  sensorId_1 = 0;
  sensorId_2 = 0;
  //Serial.println(Mach_Dist_1);
  //Serial.println(Mach_Dist_2);
  Serial.println("");
  //Serial.println(c1[3]);
}

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);
}

Great, but what happens when you put in manufactured sensor data?

Put in some print statements to make sure that intermediate variables and results are what you expect them to be.

So, I injected three fake sensor values into the catchall loop () function and did the same with the getDetections function. The outcome was the same in both simulations. Which happens to be the same as with real sensor data. Still no distance calculation as the values remains as zero's while the sensorId_1 and SensorId_2 changed to the correct id as I manipulated the fake data to simulate each sensor detecting at different times.

That is a great first step! Now, put in more Serial.print() statements to see where the calculations go wrong.

1 Like

Still working on it. Will start with a fresh mind tomorrow. Thanks for thanks for the help!

First off, what board are you using? This

  attachInterrupt(2, s1Det, HIGH); // Detection Interrupt
  attachInterrupt(3, s2Det, HIGH); // Detection Interrupt
  attachInterrupt(4, s3Det, HIGH); // Detection Interrupt

will only work on a Due. Not all pins can be attached to interrupts. attachInterrupt() - Arduino Reference

Do you want these interrupts to continue to trigger while the pin is HIGH or do you want it to trigger once when it goes from LOW to HIGH (RISING)? Big difference.

Second, you don't need to make all your variables volatile only the ones used in your ISR and main code which would be pinStateX and sXTime

Speaking of your pinState variables, they are bool so should be true/false, not HIGH/LOW. Not technically a problem since true == HIGH == 1 and false == LOW == 0

This statement:

while (pinState1 && pinState2 && pinState3 != LOW) {

is the same as

while (pinState1 == true && pinState2 == true && pinState3 == true) {

is that what you want? I can't really follow the logic. Is it wait for all pins to go high and then do the calculations?

finally, when you are copying volatile variables bigger than 1 byte, you have to turn off interrupts to avoid the chance of corruption

    // Set Interrupt Timing Vars
    noInterrupts();
    event_Time1 = s1Time;
    event_Time2 = s2Time;
    event_Time3 = s3Time;
    interrupts();

And then you should use your event times in your calculations, not sXTime;

2 Likes

First off, what board are you using?

I started this project on a mega2560 but switched to Redboard Artemis from Sparkfun. All digital pins can be used as interrupts. It works great.

Do you want these interrupts to continue to trigger while the pin is HIGH or do you want it to trigger once when it goes from LOW to HIGH (RISING)?

Hmm, Thanks for bringing this up. I don't want them to continuously trigger, I'll change them to RISING.

Is it wait for all pins to go high and then do the calculations?

Yes.

finally, when you are copying volatile variables bigger than 1 byte, you have to turn off interrupts to avoid the chance of corruption

That's HUGE! Thank you and will change it.

And then you should use your event times in your calculations, not sXTime;

That is what I am doing.

Second, you don't need to make all your variables volatile only the ones used in your ISR and main code which would be pinStateX and sXTime

Speaking of your pinState variables, they are bool so should be true/false, not HIGH/LOW. Not technically a problem since true == HIGH == 1 and false == LOW == 0

Done.

finally, when you are copying volatile variables bigger than 1 byte, you have to turn off interrupts to avoid the chance of corruption

    // Set Interrupt Timing Vars
    noInterrupts();
    event_Time1 = s1Time;
    event_Time2 = s2Time;
    event_Time3 = s3Time;
    interrupts();

This doesn't work. I get: 'noInterrupts' was not declared in this scope

I've worked a solution to my problem and will post soon.

Problem solved!

Apparently, the root of the issue was an inability of the IDE to parse equations as I had them structured within the original function. It is odd to me that the IDE couldn’t calculate simple math when parts of the formula are encased in parenthesis. Of course, it may not be the IDE that is the culprit, but my mediocre ability in constructing the code.

So instead of trying to make it work like the big boys do, I resolved to coax it into taking baby steps, literally, see my updated code below.

void machDistance() {

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

  // Instansiate the U.S standard inch conversion variable
  machInch = (machSpeed * .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;
    Mach_Dist_1 = Mach_Dist_1 / convMS * machInch;
    Mach_Dist_2 = event_Time3 - event_Time1;
    Mach_Dist_2 = Mach_Dist_2 / convMS * machInch;
    sensorId_1 = 2; sensorId_2 = 3;
  }

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

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

I am sure there is a better resolution, one that would reduce the bloat and perhaps even save my sanity. If anyone cares to share one, I’m eager to see it. Now, the most frustrating part of debugging this was the inability to view through Serial.print(), the high precision values within the double type variables.

Double only shows up to two decimal places, unfortunately, and the precision we are dealing with are as low as eight additional places to the right. So, in the beginning when I saw zeroes in my variables, although incorrect because of the math problem outlined above, I couldn’t see the numbers because of their depth. If I had known this “limitation” beforehand, the debugging process would have been a lot quicker. When I was searching for a resolution online, I saw a half dozen or so different and tedious techniques, including an elaborate fifty plus line function.

So as a contribution to this forum, I would like to share this dandy little nugget on how to serial print long double values. All that is needed, in situations like mine is:

Serial.print(double, DEC); That’s it.  

It is not the IDE, it is the C++ compiler that is following the rules. "simple math" for humans is not the same as for the compiler. When dealing with integer values, the compiler does not automatically convert them to floating point like a human would.

It pared down your original code a bit but it still uses the 'interrupts()' call since I don't have that board and can't verify the code

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

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

// 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.0;
double Mach_Dist_2 = 0.0;
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, HIGH); // Detection Interrupt
  attachInterrupt(3, s2Det, HIGH); // Detection Interrupt
  attachInterrupt(4, s3Det, HIGH); // 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;
}

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

void s3Det() {
  s3Time = micros();
  if ( !started ) startTime = s2Time;
  pinState3 = 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();   // get temperature
  distCalc();         // recalculate speed based on temperature
  machDistance();     // calculate distances
  DEBUG();            // display it all
  resetSensors();     // start again
}


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

void resetSensors() {
  noInterrupts();
  pinState1 = false;
  pinState2 = false;
  pinState3 = false;
  started = false;
  interrupts();
  Serial.println("Sensors Ready:"); // show we are ready for detection
  Serial.println("");
}

//=== Debugging Tool

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("mach-Inch: ");
  Serial.print(Mach_Dist_1);
  Serial.print("  Sensor #");
  Serial.print(sensorId_2);
  Serial.print(" mach-Inch: ");
  Serial.println(Mach_Dist_2);
  Serial.println("____________________________________________________________________________________");
  Serial.println("");
  Serial.println("");
}

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

void machDistance() {
  const double convMS = 1000000.0 * 0.0254; // convertion 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 distCalc() {
  machSpeed = (331.3 + (.606 * temp1));
}

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);
}
1 Like

I suspect that the noInterrupts() and interrrupts() functions are not a feature of the Apollo MCU. So your code won't compile unless I comment out those lines. However. It does compile on the Arduino Mega 2560 when BurstMode is commented out. After running the code, on both boards, it stalls at Sensors ready and will not detect anything. I will try to figure it out tomorrow. Nice Work!.

There's also this lightly documented function dtostre() (double-to-string-E format) for precision far away from 0.0:

char buff[40];
dtostre(PI/1e6,buff,7,0);  // prints 3.1415927e-06
Serial.println(buff);
dtostre(PI/1e6,buff,7,DTOSTR_UPPERCASE|DTOSTR_ALWAYS_SIGN|DTOSTR_PLUS_SIGN);  // prints +3.1415927E-06
Serial.println(buff);

3.1415927e-06
+3.1415927E-06

  

See avr-libc: <stdlib.h>: General utilities

1 Like

Tried debugging a little bit this morning. The only thing I know for sure is that it is looping at
if ( !started ) { return; } and the sensors are not triggering.

The following

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

Should be

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

And

const double convMS = 1000000.0 * 0.0254; // convertion to inches

Should be

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

The conversion won't work without it.

I'll put more effort into it this afternoon.

Back at it.

An omission is causing the stall.

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

There is nothing here to toggle started. So I added:

void loop() {

  // toggle started
  if (startTime != 0) {
    started = true;
  }

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

Then I added the startTime Variable to resetSensors().

void resetSensors() {
  //noInterrupts();
  pinState1 = false;
  pinState2 = false;
  pinState3 = false;
  started = false;
  startTime = 0;  // stops infinite loop.
  //interrupts();
  Serial.println("Sensors Ready:"); // show we are ready for detection
  Serial.println("");
}

Then I removed the constant type from convMS because its value changes with variations in the temperature:

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

Now the program runs but the distance calculations are not computing.