Pages: 1 2 3 [4] 5 6   Go Down
Author Topic: Measure nightsky with TSL237  (Read 11846 times)
0 Members and 1 Guest are viewing this topic.
Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am not sure, but i found this site: http://www.avdweb.nl/arduino/hardware-interfacing/frequency-period-counter.html

And i am trying this code:

Code:
#include <FreqPeriodCounter.h>
 
const byte counterPin = 5;
const byte counterInterrupt = 1; // = pin 3
FreqPeriodCounter counter(counterPin, micros, 0);
unsigned long centiHz = counter.hertz(100);
float hz = 1000/counter.period;
 
void setup(void)
{ Serial.begin(9600);
  attachInterrupt(counterInterrupt, counterISR, CHANGE);
}
 
void loop(void)
{ if(counter.ready()) Serial.println(counter.hertz());
}
 
void counterISR()
{ counter.poll();
}

And im getting this now;

Code:
3068
5004
1903
5016
5008
5053
1669
3660
5034
3665
3070
5018
5005
5057
2103
5033
2497
1668
2514
5043
1907
1667
5032
2497
1666
5046
1906
1666
3651
5056
3652

Am i getting the Hz in "centiHz" now? and why is the values fluctuating that much? i left the sensor in a enclosure with the same amout of light hitting it all the time :/
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3080
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You seem to be futzing around changing too many things at once.

If your process depends on counting pulses,   you need to get that process right before
worrying and fiddling with what you do subsequently.
Logged

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You seem to be futzing around changing too many things at once.

If your process depends on counting pulses,   you need to get that process right before
worrying and fiddling with what you do subsequently.

Well, i'm trying out different sketches to try reading just the pulses from the sensor, because the former sketch reading the Hz i think... I am a total newbe and doing many errors to...
Logged

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FreqCounter for very low frequencies (below 100 Hz or something) isn't the best thing you can do to count cycles.

As someone told you, you would need to measure the length of the pulse instead (FreqMeasure, FreqPeriod, InputCapture, pulseIn, millis()/micros() ).
Since at dark time it's rare to get more than 10,000Hz with those sensors, I think FreqCounter isn't useful at all for this project.

Is the limit in the FreqCounter library? i was thinking to count Hz as the sensor itself generates Hz, not pulses... or am i missing something? The sensor is the TSL237 light to frequency sensor.

BR/Daniel
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can count the time length of a number of pulses, the more you count the more the per-pulse average will ... average out.

You can count how many pulses in a measure of time and lose a fraction of a pulse. The longer the time the less the lost fraction means.

pulses/time or time/pulses, both are ratios is all. Get one, you have the other.

 
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can count the time length of a number of pulses, the more you count the more the per-pulse average will ... average out.

You can count how many pulses in a measure of time and lose a fraction of a pulse. The longer the time the less the lost fraction means.

pulses/time or time/pulses, both are ratios is all. Get one, you have the other.

 

That sound quite logical even to me smiley is there any good library/code that i can use for this? I believe that, after counting time, i will be have to translate to time to Hz, in some way, and that Hz is more realible than just counting Hz straight from the sensor?
Logged

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

AHA! Now i understand the differens between pulses and freq, maybe this lib. is more suiteble for me?

http://interface.khm.de/index.php/lab/experiments/frequency-measurement-library/
But he is writning:
The library returns the measured period length in 1/16 us steps as a long integer. To get the frequency, the clock frequency has to divided by the returned value. The clock frequency is set in this example to 16000400 to compensate inaccuracies of the Arduino board.

What is that meaning for me and my arduino?

This might also work?
http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
« Last Edit: March 05, 2013, 10:02:01 am by Corpze » Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I wouldn't use a library. I'd save micros() in an unsigned long, count 10,000 pulses and save the micros() right then.
Annnnnd I think you can get micros() in an interrupt though it's stopped. If not then you'll pick up a couple micros setting a flag in the interrupt, leaving the interrupt and catching the flag in loop(). With a tight loop() you'll have micros() very quickly.

Errors --- you can measure Arduino inaccuracy and compensate. Deal with that after you get the rest working. It amounts to changing time microseconds

frequency = pulses / time

If the time is a 62845 microseconds then multiply pulses by 1 million then divide by 62845 to get Hz = cycles(pulses) per second.

10000 pulses / 62845 usecs = 10000 pulses / ( 62845 seconds / 1000000 ) = 10000 pulses x 1000000 / 62845 seconds (doing it with integers and the least loss requires 64-bit long long int) = 159121 Hz.
 
When you do math for science, keep the units (pulses, seconds, ergs) in the math because at the end if your units don't make sense then your math didn't either. (this is where you remember your science teachers saying the same thing)

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Whats wrong with using library? Is the library i have posted of any use?

I am not that experienced so i can code that kind of things smiley-sad

Thats why i use librarys and allready written code
« Last Edit: March 05, 2013, 02:11:50 pm by Corpze » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@GoForSmoke, 10,000 pulses?!. This would take a whole life if the site is dark. The TSL237 generates generates pulses of frequencies as low as ~0.15Hz in dark skies (even lower if you use filters). That's more than 6 seconds of period, so integrating 10,000 cycles seems a bad idea.

