a pic with timer1 gate control would be a perfect fit for this , eg 16f1825
a pic with timer1 gate control would be a perfect fit for this , eg 16f1825
Hi,
Questions:
1) Pulse 2 and 3 both falls within the envelope of pulse 1 but is pulse 3 always trailing pulse 2 or can it equally well be leading pulse 2?
2) Once you've got your PIC doing these measurements, what else (if anything) do you need it to do?
(I ask because quite often around here you come up with a possible implementation only to then get something like: Oh, that's great! Now I need to add this and that and..... - Which may render the initial idea and work useless.
3) Will there always be two pulses or is it possible that one (or both) will be missing?
Here's a bare bones aproach, it expects the pulses to be "in order" and there's no timeout or anything. Both can be easily accommodated for though.
/Henrik.Code:Time1 VAR WORD Time2 VAR WORD Pulse1 VAR PortB.0 Pulse2 VAR PortB.1 Pulse3 VAR PortB.2 Main: GOSUB Measure ' Do whatever with the measurements Goto Main Measure: T1CON.0 = 0 ' Stop Timer TMR1H = 0 : TMR1L = 0 ' Clear timer While Pulse1 : WEND ' Wait until the 60Hz Square wave signal is low before "arming" While Not Pulse1 : WEND ' Now wait for rising edge T1CON.0 = 1 ' Start timer WHILE Not Pulse2 : WEND ' Wait for leading edge of second pulse Time1.HighWord = TMR1H Time1.LowWord = TMR1L While Not Pulse3 : WEND ' Wait for leading edge of third pulse Time2.HighWord = TMR1H Time2.LowWord = TMR1L RETURN
henrik
is there a possibility of tmr1l rolling over after tmr1h read causing an error here ?
and as you say will pulse 3 always lag pulse 2 . I also wonder what sort of resolution is required
Hi Richard,
Yes there is. On some chips (not the 16F648 though, I believe) the timer is dubble buffered so you don't need to worry about it. On chips where it isn't you do need to cater for it by reading TMR1H "on both sides" of reading TMR1L and comparing the result to verify that it didn't roll over.
As I said, the example is a bare bones approach. I didn't want to put too much into it before getting more details.
/Henrik.
Ok,
Sorry I didn’t get back to my issue at hand. I was pretty bummed and just wasn’t feeling it yesterday.
Anyway…
I have two circuits that are identical. They are both clocked with a 60Hz, 50% duty, ~8.2mS pulse width +5 volt going square pulse. Low is 0V, high is 5V. They both need this signal all the time. So for now I’m just using a 12F675 to provide that signal.
With that clock signal running, the two individual circuits each output a +5V square wave of their own, which by itself on a scope, doesn’t look like much but a square wave.
But when you trigger a scope using the leading edge of the 60Hz, 50% duty pulse that the 12F675 is currently generating (and being provided to the clock inputs on the two circuits) and you have one of the other pulses on a second scope channel, you’ll see what is in my drawing, which shows just one circuits output for clarity.
You have the 60Hz pulse with the other square wave nested inside of it. And if you adjust that circuit’s control, the pulse can be moved in relation to the steady 60Hz pulse. The other circuit is identical and does the exact same thing. And yes, it can lead the other circuits pulse (not the 60Hz pulse, both other pusles are always inside of the 60Hz pulse!) or fall behind it, or be right on top of it.
My perfect solution for this would be:
1. Generate the 60Hz 50% duty signal on one pin. Always running. HPWM10 maybe?
2. Trigger a timer off of the leading edge of the 60Hz 50% duty signal (no clue, still haven’t messed with timers!!!)
3. Count until the leading edge of the pulse from the first circuit comes in on a pin, hold that number in a variable.
4. Repeat 2 and 3 a few times to build an average – hold that average in a variable.
5. Trigger a timer off of the leading edge of the 60Hz 50% duty signal
6. Count until the leading edge of the pulse from the second circuit comes in on another pin, hold that number in a variable.
7. Repeat 5 and 6 a few times to build an average – hold that average in a variable
8. Send the measurement from both average variables out via SEROUT.
The future plan is to find out exactly what numbers to expect by spitting them out via SEROUT, once I know the ranges and such, I would build a lookup table using SELECT CASE or something and if the shift in a signal falls within a certain value, send a command out serially. This would be done for both circuits
So: SEROUT serialPin, 4, [circuit1Data, circuit2Data…]
The only timing in this that is critical is the 60Hz pulse must always be there, steady, constant. And of course the measurement itself need to be fairly accurate, with my lookup table I’m planning on building in hysteresis(?) like of
circuit one's variable equals 225, my lookup would handle it as “if x = <230 AND <220 then” – or something like that just to cancel out minor errors.
The signals I am measuring only vary by user input (i.e. turning a knob) and are independent of each other and will be handled by separate lookup tables, so measuring one before the other doesn’t matter, or if they both get measured at the same time. And seeing them change in any fine detail doesn’t matter either, So waiting on a routine to finish or something isn’t a big deal. Mainly its just getting an accurate measurement of the shift between the clock pulses leading edge and each circuits outputs leading edge.
I’d like to do this all on one chip if possible. I was trying to think in terms of the 16F648A because I have them on hand and have used them quite a bit. I’m trying to stay away from having more pins than I need, so I really don’t want to have to use an 18F4550 or something. So if there is something around the same pin count as the 16F648A that can do all this in one chip, great. If not, I can live with the 12F675 and two 16F648A I guess.
As always, thanks to all of you for helping me out!
Respectfully,
Ryan
![]()
I admit to not following the thread carefully; I find it difficult to follow prewritten cade (even my own) and maybe this has already been suggested, but wouldn't it work to:
Monitor two pins for input signal. First indication set TIMER to 0 and FLAG = 1.
Continue to monitor both pins
If "Other" pin indicates, capture TIMER as "elapsed count" variable, reset FLAG, and calculate for average (as the timer starts from 0 on each initial indication, there is no need to worry for rollover or complicated math).
If "Same" pin indicates, reset TIMER and FLAG = 1 (missed second signal indication - count errors if you like).
?
Ryan,
Don't know if you looked at my previous idea or not. It was an initial idea but had some issues (and syntax errors).
Unfortunately you won't be able to use HPWM to generate the 60Hz output signal - it won't go that low in frequency. There are other ways of doing it of course but for now I've been focusing on the measurments. Here's a second attempt based on the same idea as the previous code, this time with a bit more features and it does compile - I haven't tested it though.
/Henrik.Code:Time1 VAR WORD ' Time between leading edge of Pulse1 and leading edge of Pulse2 Time2 VAR WORD ' Time between leading edge of Pulse1 and leading edge of Pulse3 Temp VAR BYTE ' Temporary variable, use at will Trig VAR PortB.0 Pulse1 VAR PortB.1 Pulse2 VAR PortB.2 TMR1IF VAR PIR1.0 Main: GOSUB Measure ' Do whatever with the measurements Goto Main Measure: T1CON.0 = 0 : TMR1IF = 0 ' Stop Timer, Clear Interrupt flag TMR1H = 0 : TMR1L = 0 ' Clear timer Time1 = 0 : Time2 = 0 ' Clear measurments While Trig : WEND ' Wait until the 60Hz Square wave signal is low before "arming" While Not Trig : WEND ' Now wait for the rising edge of the 60Hz signal T1CON.0 = 1 ' Start timer DO '------------------------------------------------------------------------------- ' Do we have a rising edge on Pulse1 input? ' Capture value ONLY if we haven't already done so. IF Pulse1 AND (Time1 = 0) THEN Time1.HighBYTE = TMR1H Time1.LowBYTE = TMR1L ' Make sure TMR1L didn't overflow inbetween reading the high and low byte Temp = TMR1H If Temp <> Time1.HIGHBYTE THEN Time1.HighBYTE = TMR1H Time1.LowBYTE = TMR1L ENDIF ENDIF '------------------------------------------------------------------------------- ' Do we have a rising edge on Pulse2 input? ' Capture value ONLY if we haven't already done so. IF Pulse2 AND (Time2 = 0) THEN Time2.HIGHBYTE = TMR1H Time2.LOWBYTE = TMR1H ' Make sure TMR1L didn't overflow inbetween reading the high and low byte Temp = TMR1H If Temp <> Time2.HIGHBYTE THEN Time2.HighBYTE = TMR1H Time2.LowBYTE = TMR1L ENDIF ENDIF '------------------------------------------------------------------------------- LOOP UNTIL ((Time1 <> 0) AND (Time2 <> 0)) OR TMR1IF RETURN
Bookmarks