> -----Original Message----- > From: Patrick B. Murphy [SMTP:luke631@MTS.NET] > Sent: Wednesday, September 03, 2003 2:47 AM > To: PICLIST@MITVMA.MIT.EDU > Subject: Re: [PIC:] How to monitor a dozen shafts? > > I've never tried to measure periods by monitoring the inputs. In the > few projects where I have counted pulses, for example, where I > monitored a flow meter, I used the Capture or Compare module. I want > to be sure I understand what you mean here, so I want to think about > this for a while longer. I have a hunch that this type of monitoring > would be easier in assembly than in CCS C because of the timing > loops. > It realy boils down to the precision you need. The period of just one tooth on the 16 tooth wheel at 200RPM would be a whopping 188ms, so you wouldn't need to poll the inputs particularly quickly to get a reasonable precision. I don't think you will need to resort to assembly to get a useable result, especialy with a 20MHz clock. Simply set up an interrupt (the CCP module is great for arbitrary rate interrupts with no timer loading overhead) and then check the state of each input. By comparing the current reading to the previous one, you can detect a rising edge, falling edge or static high or low. By running a counter for each input and storing the value on a rising (or falling) edge you can easily and quickly make a multi channel counter. Something like the following should do the trick (only 8 channels, but gives you the idea). You would probably want to add some simple filtering and some code to detect a rollover of the counters etc. As it stands the code executes in around 170 cycles excluding context save etc. (compiled with HiTech PICC). At 20MHz that's just 34us, I would think the 12 channel version with the bells and whistles could be fairly easily made to take under 100us, so a 256us interrupt would be possible with a decent amount of cpu time left for your main loop. HTH Regards Mike unsigned int period[8]; // array to hold period for each input. void interrupt isr(void) { static unsigned int counter[8]; static unsigned char prevState; unsigned char inState; unsigned char pulse; unsigned char chan; unsigned char mask; // check for CCP interrupt if(CCPIF && CCPIE) { // reset interrupt flag CCPIF = 0; // grab snapshot of inputs inState = PORTB; // find any rising edges pulse = (inState ^ prevState) & inState; // check each channel for a rising edge (bit set in 'pulse') mask = 0x80; for(chan = 7; chan--; ) { if( pulse & mask ) { // rising edge found so load period array with the count value period[chan] = counter[chan]; // reset the counter counter[chan] = 0x00; } else { // no rising edge found so increment counter for this channel counter[chan]++; // should check for rollover here } // shift the bit mask to the next input bit. mask >>= 1; } // save current port state for next comparison prevState = inState; } } ======================================================================= This e-mail is intended for the person it is addressed to only. The information contained in it may be confidential and/or protected by law. If you are not the intended recipient of this message, you must not make any use of this information, or copy or show it to any person. Please contact us immediately to tell us that you have received this e-mail, and return the original to us. Any use, forwarding, printing or copying of this message is strictly prohibited. No part of this message can be considered a request for goods or services. ======================================================================= Any questions about Bookham's E-Mail service should be directed to postmaster@bookham.com. -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu