I have a project using three 12F683s controlled by a 16F883 master. The goal of the project is to track the RPM of 4 independant propellers on a quadcopter using an IR photodiode and emitter (i.e. a beam breaker). When the propeller blade crosses between the IR photodiode and emitter, the voltage at the interrupt pin drops to ~0.7V (a 3.3k resistor to GND). When the blade moves out of the way, the voltage at the interrupt pin increases to ~4.8V. The IR setups for the 16F883 and the 12F683s are effectively identical (same wire lengths, same IR components, resistors, etc). The 16F883 drives an 8Mhz xtal osc with the osc2 pin tied to the osc1 pins of the 12F683s (short distance). The 16F883 starts the process and takes a pin high that tells the 12F683s to start logging data. The 16F883 also begins logging data. I opted to use 4 PICs as the props can spin around 9000RPM, which is ~300 interrupts per second (2 blades per prop) and I'm not sure how I'd get it to work with interrupts occuring that frequently and occasionally falling on top of each other.
My problem is that the 12F683s are not that reliable and the data is poor, however the 16F883 seems to be logging the blade interrupts great. Below are 2 examples of a 25 second run:
As is apparent, the 883 is doing great, but the 12F683s are not (data from all 12F683s is similar). The IR max and min voltages are meeting the high/low logic requirements (0.7V low, 4.8V high) and the IR setups are effectively the same for all 4 PICs, so I'm wondering if there's some register or code modification I can do to improve the 12F683 interrupts? Or is this more of a hardware issue between the 16F883 and 12F683?
Below is the code for the 12F683 PICs. The code and interrupt for the 16F883 is similar (identical interrupt routine in fact). Thanks in advance for any help or suggestions!
Dave
Code:'PIC-12F683 #CONFIG __config _FOSC_EC & _WDT_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _CPD_OFF &_FCMEN_OFF &_IESO_OFF #ENDCONFIG DEFINE OSC 8 'Initialize Regsters: TRISIO =%101111 'I or O; MCLR is pin3 CMCON0 = 7 'Analog comparators off ADCON0 = 0 ANSEL = 0 'all inputs digital, the adcin command automatically converts it to analog CCP1CON=%00000000 'disable PWM mode IOC=%00000100 OPTION_REG=%11000000 ' Interrupt on rising edge INTEDG bit, disable internal pullups 'pins and variables EE_DAT var GPIO.1 EE_CLK var GPIO.0 INT_PIN VAR GPIO.2 MODEPIN VAR GPIO.3 'MCLR OUTPIN VAR GPIO.4 'OUTPIN also hooked up to an LED wsave var byte $20 SYSTEM wsave1 var byte $A0 SYSTEM pausetime1 var word pausetime2 var word hbfix var byte ibit var bit n var byte wconfig var byte address var word wbit var bit INCLUDE "DT_INTS-14.bas" ' Base Interrupt System INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler GPC_INT, _PULSE_WIDTH, PBP, yes endm INT_CREATE ; Creates the interrupt processor ENDASM @ INT_DISABLE GPC_INT ; disable external (INT) interrupts wconfig=%10100000 'At 8Mhz with 1:1 prescaler T1CON = %00000000 ' Prescaler = 1:1, timer off low OUTPIN pause 500 waitforstart: OUTPIN=INT_PIN 'toggles LED on OUTPIN to make sure IR sensor is reading high (clear) or low (blade in the way) if MODEPIN=1 then waitforstart high OUTPIN wbit=0 'initial write bit setting to make sure eeprom is written every other interrup TMR1H = 0 TMR1L = 0 ibit=0 address=0 @ bsf T1CON, TMR1ON ' Start timer @ INT_ENABLE GPC_INT ; enable external (INT) interrupts main: if MODEPIN=1 then waitforstart if ibit=0 then main @ INT_DISABLE GPC_INT ; disable external (INT) interrupts if pausetime2.lowbyte=0 then pausetime2.highbyte=hbfix if wbit=1 then I2CWRITE EE_DAT,EE_CLK,wconfig,address,[pausetime1,pausetime2] endif pausetime1=pausetime2 address=address+2 'effectively adding 4 to address between eeprom writes if address=0 then done 'if 0 at this point, rollover of address has occured and eeprom is full wbit=~wbit ibit=0 @ INT_ENABLE GPC_INT ; enable external (INT) interrupts goto main done: input EE_CLK input EE_DAT low OUTPIN pause 10 if MODEPIN=0 then done goto waitforstart '---[INT - interrupt handler]--------------------------------------------------- PULSE_WIDTH: pausetime2.highbyte = TMR1H pausetime2.lowbyte = TMR1L hbfix = TMR1H ibit=1 @ INT_RETURN end


Reply With Quote

Bookmarks