Searching \ for 'Frequency Multiplier' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=frequency+multiplier
Search entire site for: 'Frequency Multiplier'.

Truncated match.
PICList Thread
'Frequency Multiplier'
1999\05\09@045415 by erik

flavicon
face
Hello all.

I'm working on a project where I'm simulating a machine that we are
collecting a bunch of data from.

The little gadget would have to be configurable via switches to output a
50% duty cycle pulse at various
frequencies.
The maximum frequency would be about 71kHz. That means that I must
evaluate the configuration switches,
check a timer/counter, and turn on an output, plus execute the rest of
the program in about 72 instructions.
(that's if there are no jumps or gotos)

It's becoming pretty clear that I just won't be able to do it.

This output is to simulate an encoder and all other outputs must be "in
tune" with this encoder (machine speed) This requirment would seem to
rule out using 1 microcontroller for the encoder signals and another for
the rest.

So, If I was to give an output pulse at say, 1/10th of the desired
frequency, is there a frequency multiplier of some sort that I could use
for an application like this? I'd like the PIC to output a 7.1kHz pulse,
and do a bunch of other neat stuff, and use another IC or circuit to
multiply the 7.1kHz signal by 10.

Erik

1999\05\09@161521 by Mark Willis

flavicon
face
Afraid I'm not all that good on Analog or RF (It's just been too
long), Erik;  Some thoughts to get the list shooting me down here <G>

 I quote from Richard Martin's post of April 7th:
> The NE602 part (and it's 'kin) is usually used in RF circuits
> but it includes (in part) a 'Gilbert Cell Multiplier' which
> is (over SOME range of inputs) an analog multiplier with
> fairly good specs (and cheap, since NE602s are ~$2.00).
> <snipped>
> Thanks:  <Probably should reply to ME ONLY spam_OUTrmmartinTakeThisOuTspamserv.net>

 Philips Semiconductors makes this part (aka SA602A), Questlink.com has
data on it as well, for a .pdf file hit
http://www-us2.semiconductors.philips.com/acrobat/datasheets/SA602A.pdf.

 Works to 200MHz from a quick glance.  Sounds like a place to look.
And a person to ask <G>  DIL-8 or SOIC-8 package.  You may have to go to
a powers of 2 style multiplication, i.e. multiply Sin(a) * Cos(a) to get
output == Sin(a*2);  I'm not sure offhand, this AM, how to get Sin(a*5)
with trig. identities, but I'm sure you can do 3 2x multiplies in a row,
to get 8x, that should do you?  Maybe you can figure a way to do 5x,
though, as odd multiples are so easy to get from square waves! <G>

 Another thing to think of is PLL's, and how radio IF's and so on
work;  NE564's work up to 50 MHz, could you mix an oscillator output
just below your LOWEST desired frequency with the PIC output & then high
pass & feed the upper component of that into a PLL to give you a nice
clean output?  Or "Kick" the PLL at the right time each pass through the
output wave, to sync it up with you?  (Schmidt or comparator the output
of the PLL, as needed to give you your 50% result.  A comparator with 1
input direct to a sine wave source & the other input on that same
signal, low pass filtered through a RC filter, can do a good job of
making your sine wave become a 50% duty cycle square wave;  Throw a
couple 1N4148's in there across the R, to pull the cap up to about 50%
faster, if needed.)

 Would lookup tables / Magic Sines be one possibility here?  (Fed into
a PLL perhaps.)  Probably not, sounds like.  Also royalties may be a
hardship there?

 (I'm hoping someone who's better on RF/Analog helps you here <G>)

 Mark

erik wrote:
{Quote hidden}

1999\05\09@163416 by Roland Andrag

flavicon
face
Eric, I don't know which pic you are using, but you should be able to run
Timer0 (I think) to generate an interrupt whenever your output has to change
from high to low. This means that your frequency generating code will run in
the background, driven by the interrupt, leaving you clear to run your other
code in the foreground.

Otherwise you are probably looking at implementing a phase locked loop to be
able to multiply the frequency, which gets a little tricky.

Your interrupt routine would basically do the following:
1. Save registers etc.
2. Change output state of pin to generate frequency.
3. Reset interrupt flag(s)
4. Reset timer0 so that it will generate the next interrupt when the signal
needs to change again
5. Restore registers etc
6. Return

Steps 2 to 4 can be shuffled to suit you. Perhaps put step 4 where step 2
is - makes timing easier to calculate.

Using the interrupt has the advantage that you don't have to 'tune' your
code to achieve the correct delay - only the interrupt routine. You should
be able to get within 1 clock cycle of the required delay. The only
limitation is that the interrupt routine should be finished by the time the
next interrupt occurs.

Hope that helps (scream if you need more info)

Cheers
Roland
{Original Message removed}

1999\05\09@175855 by erik

flavicon
face
Roland,
I've been giving this alot of thought but don't think I can do things
entirely with an interrupt on
TMR0 rollover.  I would like to simulate a printing press running at
3000 ft/min which would require a pulse
once every 43usec with a 2500 pulse encoder.  There are other signals
whose frequency is directly
proportional to the press speed.  I could have TMR0 overflow at 43usec
and in the ISR I would turn on the
"encoder output".  Three switches would be used to set the "press speed"
and would directly correlate
to the prescaler bits. This way, if all timing was based on the TMR0,
the whole "machine" would slow
down.

My problem is: that on some machines (and therefore my simulator) there
are 2500 and 1200 pulse per rev encoders and
either a 2:1 or 4:1 shaft to encoder ratio. To facilitate this
functionality I think I would need a routine
independent of the interrupt that determines if it is time to turn on
the "encoder output" based on the
"machine configuration" ie. configuration switches.

My original intent was to have TMR0 interrupt every 1 msec as a means of
incrementing a "global timer register". The various routines in the
program would then check with the "global timer" to see if it was
time for an output. The "global timer" could easily be slowed down and
all the machine functions would
slow as well.  Unfortunately I've found that with a press speed of
3000ft/min with a 4:1 1200 pulse encoder
I'll need to output an encoder pulse once every 23 usec.  At 20MHz OSC I
could load the TMR0 with 141 so that
115 cycles would generate an interrupt at 23 usec. Now keeping track of
the machine speed has become more
difficult. There is a once per revolution pulse from paper roll that
obviously is dependent on the machine
speed but also has to increase in frequency as the paper roll gets
smaller. That part is easy enough if I can
establish a "metronome" or "heart beat" of the machine. I'm just not
sure how I'd do that if my "heart beat"
changes with different encoder configurations.

23usec pulse at [(1200 pulse/rev)*4] and
43usec pulse at [(2500 pulse/rev)*1]
both = 3000ft/min
depending on which machine configuration I'd like to simulate.
i.e. while the encoder output pulse changes with the configuration
switches, the other signals must not.
All this said, am I correct in thinking that I cannot manipulate the
"global timer"/"heartbeat". Instead I must establish a "heartbeat" and
change the encoder frequency for different configurations.

Maybe I'm just not thinking sneaky enough. I'm still very new at this.

And Mark,
Thanks for the URLs. I'm pretty sure I've no idea what you were talking
about. :) I've never worked with...
well, I've never worked with lots of stuff. I'll take a look at them and
see if I can figure it out. Thanks.

Erik

Roland Andrag wrote:
{Quote hidden}

> {Original Message removed}

1999\05\09@185640 by paulb

flavicon
face
erik wrote:

> The maximum frequency would be about 71kHz.  That means that I must
> evaluate the configuration switches, check a timer/ counter, and turn
> on an output, plus execute the rest of the program in about 72
> instructions. (that's if there are no jumps or gotos)

 That sounds like a 20MHz PIC.

> It's becoming pretty clear that I just won't be able to do it.

 This, Erik, is called "programming".  It's actually quite easy once
you get the hang of it. ;-) Your mistake is to assume you must do all
these things on *every* pass of the timing loop.

 Once you drop this assumption, you think in terms of getting the
timing loop done in a certain number of instructions with a few left
over.  You now use those instructions do do *part* of the non-critical
routines each time you do the timing job.

 You may either call the frequency generation code as a subroutine
