PDA

View Full Version : modulated light detection


GMGoose
07-27-05, 10:50 AM
hi,

i'm trying to do the following:

1. Measure a particular modulated frequency - lets say it pulses 3 Hz at 10kHZ.
2. Count the above frequency over a time span of a 1second.
3. Have the analog signal go through an ADC to interpret the strength - i.e. voltage

I appologize if it seems a lot, but I would be grateful if I had some insight to this problem. I'm using code much like jimturpin to implement the frequency measure. 10kHZ signal from the function generator pined to TA0; output was 50.

ie
code:
: ALL
DECIMAL
BEGIN
TA0 ACTIVE-HIGH
TA0 SET-PWM-IN
BEGIN
TA0 CHK-PWM-IN ?DUP
UNTIL
4 10 */ .
?TERMINAL
UNTIL
;
ALL . 50 50... etc.

review:
my first question is... is there a way to take samples when the source pulse is at 3 Hz? I'm not quite sure how to do that.
second question is to take the output and count/store the frequencies - this process is for our cpu bus. final question... there are more than 1 sensor, so the ADC is to determine which sensor has the most strength. I hope this isnt too much. over and out

Thank you

Grand Master Goose

RMDumse
07-28-05, 01:14 PM
Hi, I need some more information

i'm trying to do the following:

1. Measure a particular modulated frequency - lets say it pulses 3 Hz at 10kHZ.

So to see if I understand, there is a pulse train, with a modulation of 10 KHz, that comes and goes at 3 Hz?


10kHZ signal from the function generator pined to TA0; output was 50.


So here we have a steady 10 KHz with no 3 Hz pulsing. The software will measure the "high" period of the pulses. So at 10 KHz your high pulse period will be half a cycle time. A cycle time will be 1/10,000 or .0001 S or 100 uS. Half 100 uS is 50 uS, so I think the software gave you the answer you were looking for, in uS.

[/QUOTE]
BEGIN
TA0 CHK-PWM-IN ?DUP
UNTIL
[/QUOTE]

Here, while the software works, it is structured with a Program Counter Capture loop, a backwards branch, intended to hold up processing while a result is obtained. So this form is working against your end goal. You will need several parallel processes to get your answers. For instance, you might be using one timer to measure the 10 KHz frequency, and another timer timing the missing gaps between pulses to know what the pause between pulses runs, to know the 3Hz rate. You can't do a BEGIN UNTIL loop around one timers result, and still tend to the other timer.



review:
my first question is... is there a way to take samples when the source pulse is at 3 Hz? I'm not quite sure how to do that.


You might set another timer as active low, and read the low periods. A really long one would be the time between drops in the pulse train.

second question is to take the output and count/store the frequencies - this process is for our cpu bus. final question...

I don't understand what is being said/asked here.

there are more than 1 sensor, so the ADC is to determine which sensor has the most strength.

There are multiple ADC channels, and multiple timers. Can you just dedicate resources across the mix you've got available? Or do you want to bring them all into one set of timers?

GMGoose
07-28-05, 02:33 PM
hi, thanks for responding.

yes that's correct.. there's a pulse train modulated at 10kHz that blinks/flashes 3 times within a second. within those flashes there's no modulated light emitting from the source other than ambient light.
is there a way to adjust the capture sampling rate to coincide with the 3Hz?
our your suggestion how would i implement that?

oh.. sorry about the second part... it was more redundancy in the case a string of varying frequencies was outputed but had a majority count on my particular frequency... in which i could count it and send it to the cpu bus.

there are roughly 3/4 sensors... that are trying to pick up this modulated signal. they are located at the corners of a box frame. the
ADC is for the signal voltage strength.. so it can pinpoint which corner of the frame is dominate... so, is there a way to toggle only the dominate sensor to run the approiate measurements spoken above.

thank you
Grand Master Goose

RMDumse
07-28-05, 02:55 PM
is there a way to adjust the capture sampling rate to coincide with the 3Hz? our your suggestion how would i implement that?

There must be dozens of ways of approaching this problem, some using only processing power, up to using external PLL (phase lock loops) to detect the frequency.

