-No, the duty cycle doesn't matter as long as the outputed pulses are evenly spaced. -The range of the input frequency is from 0Hz(stop condition) to 1kHz(max speed). -Yes, the multiplier is always the same 10. Thanks for your reply RA ----- Original Message ----- From: "Picdude" To: Sent: Wednesday, April 30, 2003 9:10 AM Subject: Re: SPAM: Re: [PIC]: Frequency multiplier? > Couple Q's... > > - Does duty-cycle matter? > - What is the range of the input freq? > - Is the multiplier a fixed value? > > > Cheers, > -Neil. > > > > On Wednesday 30 April 2003 01:00, Reinaldo Alvares scribbled: > > 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. > > Best regards > > RA > > ----- Original Message ----- > > From: "Scott Dattalo" > > To: > > Sent: Tuesday, April 29, 2003 6:09 PM > > Subject: Re: [PIC]: Frequency multiplier? > > > > > On Tue, 29 Apr 2003, Reinaldo Alvares wrote: > > > > What if the duty cycle is not 50%, and say variable? > > > > > > Any square wave can be made into a 50% duty cycle by dividing by 2. In > > > other words, just watch the rising (or falling) edge. Brata's approach > > > still works. This is just another example of a phase accumulator. > > > > > > I haven't been monitoring this thread too closely, but the easiest way to > > > solve this problem for a single channel is to utilize the PIC's input > > > capture and timer 2 outputs. For example, configure TMR1 to capture all > > > rising edges and PR2 to specify TMR2's period. The value stuffed in PR2 > > > is simply multiplicative (and possibly filtered) factor of the capture > > > interval. The fact that someone hasn't suggested this solution implies > > > that either this is for a PIC without these peripherals or there is more > > > than one channel. [but after reading the original poster's request, it > > > appears that only one channel is required -- so maybe there's another > > > reason.] > > > > > > One way to do this in software is like so: > > > > > > In the (high frequency) interrupt routine: > > > > > > CurrentState = IOPort(); > > > rising_edge = (CurrentState ^ LastState) & CurrentState; > > > LastState = CurrentState; > > > > > > if(rising_edge & BIT_n) { > > > rollover = rising_edge_counter; > > > rising_edge_counter = 0; > > > } else > > > rising_edge_counter++; > > > > > > > > > if(freq_out == 0) { > > > toggle_output(); > > > freq_out = Fout_half_period; > > > } else > > > freq_out--; > > > > > > And in the main loop: > > > > > > if (rollover) { > > > Fout_update_period(); > > > rollover = 0; > > > } > > > > > > > > > Where Fout_update_period() scales the period of the output clock to be > > > a multiplicative factor of the input clock. Or more specifically, the > > > periods are scaled. > > > > > > This rather verbose approach is easily scalable to multiple channels. > > > > > > To monitor the rising edges and control the scaled frequency outputs, > > > then something like this would suitable for a high frequency interrupt > > > (e.g. tmr0 rollovers): > > > > > > movf Input_PORT,W ;Read the current > > > xorwf LastState,W ;compare to the last > > > xorwf LastState,F ;Save current as last > > > andwf LastState,W ;Get the rising edges. > > > > > > movwf temp ; > > > iorwf rollovers,F ;Let the main loop know > > > > > > ; before processing the rollovers, > > > ; generate the outputs (this way you'll be less susceptible to > > > ; the jitter incurred with the non-isochronous code that processes > > > ; the rising edges.) > > > > > > clrf FoutToggle ; assume that the outputs aren't > > > ; going to change > > > > > > movf Fout0_period,W ;Get the (half) period in case we roll > > > decf Fout0_ctr,F ;Toggle when this reaches zero > > > ;Check the rollovers - use btf's instead > > > skpnz ;of goto's for isochronous execution. > > > movwf Fout0_ctr ;rolled over, so reset the counter > > > skpnz ; > > > bsf FoutToggle,0 ;and set this bit for below > > > > > > > > > ... same for other outputs > > > > > > ; now update the outputs > > > > > > movf FoutToggle,W > > > xorwf Fout,W > > > movwf Fout > > > movwf Output_PORT > > > > > > ; now process the rising edges. > > > > > > > > > ch0: > > > incf Ch0_ctr ;Assume rising edge did not occur > > > btfsc temp,0 > > > goto re0 ;Handle the rising edge > > > > > > ch1: > > > ... > > > > > > chn: > > > ... > > > > > > > > > > > > > > > return ; or interrupt exit code > > > > > > > > > re0: > > > decf Ch0_ctr,W ; > > > movwf Ch0_period > > > clrf Ch0_ctr > > > > > > goto Ch1 > > > > > > re1: > > > ... > > > > > > > > > ------------ > > > > > > In the main loop, ch0_period and when it becomes non-zero, update the > > > Fout0_period. Again, this is just a detailed explanation of the phase > > > accumulator alogrithm proposed by Breta. > > > > > > Scott > > > > > > -- > > > http://www.piclist.com hint: The PICList is archived three different > > > ways. See http://www.piclist.com/#archives for details. > > -- > http://www.piclist.com#nomail Going offline? Don't AutoReply us! > email listserv@mitvma.mit.edu with SET PICList DIGEST in the body > -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body