regularly through the other code, or use a state-machine dispatcher
which returns to the timing code.  The PIC is very much "purpose-built"
to run isosynchronous code.

 I presume the timing code will use a phase accumulator type synth?
--
 Cheers,
       Paul B.

1999\05\09@192318 by Scott Dattalo

face
flavicon
face
On Sun, 9 May 1999, erik wrote:

> Hello all.
>
> I'm working on a project where I'm simulating a machine that we are
> collecting a bunch of data from.
>
> The little gadget would have to be configurable via switches to output a
> 50% duty cycle pulse at various
> frequencies.
> The maximum frequency would be about 71kHz. That means that I must
> evaluate the configuration switches,
> check a timer/counter, and turn on an output, plus execute the rest of
> the program in about 72 instructions.
> (that's if there are no jumps or gotos)
>
> It's becoming pretty clear that I just won't be able to do it.

Why?

{Quote hidden}

Erik,

You may wish to consider something like a 'co-routine'. Knuth discusses
them at length in "The Art of Computer Programming" (though I don't recall
which volume) and there was an article within the last year in 'Embedded
Systems Programming'. But basically, a co-routine is like multitasking
with just two tasks. It seems like you could divide the two tasks into 1)
Frequency synthesis and 2) Everything else.

For the frequency synthesis, I'd suggest phase accumulators. A sixteen-bit
phase accumulator would be more then adequate for your application.

I don't have time to think through the pic code, but this psuedo code
should convey the idea:

phase_accumalator = 0;    // No phase initially
clear_output();

loop1:

read_switches();

phase_chunk = phase_given_switch_setting[switch_setting];

update_output();

switch(task_state)
{
 task1:
   do_stuff1();
   break;
 task2:
   do_stuff2();
   break;
 task3:
   do_stuff3();
   break;
 task4:
   do_stuff4();
   break;
}

task_state = (task_state + 1) & 3;

goto loop1;


update_output()
{
 phase_accumulator += phase_chunk;

 if(phase_accumulator rolled over)
   toggle the output;

}


The trick though is to break the tasks into equal sizes. In other words,
the phase accumulator assumes that the time between phase adjustments is
constant. But I think you were faced with a similar problem at the outset.

I presume your running a pic with a 20Mhz clock (because (20MHz/4)/71kHz =
70.4 instructions per cycle).

It only takes 8 (or 10) instructions to do the phase accumalation and
bit-toggling:


    movf   phase_chunk_lo,w
    addwf  phase_accumulator_lo,f
    movf   phase_chunk_hi,w
    skpnc
     incfsz phase_chunk_hi,w
      addwf phase_accumulator_hi,f

    rlf    known_zero,w   ;get the rollover
    sublw  0
    andlw  BIT_POSITION
    xorwf  portx,f


Or if you make the frequency output at the LSB (or MSB) of the I/O port,
then this will work in place of the last 4 instructions:

    rlf    known_zero,w   ;get the rollover
    xorwf  portx,f        ;toggle output on rollover


So if you adjusted your timing such that you ran the phase accumulator
algorithm 4-times for the 71kHz period, then you would have about 70 - 32
or 38 cycles for looping, task switching, and task execution. Now, since
the phase accumulator code is so short, you might as well repeat it
whenever it is needed (saving 4 cycles for the call/return over head). The
looping and task switching take at worst 10 cycles. That leaves 28 or so
cycles for all of your mini-tasks.

Challenging, but doable.

Scott

1999\05\09@194443 by Mark Willis

flavicon
face
Erik, Roland's approach sounds probably easier for you to do then.
(Beware, girlfriend's interrupting me a lot today so I'd rather scream &
run, I think.  I may look a little more distracted than average,
here...)

 To build a real time operating system like this, the usual approach is
to do this (Time-Slicing Real Time OS idea;  Pseudo-Code warning <G>):

 Setup_Task1();
 Setup_Task2();
 Setup_Task3();
 Main_Loop:
   Do_Part_of_Task1();
   Do_Part_of_Task2();
   Do_Part_of_Task3();
   Do_Short_Delay();
 goto Main_Loop;

 The main idea here is to split each task into little tiny "time slice"