But I still don't get the over all picture. What is it you are trying to detect? Is it the signal presence or absense? Is it the timing of the 3 Hz signal so you can extract a coded stream? or are you looking for phase shifts in the 10 KHz, which would be an entirely different approach.

Basically, if you hook two timers to a line, and scan the timers often enough, you can extract every single bit of timing information, to the point you could retransmit the signal again if you wanted. So an ultimate processor intense approach would be to capture the wave form, and know every time it went high or low. The DSP is fast enough to do that.

there are roughly 3/4 sensors... that are trying to pick up this modulated signal. they are located at the corners of a box frame. the
ADC is for the signal voltage strength.. so it can pinpoint which corner of the frame is dominate... so, is there a way to toggle only the dominate sensor to run the approiate measurements spoken above.

We have paralleled IR sensors in the past. So we had a single input. They usually have a pull up on the output, and switch to gnd when they see a pulse train.

Unless you think the other sensors are going to be full of noise, you might be able to combine the signal into a single input on two timers. If they're really noisy, I'd bring the signals into individual timer pairs.

Another approach is to use a PLL external, and then have it only output when it sees the 10 KHz signal. This would be very much like how the TV remote sensors work. BTW, we've built hardware for such detection. We make a barrel racing timer with lasers, and put a 250 KHz signal on the lasers, in which we used PLL's to capture the signal on the recieving side.

So sorry to ask again, but what is the ultimate result you want to have happen, and I'll try to make a suggestion on what might work.

GMGoose
07-28-05, 04:19 PM
sorry for the confusion...

i'll try my best to explain...

all i need from the dsp is to calculate the frequency that's modulated at 10khz... where i'm lost is:

- 3Hz pulse: only sample when the 10kHz is on.

now for the ADC... it's purpose is primarily for signal strength...
recall i have 4 sensors that located at the four corners of a square frame. i only want to toggle the one with the highest strength -- on cpu bus end this will help address what side of the frame the signal is coming from. everything on the cpu bus is of no consequence. that will be tied up on my end... so no worry.

i hope this helps... really i'm sorry for the confusion

once again thank you very much

RMDumse
07-28-05, 07:28 PM
Oh, if all you need is frequency of the ~10 KHz, then a single timer will do and just read half the pulse, multiply by 2 and invert for frequency. Just test result to be sure it is less than some maximum, which would be the lowest possible frequency. Read high periods, so you can ignore the low periods when the signal isn't there. I'd probably run one signal to one of each of four timers. Start all four conversions, but take the one that has the highest A/D reading. Or take 4 A/D readings then start the conversion on the one with the highest A/D and ignore the other three. How does that sound?

RMDumse
07-28-05, 07:53 PM
Code might look something like this (not tested).

SCRUB

DECIMAL

VARIABLE TA0-RESULT
VARIABLE TA1-RESULT
VARIABLE TA2-RESULT
VARIABLE TA3-RESULT
VARIABLE MAX-RESULT
VARIABLE MAX-LEVEL

: INIT
TA0 ACTIVE-HIGH
TA1 ACTIVE-HIGH
TA2 ACTIVE-HIGH
TA3 ACTIVE-HIGH
;

: MAX-CHK-KEEP
ANALOGIN MAX-LEVEL @ OVER <
IF
MAX-LEVEL !
MAX-RESULT !
ELSE
2DROP
THEN
;

: ALL
0 MAX-LEVEL !
TA0 CHK-PWM-IN ?DUP IF TA0-RESULT ! TA0 SET-PWM-IN THEN
TA0-RESULT @ ADC0 MAX-CHK-KEEP

TA1 CHK-PWM-IN ?DUP IF TA1-RESULT ! TA1 SET-PWM-IN THEN
TA1-RESULT @ ADC1 MAX-CHK-KEEP

TA2 CHK-PWM-IN ?DUP IF TA2-RESULT ! TA2 SET-PWM-IN THEN
TA2-RESULT @ ADC3 MAX-CHK-KEEP

TA3 CHK-PWM-IN ?DUP IF TA3-RESULT ! TA3 SET-PWM-IN THEN
TA3-RESULT @ ADC3 MAX-CHK-KEEP
;

