On Tue, 6 Jan 2004, Jan-Erik Soderholm XA (TN/PAC) wrote: > Bill Couture wrote : > > > It's actually about 300us out of the 500us between TMR1 > > interrupts. > > And, yes, it does have to be done in the interrupt. > > As noted elsewhere, I could use the TMR1IF flag to poll > > when the PID loop needs to execute, but I found that the > > resultant jitter could be seen (and heard!) in the > > mechanical system. > > Note that it isn't a choice between doing *everything* in > the ISR and doing *nothing* in the ISR (with regard to the > TMR1 iterrupt). > > Let the TMR1IF generate an interrupt (as now). Then in the ISR > just set your own "PID-flag" saying that your PID routine has > to be run now (or rather "soon"). Then leave the ISR and > let your main-loop detect your PID-flag and run the PID > code. During that time, you are able to service other > interrupts like the UART receive interrupt. Make sure that > you make *that* ISR code as short as possible also (just > saving the received byte) so you don't hold up your > PID calculations unnecessarily. Actually, the original code was implemented by using TMR1IF as a "do PID now" flag, no interrupt necessary. I found that the PID *HAD* to be in the interrupt, *IN IT'S ENTIRETY* (otherwise, the part of the PID that was not in the interrupt had to look for it's flag, and there was no advantage to having ANY of the PID in the interrupt). The background loop has a fair amount of processing (none of it time critical), and the jitter associated with getting around to see if the PID flag was set could be seen in the mechanical system (and even heard!). Since the PID is in the interrupt, it runs EXACTLY on schedule. Although, there is some jitter, based on the values in the loop. For example, with PID, Kp, and delta_position all long ints PID += Kp * delta_position; is *MUCH* slower (about a factor of 2) if delta_position is negative intead of positive. In fact, if you do it right, you can save processing time with statements like pos_delta_pos = (current - desired); neg_delta_pos = (desired - current); if (current > desired) PID += Kp * pos_delta_pos; else PID -= Kp * neg_delta_pos; (you do have to be careful that you don't spend more time saving time, but if you're careful you can save considerable time.) Bill -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu