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.
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.
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.
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("");
}