The best approach I think is to measure first one single pulse and decide (at runtime) if you want to count frequencies (or a great amount of pulses to promediate, as GoForSmoke suggested) or you need an alternative way to get the frequency.

Corpze, the SQM is *cheap* for what it does. If you take into account that those instruments need filters to cut the IR and narrow the spectral sensibility, needs some kind of optics to narrow the FoV, needs a case, an LCD, a board ... you end (in the arduino road) with an instrument that is nearly as expensive as the SQM (or even more!) and probably not as accurate (at least if you don't know what you do/need), trust me. And then, you need to calibrate the device.

If you want to build it just for learning purposes or something else, I think you need to return to the basics and stop trying to get inmediate results. I've been researching on this topic for months and I haven't found any library that just do what you want, sorry.

Just my two cents.
« Last Edit: March 05, 2013, 01:46:00 pm by minaya » Logged

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I had all the hardware at home, except for the sensor, UV/IR block filter and lens that on its way (5 USD worth of hardware) It is kind of a learning thingy, maybe it isn't any idéa of keep on going with this :/
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you count pulses for 1800 or even 180 seconds and something bright doesn't intrude, you can get less error than if count 1 or 3 seconds. Can get... because there's always a way to can't anything.

If you count pulses and see that a certain time has elapsed then you will be off by the fraction of the last pulse that didn't make it unless you exactly end the time period on a pulse start. So there you have the fraction error but that is divided by the number of pulses when you determine the average length of just 1 pulse (the inverse of frequency) so the more pulses, the better.

To do that, have an interrupt increment the pulse count and in loop() set up a timer the way it's done in BlinkWithoutDelay and when the interval is reached, copy pulse count and use that with the time interval you set up, do the math and you can have frequency. The longer the interval, the closer to precise you can be as long as something doesn't intrude on the patch of sky you're watching.

OTOH you can set up an interrupt to count some number of pulses and see how long that took, maybe completely in the IRQ. Then your loop() code just watches for the IRQ to update the how-long-it-took variable and report that. You will have pulses and time. 

Why not a library?
You keep wondering what library to use. You keep wondering if the library you use is the problem. That's because you don't know what they do and it is a problem trying to troubleshoot with such an unknown.

In this case what the library does is not difficult and you will doubtless benefit from learning. Just take your time, identify what it is your don't know and learn those pieces as you put it together.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I understand :-) i thing i will give it a try, i think i finally know how you mean :-)
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So you have used interrupts and know to make variables used in interrupts as volatile?
And you know that time is kept in unsigned long variables?

How long can you aim at dark sky to get measurements? 3 seconds? 30 s? 300 s? 30 minutes?

Maybe the best way will be to count pulses and see how long that takes.
....
You understand, if I stop when pulse count is done I can know how many whole usecs (microseconds) it takes but I can't know the fraction of a usec after the last full usec. If it was 400001.7 usecs, I will miss the .7. That is an unavoidable (and small) source of error.
If I stop on a time count while also counting pulses then I can know the usecs and how many pulses but not the fraction. If 100 seconds takes 50.8 pulses, my 100 second read only sees 50.
....
Since pulses are so big compared to usecs there will be more possible error counting over a set time than counting a set number of pulses and seeing how long that took. I would rather have a fraction of a usec (really, Arduino is good to 4 usecs which is still very small) as error than a fraction of a much bigger pulse as error.
What decides the method for me is the way with the smaller error. In this case, it's pretty clear?


So big open to the forum just to be sure question --- can you read micros() in an interrupt?


Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So you have used interrupts and know to make variables used in interrupts as volatile?
And you know that time is kept in unsigned long variables?

How long can you aim at dark sky to get measurements? 3 seconds? 30 s? 300 s? 30 minutes?

Maybe the best way will be to count pulses and see how long that takes.
....
You understand, if I stop when pulse count is done I can know how many whole usecs (microseconds) it takes but I can't know the fraction of a usec after the last full usec. If it was 400001.7 usecs, I will miss the .7. That is an unavoidable (and small) source of error.
If I stop on a time count while also counting pulses then I can know the usecs and how many pulses but not the fraction. If 100 seconds takes 50.8 pulses, my 100 second read only sees 50.
....
Since pulses are so big compared to usecs there will be more possible error counting over a set time than counting a set number of pulses and seeing how long that took. I would rather have a fraction of a usec (really, Arduino is good to 4 usecs which is still very small) as error than a fraction of a much bigger pulse as error.
What decides the method for me is the way with the smaller error. In this case, it's pretty clear?


So big open to the forum just to be sure question --- can you read micros() in an interrupt?




No i haven´t really used interrupts more then those that allready have been written in existing code... I have read the reference about interrupts and there are two kinds? internal and external? the external ones are located on pin2 and 3 on the uno. Is one of those inputs usable for me?

I think 10sec will be the highest time i want to measure (the original SQM-meter measures on 2sec)

So 10000ms of measurements is a number i can start with.

I understand that i will lose the .x count of the pulses if the time runs out smiley

Logged

Pages: 1 2 3 [4] 5 6   Go Up
Jump to: