Shop OBEX P1 Docs P2 Docs Learn Events
Measuring light energy using multiple TSL230's — Parallax Forums

Measuring light energy using multiple TSL230's

RichardFRichardF Posts: 168
edited 2007-06-27 19:09 in Propeller 1
Fellow Spinners,
My application requires reading 8 TSL230 light to frequency converters as rapidly as possible and with as much dynamic light energy range as possible. There·will··be a compromise because it takes more time to measure lower frequencies.·I want to do this in Spin first, then go on to assembly later.· I have come up with the following method as a starting point:

PUB start
cognew(measFreq, @stack2)
'do something with freq[noparse][[/noparse]pinx]
····
PUB measFreq
ctra[noparse][[/noparse]30..26] := %01010························· · 'counter module set·to pos edge detect
repeat···················································'continuous light energy meaurement
· repeat pinx from 0 to 7···················· ···· ·'select TSL230 input pin to read·
··· ctra[noparse][[/noparse]5..0] := pinx
··· frqa := 1············································'add 1 to ·phsa·with each pos edge detect
··· phsa~···············································'clear phsa
··· waitcnt(clkfreq/10+cnt)·················· ·· · 'count detects for 1/10 sec period
··· freq[noparse][[/noparse]pinx] := phsa*10·························· 'save frequency measured

I should be able to measure and save values for all 8 detectors in less than a second. My lower frequency range·should be limited to ~15 hz. In my application I don't think I will need to go near as low as 20 hz, so I can keep reducing the count period and increase the number of reads per second as my application proceeds in development. Basically, I·want to be able to detect a flashbulb going off in daylight conditions and tell in what direction it is coming from. I don't need true values of frequency for comparison, only changes·in relative values between the converters. I will need to experiment with different ranges and look at the dynamic changes in frequency that occur.

I would appreciate any comments on this, especialy ways·to speed up the reads and increase dynamic range.

Thanks,
Richard·

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-06-26 15:26
    You could use two counters: ctra for 0 through 3, say, and ctrb for 4 through 7. The counters can count simultaneously, cutting your read time in half. Also, for lower frequencies, it may be faster (and more accurate) to measure the period, assuming that jitter is negligible.

    This is an interesting app! Please keep us tuned in!

    -Phil
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2007-06-26 16:28
    Hi Richard,

    Correct me if I am missing something, but isn't the duration of a flashbulb flash less than 0.1 second, in which case the sampling would have to be much faster. The TSL230 does have frequency and sensitivity scaling.

    To measure period, it might be possible to do all channels in parallel in assembly, using a waitpne mask. Every time there is a transition, update the period of the sensor that changed state, update the mask, and loop. That would take a cog. The 8 element data array could be passed to other objects in a producer/consumer scheme.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-06-26 17:34
    Oops, I missed the part about the flash. blush.gif Tracy's right: you need to measure all eight periods simultaneously in assembly for any hope of capturing a flash.

    To get an idea what you'd be looking at, I took an old TCS230 board without the lens or LEDs, programmed it to read the "clear" channel, and hooked the output to a scope. (The TCS230 is similar to a TSL230, but with color filters.) The scope was set to trigger on a pulse width less than 5µS, so I could capture the flash event. Then I took a flash picture of the setup. The resulting photo and the scope trace are shown in the photos below.

    As you can see, the flash event lasted only 160µS, but it does cause a significant change in the output period during that time.

    -Phil
    640 x 454 - 80K
    640 x 480 - 18K
  • deSilvadeSilva Posts: 2,967
    edited 2007-06-26 18:31
    Tracy Allen said...
    To measure period, it might be possible to do all channels in parallel in assembly, using a waitpne mask.
    This is a great idea, perhaps a little bit easier to implement by simple polling rather than waits..
    I did not try the following code, but it should be not far from Tracy's idea. It has to be assmebler of course....

    The current period of all (upto 32!) I/Os is readily available through vector "periodV".

    A change of frequency has to be detected by other means which needs much more code! Note that this mainloop must not be disturbed by conditional code


                 MOV p0, INA
                 MOV p1, p0
                 XOR p1, p2     ' difference
                 
                 MOV p2, p0
                 
                 MOV pcount, #8  ' or some more [img]http://forums.parallax.com/images/smilies/smile.gif[/img]
                 MOVD :add, #countingV
                 MOVS :add2, #countingV
                 MOVD :add2, #periodV
                 MOVD :add3, #countingV
    
    :inloop:     SHR p0 ,#1   wc  ' is it low?
    :add:  IF_NC ADD 0-0, #1      ' count on low phase
            IF_C SHR p1, #1  wc   ' a change to high?
                 
    :add2:  IF_C MOV 0-0, 0-0     ' save the period!
    :add3:  IF_C MOV 0-0, #0     ' ... and reset countingV
                 ADD :add, add200
                 ADD :add2, add201
                 DJNZ pcount, #:inloop
    
    ....
    
    p0         LONG 0   ' current ios - shifting
    p1         LONG 0   ' differences - also shifting
    p2         LONG 0   ' last ios
    
    add200     long $200  ' for incrementing dest fields
    add201     long $201  ' for incrementing both fields
    countingV  res 8
    periodV    res 8
    
    


    (Corrected a bug :- )

    Post Edited (deSilva) : 6/26/2007 6:41:51 PM GMT
  • RichardFRichardF Posts: 168
    edited 2007-06-26 20:22
    Phil and DeSilva,
    Please bring it down about ten notches. You are in areas way over my head! Maybe a year from now, but for now... thanks.
    In my further testing of how high a frequency I can count in the minimum period of time using just Spin, the following is the best I can do so far:
    Note: pin 15 and 16 are jumpered together.

    PUB freqOut
    dira[noparse][[/noparse]15]~~
    repeat
    waitcnt(400 + cnt) 'around 100 khz?
    !outa[noparse][[/noparse]15]

    PUB measFreq
    ctra[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16
    frqa := 1
    phsa~
    waitcnt(clkfreq/1000 + cnt) 'around 1 ms measurement time
    dc := phsa

    dc comes out to be 22 on the Lcd. If I multiply frequency by ten I get register overflow; if I reduce measurement time by ten I get zero in phsa.
    The lowest frequency I can measure with a 1 ms measurement period is around 10 khz. That gives me a value of 7 in phsa.

    Phil,
    Based on your scope results with a flash and TSL230 I may still get enough of a change in converter output to see a measurable difference from the other converters. I am thinking the 230 converter output takes a while to revover after the flash, so there is a longer period than 5us that a change in output frequency can be noted.

    Richard

    Post Edited (RichardF) : 6/26/2007 8:34:19 PM GMT
  • deSilvadeSilva Posts: 2,967
    edited 2007-06-26 21:36
    The figures you derive are confusing at the first glance. I think the problem is that "freqOut" does not do what you expect - it is way to slow smile.gif

    The repeat-loop will take approx. 20 mys
    Adding a wait delay of 5 mys is minimal

    Thus you get 50 mys for a full cycle which results in your reading of around 20 in 1ms.

    Reducing the wait delay will bring you a desaster, as 200 or 300 are minimum wait times in SPIN, and "cnt" will probably overflow, as you described.

    A delay of 50 mys = 4000+cnt will result in a 140 mys cycle which explains your reading of "7"

    Post Edited (deSilva) : 6/26/2007 9:41:05 PM GMT
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-06-26 21:57
    Richard,

    What the scope trace shows is that you have no more than 160uS (possibly less, depending on the flash duration) to read all eight sensors; otherwise you could miss the flash. You can't do this in Spin. You will have to write an assembly routine, as Tracy suggested, to read the sensors and determine if a flash has occurred and from which direction.

    The TSL230 recovery time is one output cycle, by the way. There's no latency beyond that. The 5 uS pulse width I mentioned was a threshold I used to trigger the scope. You could do something similar in your assembly program. If any pulse is less than X uS wide, there's been a flash. The direction will correspond to the sensor that produced the narrowest pulse.

    -Phil
  • RichardFRichardF Posts: 168
    edited 2007-06-26 22:23
    Phil,
    I understand what you are saying.

    PushingSpin as much as I can for now:

    PUB freqOut
    ctra[noparse][[/noparse]30..26] := %00100
    ctra[noparse][[/noparse]5..0] := 15
    frqa := 112_367 'by formula for freq in NCO mode -> freq ~ 2,093
    dira[noparse][[/noparse]15]~~


    PUB measFreq
    repeat
    ctra[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16
    frqa := 1
    phsa~
    waitcnt(clkfreq/100 + cnt) '1/100 sec measure period
    dc := phsa

    This yielded a phsa 0f 21

    Richard
  • rokickirokicki Posts: 1,000
    edited 2007-06-26 23:06
    Try the following after the phsa~ line:

    hival := 0
    curphs := phsa
    repeat 10000
       newphs := phsa
       delta = newphs - curphs
       if delta > hival
          hival := delta
       curphs = newphs
    term.dec(hival)
    
    



    This runs the accumulation in a loop; each loop execution will be roughly the same amount of
    time (and probably on the order of 100us or something each). Note we don't reset phs because
    doing so may mean we miss the pulse that just caused it to bump up a lot! This gives you a bit
    more time to fire off the flash and see how many pulses you can get max. Compare it with the
    same thing when you *don't* fire off the flash. They should be *very* different.
  • RichardFRichardF Posts: 168
    edited 2007-06-27 10:20
    rokicki,
    I like your idea of accumulating phsa as opposed to a reset. I now have a single TSL 230 up and running using the following Spin method to measure light energy into the 230:

    PUB measFreq
    repeat
    ctra[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16 'TSJ230 input
    frqa := 1
    phsa~
    waitcnt(clkfreq/100 + cnt) '1/100 sec measure period
    dc := phsa 'freq = dc*100

    I have the 230 set on highest sensitivity and divide-by 100 scale. I am going to get a full set of light readings as the day progresses and then into the night and adjust my scale accordingly. I also will try and capture a flash today.

    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-27 11:10
    I now have some data points attempting to capture a flash bulb light source. I have the TSL230 set for max sensitivity and no divide-by scaling (max frequency out 1 mhz). The following is the current capture method:
    Note, read time is set at 1 ms.

    PUB measFreq
    freq[noparse][[/noparse]0] := 0
    repeat
    ctra[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16
    frqa := 1
    phsa~
    waitcnt(clkfreq/1000 + cnt)···················· '1/1000 sec measure period
    if phsa > freq[noparse][[/noparse]0]
    · freq[noparse][[/noparse]0] := phsa····································'freq[noparse][[/noparse]0] sent to LCD readout

    The first test used low ambient light conditions giving a freq[noparse][[/noparse]0] of 7. The flash from my camera was capured at freq[noparse][[/noparse]0] = 175.
    The second test was with an ambient reading of 903 (turned the reading lamp on). I was able to capture that flah with a reading of 1327. Pretty encouraging so far, but I realize I have a long way to go to monitor 8 230's for a flash. I like the idea of using 4 cogs and 8 counter modules. Rokicki's idea of not reseting phsa will be tried next.

    Thanks again,
    Richard

    Post Edited (RichardF) : 6/27/2007 11:19:16 AM GMT
  • RichardFRichardF Posts: 168
    edited 2007-06-27 11:38
    I just ran the following (using rokicki's loop):

    PUB measFreq | curphs, newphs, delta
    freq[noparse][[/noparse]0] := 0
    ctra[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16
    frqa := 1
    curphs := phsa
    repeat
    · newphs := phsa
    · delta := newphs - curphs
    · if delta > freq[noparse][[/noparse]0]
    ··· freq[noparse][[/noparse]0] := delta
    · curphs := newphs

    It worked giving me results of 64 flash in 9 ambient and 64 flash in 32 ambient. How long does the loop take and how much time in the loop is dead (non-capture) time?
    Thanks,
    Richard
    p.s. this is why a microcontroller hobby is some much better than programming games on a PC!

    Post Edited (RichardF) : 6/27/2007 11:43:22 AM GMT
  • RichardFRichardF Posts: 168
    edited 2007-06-27 12:14
    This is the way I would work two sensors into a cogs' a and b counters:

    PUB measFreq | curphsa, curphsb, newphs, delta
    freq[noparse][[/noparse]0] := 0
    freq := 0
    ctra[noparse][[/noparse]30..26] := %01010
    ctrb[noparse][[/noparse]30..26] := %01010
    ctra[noparse][[/noparse]5..0] := 16
    ctrb[noparse][[/noparse]5..0] := 17
    frqa := 1
    frqb := 1
    curphsa := phsa
    curphsb := phsb
    repeat
    · newphs := phsa
    · delta := newphs - curphsa
    · if delta > freq[noparse][[/noparse]0]··········································· 'increase due to incoming light pulses
    ··· freq[noparse][[/noparse]0] := delta
    · curphsa := newphs

    · newphs := phsb
    · delta := newphs - curphsb
    · if delta > freq················································'increase due to incoming light pulses
    ··· freq := delta
    · curphsb := newphs

    Does this look correct to you? I am going to go ahead and get the second 230 wired up and I can see how this works with two sensors detecting a flash and indicationg from what sensor it came from. I can then expand out two at a time until it doesn't work any more. Then it is time for assembly code!

    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-27 15:19
    I now have a fully functioning object for detecting and trapping the highest peak light energy coming into multiple TSL230 Light to Frequency converters. To date I have only tested it with one 230 hooked up to the pins being read, but the overall scheme appears to work fine. Testing with just one 230, I get the following results with my Lumix Panosonic digital camera flash:

    Ambient light max reading 300·phsx units
    Flash·going off 8 ft from sensor 11,400 phsx units

    A soon as I get the other 7 TSL230's hooked up I will publish the results.

    I am putting the 8 sensors in a radial configuration so that a flash going off from any 45 deg segment can be detected and it's approximate direction calculated.

    For those who have helped, thank you.

    Richard

    Post Edited (RichardF) : 6/27/2007 3:54:09 PM GMT
  • rokickirokicki Posts: 1,000
    edited 2007-06-27 17:02
    Congratulations on your success so far!

    Wow, looked at your code, you're doing great!

    I'd use a single subroutine and pass parameters to distinguish them, but other than that,
    things look really good.
  • RichardFRichardF Posts: 168
    edited 2007-06-27 18:58
    Rokicki,
    Thank you. Don't know if Phil and DeSilva have been around. I hope I didn't upset them when I said they were getting over my head. Don't think so. I still have to add a method to come up with dynamic average ambient levels, and then a means of setting a triggering detection threshold above that level. I keep thinking how much harder all this would be if it weren't for the Propeller chip.

    regards,
    Richard
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-06-27 19:09
    Richard,

    I'm still following this thread with interest, and I'm impressed with what you've done so far. Using four cogs overcomes the "it can't be done in Spin" admonition nicely! smile.gif

    -Phil
Sign In or Register to comment.