: MAIN
INIT
CR ." MONITOR FREQ"
BEGIN
CR
MAX-LEVEL @ .
MAX-RESULT @ 4 10 */ .
5E6 MAX-RESULT @ S>F F/ F.
?TERMINAL
UNTIL
;

SAVE-RAM
AUTOSTART MAIN

GMGoose
08-02-05, 04:50 PM
sorry I haven't replied, been working in the lab 24/7 last few days. And, it doesn't help being absent minded. I've re-surfaced... anyway. first off want to say thanks for the review. I do have questions about your code.. one particular line in MAX-CHK-KEEP...

ANALOGIN MAX-LEVEL @ OVER <

the code seems to hang itself at this point.. it seems to be asking for a pin argument (i.e. ADC0, etc.)

next question is just for clarification on what i'm looking at the output...
three columns... 1st:max-level,2nd:max-result,3rd: not quite sure -seems to be some form of conversion from the 2nd column.

final question..
using the SCI0 pin to transmit to a serial board is there way to just transmit the high ADC that's toggled ... a simple loop that says which adc is high?

once again thanks for the review

GMG

RMDumse
08-02-05, 07:21 PM
MAX-CHK-KEEP...

ANALOGIN MAX-LEVEL @ OVER <

the code seems to hang itself at this point.. it seems to be asking for a pin argument (i.e. ADC0, etc.)

Okay, since a specific object hasn't been invoked, ANALOGIN isn't in the available dictionary, so we get a question mark. Let's see if we can trick it this way. We execute ADC0 which makes ANALOGIN available for compilation. However in later use, a different object will be selected. I think that will work. (Pls don't skin me if it doesn't. We'll find another way.)

: MAX-CHK-KEEP
[ ADC0 ] ANALOGIN MAX-LEVEL @ OVER <
IF
MAX-LEVEL !
MAX-RESULT !
ELSE
2DROP
THEN
;


next question is just for clarification on what i'm looking at the output... three columns... 1st:max-level,2nd:max-result,3rd: not quite sure -seems to be some form of conversion from the 2nd column.

The value returned by CHK-PWM-IN is an unsigned integer, representing ticks of a 2.5 MHz system clock. This is the same timebase used for PWM output. Each tick of this clock takes 0.4 microseconds. So, the measured pulse time can be computed with the formula
microseconds = N * 0.4
If you measure a pulse input of 25000 decimal, you know that this is 10 milliseconds.

The second colum is the raw reading in system clock cycles multiplied by .4uS per system clock cycle. The conversion is an integer way of multiplying by .4, or put another way, multiplying by 4 and dividing by 10 to compute the integer result without undue loss of precision.

The third colum is the conversion to frequency. 2,500,000 system clock cycles per second and the a period measurement is half the length of the full cycle, high+low period. So I think I may have the 5E6 wrong, and it should have been 1.25E6 (I multiplied by 2 and should have divided by 2). Pls check.


final question..
using the SCI0 pin to transmit to a serial board is there way to just transmit the high ADC that's toggled ... a simple loop that says which adc is high?


I don't know what it means to transmit the high ADC that's toggled. A simple loop to see which A/D is highest can be done like this:

: ADC0123
BEGIN
CR
ADC0 ANALOGIN .
ADC1 ANALOGIN .
ADC2 ANALOGIN .
ADC3 ANALOGIN .
?TERMINAL
UNTIL
; EEWORD

Or if you only want a number saying which is highest, this might be what you want:

VARIABLE AD#

: ADC0123
BEGIN
CR
0
DUP ADC0 ANALOGIN 2DUP < IF SWAP DROP 0 AD# ! ELSE DROP THEN
DUP ADC1 ANALOGIN 2DUP < IF SWAP DROP 1 AD# ! ELSE DROP THEN
DUP ADC2 ANALOGIN 2DUP < IF SWAP DROP 2 AD# ! ELSE DROP THEN
DUP ADC3 ANALOGIN 2DUP < IF SWAP DROP 3 AD# ! ELSE DROP THEN
AD# @ .
?TERMINAL
UNTIL
; EEWORD

I'm sure I could come up with something more elegant, but that should give you a rough idea. We are usually paid for our programming services. Our support is to answer questions, give ideas, etc., and the actual applications programming is the customers ultimate responsibility.