High resolution light measurement
#1
Posted 17 September 2011 - 02:50 PM
#2
Posted 17 September 2011 - 04:09 PM
Nick,I bought this light-to-frequency converter: http://www.sparkfun.com/products/9768, which looks promising. Does anyone have any other suggestions for suitable components?
Funny you should mention this component as I was looking at it this morning. I was considering using it to measure daylight. There is an article on Bildr showing an Arduino hooked up to another device in the family. My thoughts were to hook it up to one (or two) binary counters (I was thinking 74HC4040) to get the frequency.
I'd be interested in hearing your experiences.
Regards,
Mark
To be or not to be = 0xFF
Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life
Follow @nevynuk on Twitter
#4
Posted 17 September 2011 - 04:45 PM
#5
Posted 17 September 2011 - 05:33 PM
Nick,I am under the impression that I can use an InterruptPort on the Netduino without the need for additional components. Perhaps code like this would work with the TSL235R? I will give it a try and let you know the results.
The reason I was thinking about the counter was to lower the overhead on the Netduino. By farming this task out you can set it going and come back to it later to get the results.
I was going to put the sensor in various light conditions and measure the frequency to get an idea of the range I could be expecting and let the results determine InterruptPort or hardware. As Mario pointed out, low frequency (and indeed high frequencies) could be a problem. Mind you, it depends upon the level of accurary required.
This is to be part of the greenhouse monitoring / control project I was thinking about for next year. I'd like to think our tomato plants will be watered and cared for to get the most out of them
Look forward to seeing the conclusions you come to.
Regards,
Mark
To be or not to be = 0xFF
Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life
Follow @nevynuk on Twitter
#6
Posted 17 September 2011 - 07:05 PM
#7
Posted 17 September 2011 - 07:52 PM
This is the wiring I am using right now:
TSL235R ------ Netduino
======= ---- ========
GND(1) ---- GND
Vcc(2) ------ +5V
Out(3) ------ Digital I/O pin 2
I also have a 0.1uF cap wired from Vcc to GND, as mentioned in the TSL235R datasheet.
This does not work, and when I try to load my C# via USB, it says: "An error occurred: Please check your hardware." Edit: If I remove the TSL235R from the Netduino, I do not get the hardware error. I have no other devices plugged in to the Netduino.
I also tried wiring it to 3.3V on the Netduino and that does not work either.
Does anyone know what is wrong with my wiring?
Edited by xdfkdkhj, 07 October 2011 - 03:36 AM.
#8
Posted 17 September 2011 - 11:29 PM
using System; using System.Net; using System.Net.Sockets; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.NetduinoPlus; namespace TSL235R { public class Program { // Constants const ulong period = 10000; // Number of light frequency measurements const float area = 0.0092F; // Sensing area of TSL235R device (cm2) // Variables static ulong pulses = 0; // Counter of measurements of the TSL235R static ulong frequency; // Read the frequency from the digital pin (pulses/second) static float irradiance; // Calculated irradiance (uW/cm2) private static InputPort TSL235R_Pin = new InputPort(Pins.GPIO_PIN_D7, false, Port.ResistorMode.Disabled); static int readCount = 0; static bool result = false; static bool prev_result = false; public static void Main() { while (true) { while (readCount < 10000) { result = TSL235R_Pin.Read(); if (result == true && prev_result == false) // Rising pulses++; if (result == false) prev_result = false; if (result == true) prev_result = true; readCount++; } getfrequency(); Debug.Print("Frequency: "); Debug.Print(frequency.ToString() + " pulses/second"); getirradiance(); Debug.Print("Irradiance: " + irradiance.ToString() + " uW/cm2"); readCount = 0; pulses = 0; Thread.Sleep(1000); } } static ulong getfrequency () { frequency = pulses/(period/10000); // Calculate the frequency (pulses/second) return (frequency); } static float getirradiance() { irradiance = frequency / area; // Calculate Irradiance (uW/cm2) return (irradiance); } } }
Example results from debug console:
Frequency: 1786 pulses/second Irradiance: 194130.438 uW/cm2 Frequency: 1790 pulses/second Irradiance: 194565.219 uW/cm2 Frequency: 1932 pulses/second Irradiance: 210000 uW/cm2 Frequency: 2375 pulses/second Irradiance: 258152.172 uW/cm2 Frequency: 2478 pulses/second Irradiance: 269347.812 uW/cm2 Frequency: 2640 pulses/second Irradiance: 286956.5 uW/cm2 Frequency: 2435 pulses/second Irradiance: 264673.906 uW/cm2 Frequency: 3001 pulses/second Irradiance: 326195.656 uW/cm2 Frequency: 2720 pulses/second Irradiance: 295652.156 uW/cm2 Frequency: 2540 pulses/second Irradiance: 276086.938 uW/cm2 Frequency: 2104 pulses/second Irradiance: 228695.641 uW/cm2 Frequency: 2742 pulses/second Irradiance: 298043.469 uW/cm2
There are two problems here though:
- I am not using an InterruptPort, because it did not work properly for me.
- I do not know if the readings I am getting are really accurate irradiance measurements.
Regarding Point 1, if anyone knows how to modify this code to use an InterruptPort, please reply and let me know. I tried to add InterruptPort code, but it causes my Netduino to lock up and become non-responsive to my C# IDE.
Regarding Point 2, I put a black piece of felt cloth over the sensor, and the reading went way down. I then shined a bright light onto the sensor and the reading went way up, so I know I am getting semi-valuable readings. However, the readings fluctuate by about 20 to 50 values while I am at a particular light level, and I am uncertain why. The readings do go up and down as expected, but they also "jump" while they are within that range. How can I fix this? Perhaps there is nothing wrong. I wonder if shadows are causing the "jumps".
#9
Posted 18 September 2011 - 05:49 AM
the specs say that the output frequency can vary from 1Hz up to 1MHz (fig. 1). It means a pulse every second, but as low as 1us. The interrupt port of the Netduino absolutely can't follow a so high rate, nor it is able to serve the counter within the handler (it takes much longer than just a microsec).
Moreover, to measure the frequency, you should count the number of pulses within (let's say) one second. It means that the response time of your "light-detector" could not be faster than just a second.
Now, if the symbol rate of the Sparkle is about 10Hz (1 symbol every 100ms), how will you able to detect the symbols?
Keep it simple!
Watch this circuit: is given for Arduino, but it's absolutely the same for Netduino:
http://www.flickr.co...ter/3483847795/
The only difference is that you should power it using +3.3V, instead of +5V.
How it works?
The transistor is actually a "photo-transistor". It is a (quasi) normal transistor, having a lens focused on the silicon chip inside it.
Look at the schematic now. When the transistor is "open" (i.e. suppose a switch), there's no else component than the resistor pulling the voltage to ground (i.e. 0V).
A normal transistor will let the current flowing when there is a small driving to the "base" lead. Here the base lead is left open, and the light will act as the base was connected. At this point the current flowing through the transistor will bring the analog input toward the +3.3V.
So:
- when it's dark the transistor is "open" and the analog port voltage is close to zero;
- when it's bright the transistor is much like a "variable resistor", acting as a voltage divider, thus the analog port is greater than zero.
In your app you may simply read the AnalogPort, then compare the read value with a couple of thresholds: lower and upper. When the spot is dark, the reading must fall below the lower threshold, when is bright the value must fall above the upper limit.
That's a pretty good yet reliable way to detect the light symbols.
Cheers
#10
Posted 18 September 2011 - 09:20 AM
#11
Posted 18 September 2011 - 01:28 PM
- use the sensor output to feed a counter, then read the number produced by the counter within a time unit (e.g. 1 second);
- use an Arduino board.
The second choice is using the native code on a very basic microcontroller, without any other service running into. However, the Arduino could produce its result, and a Netduino could read it via SPI, for instance.
I'd choose the second solution, because it sounds simpler and more compact than the first one.
The sensor looks great, but there is a problem that makes any conversion hard. You may notice that the sensor has a dynamic of 10E6, i.e. from 1 to 1MHz. In other words, if this sensor was a voltage generator and you were using an ADC, you should consider at least a 20-bit ADC.
So, I guess the Arduino would be the easiest way to monitor the frequency produced by the sensor, just because you may code the best algorithm without great efforts.
Hope it helps.
Cheers
#12
Posted 18 September 2011 - 06:28 PM
The sensor looks great, but there is a problem that makes any conversion hard. You may notice that the sensor has a dynamic of 10E6, i.e. from 1 to 1MHz. In other words, if this sensor was a voltage generator and you were using an ADC, you should consider at least a 20-bit ADC.
So, I guess the Arduino would be the easiest way to monitor the frequency produced by the sensor, just because you may code the best algorithm without great efforts.
Hope it helps.
Cheers
Pardon my ignorance, but does this mean I could connect a 20-bit ADC to an Arduino and use it to measure the TSL235R output and then connect an Arduino to my Netduino via SPI? This way, the Arduino could report the measurements to the Netduino at a certain reasonable time interval. Is that correct?
I found this ADC chip that looks like it interfaces with an Arduino nicely. Although it is a 24-bit ADC, they were getting 18-to-19-bit precision in testing. Would this chip work for me?
#13
Posted 18 September 2011 - 06:40 PM
-- H.L. Mencken, "What I Believe"
#14
Posted 18 September 2011 - 06:51 PM
No, the ADC was for an hypothetical analog sensor. If you're hooking your sensor to an arduino, you can directly count the pulses with it and then send that number to your netduino. However, using an arduino is overkill for that, you could just use a "naked" microcontroller (e.g. an atmega168 or similar - also overkill for this, but a lot cheaper than a "full" arduino - that is, if you already have a programmer/are planning to buy one anyway).
#15
Posted 18 September 2011 - 07:24 PM
#16
Posted 18 September 2011 - 07:44 PM
Nick,I am still confused as to why I cannot directly interface it with a Netduino. Does it somehow make a difference if it is outputting a 50% duty cycle and not a pulse train? How are they doing this with a .Net Micro Framework board? Here is an example of directly interfacing a TSL230R with a .Net FEZ board, using .Net Micro Framework C# code. Am I missing something? Are they scaling the result or something?
It's down to the speed that the Netduino works at compared to the frequency range. Whilst the processor itself is fast you need to allow a fair amount of the CPU time for NETMF. You could find yourself with the interrupts coming in to fast for NETMF to process. You also have to consider that there is some latency in processing the interrupt and also grabbing the time. This latency can lead to errors in calculating the frequency.
Cannot comment of the FEZ example or how / why that works.
Regards,
Mark
To be or not to be = 0xFF
Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life
Follow @nevynuk on Twitter
#17
Posted 18 September 2011 - 07:53 PM
Just browsing the code and they use a NativeEventHandler - wondering if this is helping with the speed of the interrupts?Here is an example of directly interfacing a TSL230R with a .Net FEZ board, using .Net Micro Framework C# code. Am I missing something? Are they scaling the result or something?
Regards,
Mark
To be or not to be = 0xFF
Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life
Follow @nevynuk on Twitter
#18
Posted 18 September 2011 - 08:33 PM
#19
Posted 18 September 2011 - 08:40 PM
Just browsing the code and they use a NativeEventHandler - wondering if this is helping with the speed of the interrupts?
Regards,
Mark
No, that part of the code is redundant.
The method will also work on the netduino, as long as the frequencies don't get too high. From the datasheet you can see that the frequency can go up to at least 500khz (they don't provide an absolute upper limit, but a graph in it goes up to 1mhz) which means that there's one pulse every 2 µs, and that is too fast (i don't have absolute timings, but i recall interrupts taking at least 20µs).
-- H.L. Mencken, "What I Believe"
#20
Posted 18 September 2011 - 09:50 PM
Using an Interrupt Reading 0 20400 Hz 221739.13043478262 uW/cm2 2650.3369113867698 lux (single) 163.81671308080081 lux (gauss) Reading 1 20500 Hz 222826.08695652176 uW/cm2 2663.3287589916072 lux (single) 164.61973618413808 lux (gauss) Reading 2 20400 Hz 221739.13043478262 uW/cm2 2650.3369113867698 lux (single) 163.81671308080081 lux (gauss) Reading 3 3500 Hz 38043.478260869568 uW/cm2 454.71466616929877 lux (single) 28.105808616804058 lux (gauss) Invalid frequency 0 Invalid frequency 0 Invalid frequency 0
I guess I am going to have to learn how to program another bare MCU and use that for my readings. It is really cool to watch the frequency change on my oscilloscope as the light levels change. The readings look nice and stable. And yes, I shined a really bright light on the sensor and watched the scope and it did go to one pulse every 2µs.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users