Ok, that's a bit strange.
The complete code is large and does many different things (printing on LCD, printing on SD, printing through Serial interface, reading and callibrating the TSL response with temperature ...). In fact, it nearly fills the entire flash space, ~29kbytes. So I extracted the relevant part and remove all other parts.
#define TSL238PIN 5 // TSL238 data pin. Must be 5 to measure high freqs (Timing 1 port)
#define DELAY_MEASURES 15000 // Delay between measures
#include <FreqCounter.h>
const byte TSL238PINS[] = {6,7}; // List of (digital) pins in use to select the photodiode.
float high_freq_measure();
float low_freq_measure(unsigned short maxmeasures);
void freq_measure(unsigned short maxmeasures);
float freq = 0.0;
float freqs[sizeof(TSL238PINS)];
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Freq Measures
*/
float high_freq_measure(){
// Use FreqCounter to measure high frequencies
FreqCounter::f_comp=100; // Cal Value / Calibrate with professional Freq Counter
FreqCounter::start(1000); // 1000 ms Gate Time
while (!FreqCounter::f_ready); // Wait for the end of a cycle
FreqCounter::f_freq; // Throw away this sample
while (!FreqCounter::f_ready); // Wait for a new cycle to complete
float hfrq = FreqCounter::f_freq;
return hfrq;
}
float low_freq_measure(){
// Use pulseIn to measure low frequencies.
float period = 0;
byte tries = 0;
do{
period = 2*pulseIn(TSL238PIN, LOW, 1000000); // uS
}
while(period==0 && ++tries<=5);
return(1000000.0/period);
}
void freq_measure(unsigned short maxmeasures){
unsigned short measures=maxmeasures;
freq = 0.0;
freq = high_freq_measure();
if (freq<10000){
freq = 0.0;
do{
freq+=low_freq_measure();
//delay(10);
}
while(--measures);
freq = freq/maxmeasures;
}
else{
freq = 0.0;
do{
freq+=high_freq_measure();
//delay(10);
}
while(--measures);
freq = freq/maxmeasures;
}
}
void setup(){
// Initialize serial COM (computer)
Serial.begin(9600);
Serial.flush();
pinMode(TSL238PIN, INPUT);
for (byte k=0; k<sizeof(TSL238PINS); k++){
pinMode(TSL238PINS[k], OUTPUT);
digitalWrite(TSL238PINS[k],HIGH);
}
}
void loop(){
if (millis()%DELAY_MEASURES == DELAY_MEASURES/2){
for (byte j=0; j<sizeof(TSL238PINS); j++){
// Deactivate all sensors except the one we will use now
for (byte k=0; k<sizeof(TSL238PINS); k++)
digitalWrite(TSL238PINS[j],HIGH);
digitalWrite(TSL238PINS[j],LOW);
freq_measure(10);
// Save measure in the array for further analysis (not showed in this version)
freqs[j] = freq;
freq = high_freq_measure();
digitalWrite(TSL238PINS[j],HIGH);
}
for (byte j=0; j<sizeof(TSL238PINS); j++){
Serial.print("TSL "); Serial.print(j); Serial.print(".- "); Serial.print(freqs[j]);
Serial.print("["); Serial.print(freq); Serial.print("]"); Serial.print(" ");
}
Serial.println(" ");
}
}
But as I said, it's strange. This little piece of code seems to work without issues. In fact, I used this code to calibrate the FreqCounter library with PulseIn. I see a clear offset of +37.4Hz (FreqCounter prints the same as PulseIn plus these +37.4Hz offset). Both measures are pretty linear (1.00035 slope, with R2=0.97 !). But this is another issue hehe.
I thought, maybe there's something weird elsewhere ... ?. I rewrote and tested carefully all other parts (removing some older functions and init code of sensors I won't use anymore like the DHT11, LM35, the internal voltmeter and thermometer) and now it doesn't show those random buggy measures.
The new code just returns what it should return,
Time:789438; F1=15528.053Hz;F2=506.060Hz
Time:804453;F1=15643.705Hz;F2=533.424Hz
Time:819439;F1=15205.911Hz;F2=486.460Hz
Time:834440;F1=14978.887Hz;F2=477.104Hz
Time:849440;F1=15660.700Hz;F2=532.094Hz
Time:864450;F1=14742.996Hz;F2=500.471Hz
Time:879443;F1=15596.983Hz;F2=531.732Hz
If I see that the problem reappears, I will show the complete code here.