pieces - i.e. the first time you call Do_Part_of_Task1(), for example,
it just does one small part of it's job - the next time through it does
the next part of it's job, and so on.  Something like:

Proc Do_Part_of_Task1()
{
 Static Int WhichSlice1=0;  /* Initialize only at startup, not with
each call to this procedure <G> */
 Const n = 3; /* number of total time slices for this task, arbitrarily
3 here. */

 WhichSlice1 = (WhichSlice1 + 1) mod n;
 Case WhichSlice of
 {
    1:  Do_Task1_TinyPart1(); break;
    2:  Do_Task1_TinyPart2(); break;
    3:  Do_Task1_TinyPart3();
 }
};

 Task1TinyPart1 could do the first half of a math calculation, part 2
could do the next half, part 3 could do a comparison to check & see if
it's time to flip an output bit - for something somewhat specific here.
Do feel free to use more than 3 slices, too!  (In avionics, for example,
you commonly test ALL CPU instructions, regularly, so TinyPart1 might
test a register increment instruction, TinyPart2 a register assign,
TinyPart3 a register decrement, TinyPart4 a Jump instruction, and so on
and on, probably 100 slices or more <G>

 Task 1 could be "check if it's time to flip the 43uSec pulser".  Task
2 could be some other pulser.  Task 3 could be "see if the paper roll's
turned another turn", and could gradually increase or decrease the Paper
Roll Diameter variable, to suit the radius of the paper roll.  The
problem can be figuring out how to do things just right, the first time
<G>

 You can also do this in two ways, "Isochronously" or "Synchronously";
The first means you have routines that take different numbers clock
cycles to run through, so you need a synchronizing delay loop in
Do_ShortDelay() to sync everything up to the (Timer) heartbeat;  The
second would be needed if you're way low on CPU resources, you make sure
that whatever happens your program takes the exact same number of cpu
cycles to do it's job, then you don't have any delay loop;  Harder to
do, but if you need the cycles to all do processing not overhead, you
need it.

 There is no "Wrong" way to do something like this, so long as your
code works, it's "right".  Do it the way that makes sense to you!

 Mark

erik wrote:
{Quote hidden}

> > {Original Message removed}

1999\05\09@211223 by Thomas McGahee

flavicon
face
----------
> From: erik <.....erikKILLspamspam@spam@NETWURX.NET>
> To: PICLISTspamKILLspamMITVMA.MIT.EDU
> Subject: Re: Frequency Multiplier
> Date: Sunday, May 09, 1999 5:58 PM
>
> Roland,
> I've been giving this alot of thought but don't think I can do things
> entirely with an interrupt on
> TMR0 rollover.  I would like to simulate a printing press running at
> 3000 ft/min which would require a pulse
> once every 43usec with a 2500 pulse encoder.

--big snip to keep bandwidth low --

Erik,
why don't you take the output of the encoder and divide it externally
before applying it to the PIC? Quite often I add a cmos 4020 or 4024
or 4040 binary divider to my high speed inputs to 'tame' them down a bit.

The dividers have outputs that divide the input by 2 4 8 16 32 all the
way up to 2^14. Very handy, and dirt cheap.

Hope this helps.
Fr. Tom McGahee

1999\05\10@115116 by Roland Andrag

flavicon
face
Erik,

The way understand it now you need two signals:
1. A signal that occurs say 2500 times per revolution of the press;
2. A signal that occurs once per rev.

To generate the first, use a tmr0 ISR that occurs whenever you need to
change the output, ie. 5000 times per rev. for a 2500 pulse/rev encoder;

To generate the second, use a 16 bit counter that you decrement from your
ISR from a value of 2500 down to 0. When 0 is reached, change your 1 pulse
per rev output and reset the counter.

To set the press speed, modify the value of Tmr0 so that it rolls over after
a different speed.  To compensate for the roll getting thinner, do the same.
To use different encoder ratio's, modify the value from which the 16 bit
counter counts down and tmr0 reset value. What else was there? To modify the
encoder ratio, modify Tmr0's reset value and the 16 bit counter value to
represent the amount of pulses per rev.

Sounds like lookup tables to me, especially considering the thinning roll...

Have fun, hope that's clear and that I understood you correctly...

Roland

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...