@FiDel, Continuing the discussion from Using qsort to average readings:
So I had some time and created an (approx) 4kHz signal on an Arduino and synthesized a pseudo random PWM like this:
void setup()
{
TCCR1B = TCCR1B & 0b11111000 | 0x02; //3906Hz
}
void loop()
{
randomSeed(digitalRead(A0));
analogWrite(5, 100 + random(5));
analogWrite(9, 100 + random(5));
delay(75);
}
and fixed the sketch I offered you to calc the duty cycle (correctly) with floating point numbers and get this output:
tested code (i used only two inputs)
/**************************************************************
* 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 averageTemperature;
int pulsePins[] = { D3, D4 }; //, 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(115200);
for (int i = 0; i < sizeof(pulsePins) / sizeof(pulsePins[0]); i++)
{
pinMode(pulsePins[i], INPUT);
}
Particle.variable("result", resultstr, STRING);
Serial.println("starting");
}
void loop()
{
strcpy(resultstr, ""); // start with an empty buffer
averageTemperature = 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]);
averageTemperature += Temp[i]; // add all of the readings together
char myText[15] = ""; // create a little buffer for your reading.
snprintf(myText, sizeof(myText), "T%d: %5.2fC%s ", i, Temp[i], (i < (sizeof(pulsePins) / sizeof(pulsePins[0]) - 1)) ? "," : " "); // Build your buffer reading by reading
strcat(resultstr, myText); // bolt on each segment to the buffer
}
averageTemperature /= 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(averageTemperature, 2);
delay(5000);
}
double analyze(pin_t pulsePin)
{
double temperature = 0.0;
const int num_pulses = 100;
int goodReads = 0;
double periodDutyCycle[num_pulses] = {0.0};
RGB.control(true);
RGB.color(255, 255, 255); // Making it Red looks lika an error message...
for (int i = 0; i < num_pulses; i++) // get num_pulses samples of HIGH and LOW pulses
{
unsigned long highPulseTime = 0;
highPulseTime = pulseIn(pulsePin, HIGH);
unsigned long lowPulseTime = 0;
lowPulseTime = pulseIn(pulsePin, LOW);
periodDutyCycle[i] = double(highPulseTime) / double(highPulseTime + lowPulseTime); // save individual period duty cycle
}
double dutyCycle = 0;
for (int i = 0; i < num_pulses; i++)
{
dutyCycle += periodDutyCycle[i];
}
dutyCycle /= num_pulses;
//Serial.print("DutyCycle = ");
//Serial.println(dutyCycle);
temperature = (212.77 * dutyCycle) - 68.085;
RGB.control(false); // end RGB LED control
//Serial.println("Returning Temperature: ");
//Serial.println(temperature);
return temperature;
}
so, did you want the median value of the accumulated periodDutyCycle[] array or the Temp[] array?
