On Wed, 30 Apr 2003, Reinaldo Alvares wrote: > Thanks to all for your answers to my 50% stuff question. > I perhaps didn't explain myself properly or didn't understand your answer > correctly. > Let me please rephrase my question. Let's say I want to multiply the > frequency of an input square wave by some factor "F".Consider a sensor > giving pulses from a rotating shaft, if the shaft accelerates then two > consecutive periods are different. Every next period will be shorter than > the previous one. Now if I divide the first period "P" by "F" and output an > "F" amount of pulses with periods equal to "P/F" then the PIC will still be > outputting pulses while the next period is already happening. I can't loose > counts since I need this for positioning, direction and speed measurement > purposes. I have to watch both edges for any change in the direction of the > shaft.The sensor is a quadrature encoder with only A and B outputs, no Z. I > have to output two channels out of phase by ~90% to the system processing > the data.The phase difference is naturally the same as the incoming pulse. I > have managed to do it for a fixed or slow variable frequency.I implemented > it in software on an 16F84A, I know they are outdated, but I have lots of > them!. When the shaft accelerates fast then I start to miss about 3 to 10% > of the pulses depending on the acceleration, getting offsets in > position.When the shaft is slowing down then is ok because the next period > will be longer. There will be space enough in time to accommodate the > multiplied pulses before the next ones will have to be outputted. I might be > missing something here, I don't know what a phase accumulator is but I'll > try to find out. It looks to me that this task is just not possible to fix > on a base of period by period multiplication. I appreciate very much any > advise or pointer to how to solve this. And sorry for taking this thread, I > didn't mean to. Okay. There are two pieces of information that are being manipulated. There's the frequency *and* there's the pulse width. The phase accumulator approach can still be made to work. The job would be *so* much easier to accomplish with a better endowed PIC than the lowly f84... 1) Measure the input period, i.e. time between rising edges 2) Measure the input pulse width, i.e. time between a rising and falling edge. 3) Scale the input period and input frequency to produce the output period and frequency. The hard part (with an f84) is sampling the signals fast enough. Here are some snippets to help: Edge detector: movf IOPORT,w ;sample the incoming signal xorwf last_sample,w ;compare to the last sample andlw IOBIT ; skpnz ;If they're the same then no need to goto no_change ;process xorwf last_sample,f ;Save this sample for next time andwf last_sample,W ;Is this a rising edge? skpnz goto falling_edge rising_edge: ... goto no_change falling_edge: ... no_change: ------------------ Now to generate the scaled pulse output, I'd use phase shifted counters: http://www.dattalo.com/technical/theory/pwm.html The periods of the rising and falling edge counters are the same and equal the scaled frequency output. The relative phase shift corresponds to the desired pulse width. See http://www.dattalo.com/technical/software/pic/pwm8.asm for example of 8 parallel PWM outputs that use this technique. For a single channel, there several optimizations one could make. Scott -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body