great,
I added a timeout in the case where the sensor is not producing any PWM signal (not tested obviously): you could even extend it to report a bad sensor...
double analyze(pin_t pulsePin)
{
double temperature = 0.0;// Local variable
const int num_pulses = 160;
const int timeout = 25; // we should see nearly 100 pulses at 4kHz in 25milliseconds
int periodDutyCycle[num_pulses] = {0};
RGB.control(true); // control RGB LED
RGB.color(255, 0, 0);// RGB LED Red
for (int i = 0; i < num_pulses; i++) // get num_pulses samples of HIGH and LOW pulses
{
bool goodRead = true;
int startReadTime = millis();
int highPulseTime = 0;
while(highPulseTime == 0)
{
highPulseTime = pulseIn(pulsePin, HIGH);
if(millis() - startReadTime > timeout)
{
goodRead = false;
break;
}
}
int lowPulseTime = 0;
startReadTime = millis();
while(lowPulseTime == 0)
{
lowPulseTime = pulseIn(pulsePin, LOW);
if(millis() - startReadTime > timeout)
{
goodRead = false;
break;
}
}
if(goodRead) // will only do the math if you have received values, otherwise it will stay zero...
{
periodDutyCycle[i] = highPulseTime / (highPulseTime + lowPulseTime); // save individual period duty cycle
}
}
int dutyCycle = 0;
int num_goodReads = 0;
for(int i = 0; i < num_pulses; i++)
{
if(periodDutyCycle[i] != 0)
{
dutyCycle += periodDutyCycle[i];
num_goodReads++;
}
}
dutyCycle /= num_goodReads;
temperature = (212.77 * dutyCycle) - 68.085;
RGB.control(false); // end RGB LED control
return temperature;
}
compiles as part of this:
/**************************************************************
* Duty Cycle analyzer FUNCTION for PWM temperature sensors
Any pin can be sensor input pin: Specify in function call in the loop()
For debugging, the serial monitor shows all temperatures on one line
**************************************************************/
//double Temp[16] = {0}; // All the temperatures into an array!!
double Tav; // Only variables needed in the loop() function.
int pulsePins[] = { D0, D2, D3, D5, D7, A1, A3, A5, A7, TX };
double Temp[10] = {0}; // All the temperatures into an array!! // 10 in this example
char resultstr[256] = "";
void setup()
{
Serial.begin(9600);
for (int i = 0; i < sizeof(pulsePins)/sizeof(pulsePins[0]); i++)
{
pinMode(pulsePins[i], INPUT_PULLUP);
}
Particle.variable("result", resultstr, STRING);
}
void loop()
{
// 1) Data collection (All 16 Photon pins!)
strcpy(resultstr, ""); // start with an empty buffer
Tav = 0; // get ready to average what we recieve
for (int i = 0; i < sizeof(pulsePins)/sizeof(pulsePins[0]); i++) // count our way through all of the pins
{
Temp[i] = analyze(pulsePins[i]);
Tav += Temp[i]; // add all of the readings together
char myText[10] = ""; // create a littl buffer for your reading.
sprintf(myText, "T%d:%3.2f%d ", i, Temp[i], i < sizeof(pulsePins)/sizeof(pulsePins[0])? "," : ""); // Build your buffer reading by reading
strcat(resultstr, myText); // bolt on each segment to the buffer
}
Tav /= sizeof(pulsePins)/sizeof(pulsePins[0]); // compute the average by dividing by number of readings
Serial.print("temperatures:");
Serial.println(resultstr);
Serial.print("Average = ");
Serial.println(Tav,1);
// 4) Test conditions and send status & alert messages, take actions: Pumps, valves...
if (Temp[0] > 30.0) // Example...
{
Serial.println("T1 > 30 deg");
Particle.publish("Status","T1 > 30 deg",60,PRIVATE);
RGB.control(true); // start control RGB LED
RGB.color(255, 255, 255);// RGB LED White
delay(1000);
RGB.control(false); // stop control RGB LED
}
delay(500); // Slow down!
}
// In this function I'd like to integrate a "median filter":
double analyze(pin_t pulsePin)
{
double temperature = 0.0;// Local variable
const int num_pulses = 160;
const int timeout = 25; // we should see nearlyu 100 pulses at 4kHz in 25milliseconds
int periodDutyCycle[num_pulses] = {0};
RGB.control(true); // control RGB LED
RGB.color(255, 0, 0);// RGB LED Red
for (int i = 0; i < num_pulses; i++) // get num_pulses samples of HIGH and LOW pulses
{
bool goodRead = true;
int startReadTime = millis();
int highPulseTime = 0;
while(highPulseTime == 0)
{
highPulseTime = pulseIn(pulsePin, HIGH);
if(millis() - startReadTime > timeout)
{
goodRead = false;
break;
}
}
int lowPulseTime = 0;
startReadTime = millis();
while(lowPulseTime == 0)
{
lowPulseTime = pulseIn(pulsePin, LOW);
if(millis() - startReadTime > timeout)
{
goodRead = false;
break;
}
}
if(goodRead)
{
periodDutyCycle[i] = highPulseTime / (highPulseTime + lowPulseTime); // save individual period duty cycle
}
}
int dutyCycle = 0;
int num_goodReads = 0;
for(int i = 0; i < num_pulses; i++)
{
if(periodDutyCycle[i] != 0)
{
dutyCycle += periodDutyCycle[i];
num_goodReads++;
}
}
dutyCycle /= num_goodReads;
temperature = (212.77 * dutyCycle) - 68.085;
RGB.control(false); // end RGB LED control
return temperature;
}