If it can help, here is one I recently made, and I’d like to integrate a “median filter” in the analyze() function:
(My previous choice of water temperature sensor was one with PWM output, needing one I/O pin per sensor. Below is a sketch I made to read temperatures of 16 of these sensors with one Particle. I will adapt it to use the DS18B20 sensors.)
/**************************************************************
* 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
**************************************************************/
float T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Tav, temperature; // Only variables needed in the loop() function.
int nrPins;
char resultstr[64]; // To send results to Google as string
void setup()
{
Serial.begin(9600);
Particle.variable("result", resultstr, STRING);
}
void loop()
{
// 1) Data collection (All 16 Photon pins!)
nrPins=0; // Reset every time
analyze(D0);
T1=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D0 ");
}
analyze(D1);
T2=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D1 ");
}
analyze(D2);
T3=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D2 ");
}
analyze(D3);
T4=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D3 ");
}
analyze(D4);
T5=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D4 ");
}
analyze(D5);
T6=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D5 ");
}
analyze(D6);
T7=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D6 ");
}
analyze(D7);
T8=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=D7 ");
}
analyze(A0);
T9=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A0 ");
}
analyze(A1);
T10=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A1 ");
}
analyze(A2);
T11=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A2 ");
}
analyze(A3);
T12=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A3 ");
}
analyze(A4);
T13=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A4 ");
}
analyze(A5);
T14=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A5 ");
}
analyze(A6);
T15=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A6 ");
}
analyze(A7);
T16=temperature;
if (temperature!=0)
{
nrPins++;
Serial.print("=A7 ");
}
// 2) Data processing
// Calculate average, buffer energy etc...
if (nrPins!=0)
{
Tav=(T1+T2+T3+T4+T5+T6+T7+T8+T9+T10+T11+T12+T13+T14+T15+T16)/nrPins;
Serial.print(" T-av = ");
Serial.println(Tav,1);
}
// 3) Data broadcasting to Google
sprintf(resultstr, "{\"T1\":%lg,\"T2\":%lg,\"T3\":%lg,\"T4\":%lg,\"T5\":%lg,\"T6\":%lg,\"T7\":%lg,\"T8\":%lg}", T1, T2, T3, T4, T5, T6, T7, T8);
// 4) Test conditions and send status & alert messages, take actions: Pumps, valves...
if (T1 > 30) // 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":
void analyze(pin_t pulsePin)
{
RGB.control(true); // control RGB LED
RGB.color(255, 0, 0);// RGB LED Red
unsigned long startTime, endTime; // Variable to record the start & end time
int nrPulses = 160; // Even number: Number of HI+LOW pulses (Number of spaces in array)
int periods = nrPulses/2; // For this sensor, use a multiple of 8! (See datasheet)
int dataCounter;
byte storedData[nrPulses]; // Array to store the data
// Use floating variables for calculations
float transmissionDuration, transmissionDurationSec, totalCount, totalLowCount, totalHighCount, dutycycle, frequency;
temperature=0;// Reset each time
frequency=0;
pinMode(pulsePin, INPUT_PULLUP);// Make the pin HIGH without signal
startTime=micros(); //Start time to measure wait time
while(digitalRead(pulsePin) == HIGH) //Detect NO CONNECTION; Wait for LOW signal:
{
if ((micros()-startTime) > 10000) // If it takes longer than 10ms, quit function!
{
return;// Exit the function!
}
}
RGB.color(0, 0, 255);// RGB LED Blue
while(digitalRead(pulsePin) == LOW) //Wait here until a HIGH signal is received:
{
startTime=micros(); //Reset start time with every recording
}
for(int i=0; i<nrPulses; i=i+2) // Record pulse train!
{
dataCounter=0; //reset the counter
while(digitalRead(pulsePin) == HIGH)
{
dataCounter++;
storedData[i]=dataCounter;
}
dataCounter=0; //reset the counter
while(digitalRead(pulsePin) == LOW)
{
dataCounter++;
storedData[i+1]=dataCounter;
}
}
endTime=micros(); //End time of the pulse train reading
transmissionDuration=endTime-startTime;
transmissionDurationSec = transmissionDuration/1000000;
frequency = periods/transmissionDurationSec;
//Serial.print("Freq = ");
//Serial.println(frequency,0);
totalLowCount=0; //reset accumulator
totalHighCount=0; //reset accumulator
for(int i=0; i<nrPulses; i=i+2)
{
totalHighCount=totalHighCount+storedData[i]; // Total all HIGH pulses
totalLowCount=totalLowCount+storedData[i+1]; // Total all LOW pulses
//Serial.print(storedData[i]);
//Serial.print(",");
//Serial.println(storedData[i+1]);
}
totalCount=totalHighCount+totalLowCount;
dutycycle=totalHighCount/totalCount;
temperature = (212.77*dutycycle)-68.085;
if (temperature!=0)
{
Serial.print(temperature,1);
}
RGB.control(false); // end RGB LED control
}