PDA

View Full Version : Help with Analog Interrupt



brid0030
- 12th February 2008, 20:20
Ok. After several hours of searching. I gotta ask for some help. I’m a biologist, not an electronics engineer or a programmer, so I have trouble making sense of datasheets, defining registers, writing assembly code, and all of that other stuff that PBP usually takes care of. Despite my caveman ineptitude I have managed to put together several devices that have been useful in my field work—mainly things like data-loggers.

I’m now working on a very simple data logging device that stores a time stamp whenever an external sensor is triggered. Basically the PIC could be asleep most of the time and wake up only to write a timestamp from an external real-time clock to an eeprom memory IC. Right now the external trigger is just a switch, and I am monitoring it by polling a pin with IF statements . However, the time during which the switch will remain high (triggered) could be very short, so I have to poll the switch every 10ms to make sure I don’t miss something (and the PIC does not get to sleep).

This application obviously calls for an interrupt, and I think I have found the resources I need to pull this off when using a simple on/off digital input. But, I would like to replace the switch with a flex sensor to eliminate any moving parts and corroding contacts (the device will have to live outdoors). This brings me to my first question:

The flex sensor gives an analog input, and although I believe it is possible for analog inputs to trigger interrupts, I can’t locate any resources to help me make it work, to say nothing of adjusting the sensitivity (i.e. the magnitude of the change in voltage that will cause an interrupt). Does anybody know of code examples or explanations that touch on interrupts triggered by analog inputs through the analog/digital converter (or comparators)?

My second question has to do with using “ON INTERRUPT” vs assembly language. I think either would work (my timestamps do not have to be exact, so latency should not be an issue), I would like to use ON INTERRUPT because that’s where I am on the learning curve, but I don’t want to miss any events that should trigger the interrupt. When you use ON INTERRUPT, does the PIC constantly monitor for an interrupt, or does it only poll the interrupt port at the end of each command? For example if you have a 1000ms pause and an event occurs 100 ms into the pause but ceases 900 ms into the pause, is the event missed? If so, suppose I will need an asm interrupt or very short pause periods.

I am using a PIC16F688 for now, but could switch to something else if need be. My instincts tell me that the solution to this problem will involve PIR1, the PERIPHERAL INTERRUPT REQUEST REGISTER 1:

bit 7 EEIF: EEPROM Write Operation Interrupt Flag bit
1 = The write operation completed (must be cleared in software)
0 = The write operation has not completed or has not been started
bit 6 ADIF: A/D Interrupt Flag bit
1 = A/D conversion complete
0 = A/D conversion has not completed or has not been started
bit 5 RCIF: USART Receive Interrupt Flag bit
1 = The USART receive buffer is full
0 = The USART receive buffer is empty
bit 4 C2IF: Comparator 2 Interrupt Flag bit
1 = Comparator 2 output has changed (must be cleared in software)
0 = Comparator 2 output has not changed
bit 3 C1IF: Comparator 1 Interrupt Flag bit
1 = Comparator 1 output has changed (must be cleared in software)
0 = Comparator 1 output has not changed
bit 2 OSFIF: Oscillator Fail Interrupt Flag bit
1 = System oscillator failed, clock input has changed to INTOSC (must be cleared in software)
0 = System clock operating
bit 1 TXIF: USART Transmit Interrupt Flag bit
1 = The USART transmit buffer is empty
0 = The USART transmit buffer is full
bit 0 TMR1IF: Timer1 Overflow Interrupt Flag bit
1 = Timer1 register overflowed (must be cleared in software)
0 = Timer1 has not overflowed

krohtech
- 12th February 2008, 22:41
You might have a look at Darrel's DT_INTS-18 if you ues a 18F pic you can use the AD_INT -- A/D Converter interrupt.

EDITED see below EDITED

krohtech
- 12th February 2008, 22:54
I actually just checked and you can use the AD_INT -- A/D Converter Interrupt in his 14 bit version as well... So you don't have to use an 18F

Thanks Darrel

http://darreltaylor.com/DT_INTS-14/intro.html

Dave
- 13th February 2008, 12:00
brid0030, Why not look for a PIC that has an analog comparator with an interrupt available. That way the PIC can sleep indefinitely untill the voltage comparator is triggered at which time you can wake and make a measurement then time stamp the data and, back to sleep...

Dave Purola
N8NTA

Bruce
- 13th February 2008, 12:48
The A/D interrupt fires when an A/D conversion is complete. This is handy for entering sleep mode, and having the PIC wake up when the A/D conversion is complete. With the oscillator shut down during sleep, you get much more stable A/D readings.

The comparator can also wake the PIC from sleep on change of a comparator output. This would work too, but I would check the Electrical Specifications section of the data sheet for current draw.

A/D, comparator, Vref, WDT, etc,, they all draw current during sleep. Which one is best depends on your power budget, and application. Wake up on comparator output change would probably let the PIC sleep for longer periods.

This PIC also has an ultra low-power wake-up option if you really need to squeeze power consumption down during sleep. Look for AN879 on the Microchip site.

brid0030
- 13th February 2008, 14:39
Thanks for these suggestions. I'm still not clear how to implement them, but I have some direction for future reading. It sounds as if using "ON INTERRUPT" is generally to be avoided. I'm still not sure whether it will miss events that start and end during a long command, but it definitely would not provide the most elegant solution.

I've looked into Darrel Taylor's interrupt system, and will have to do some more research before I can grasp what is going on. Using the ultra-low-power wake up module is quite tempting. I use a large external battery so power consumption is not that big an issue, but why not save as much as possible? I don't know how to implement the module, but there is some asm code in application note AN879 (http://ww1.microchip.com/downloads/en/AppNotes/00879C.pdf), so perhaps I can start there. If anyone has ever used the low-power wake up, I would love to see some examples.

Bruce
- 13th February 2008, 15:36
Here's something to start with. I've converted the assembler example in the app note to PBP for you with one exception. It does not use interrupts. This just uses the ultra low-power wake-up feature to wake from sleep. Global interrupts are disabled.

With a 10K / 1uF RC network on RA0, it wakes up & toggles RC5 ~ once every 34 seconds.


@ device pic16F688, intrc_osc_noclkout, wdt_off, mclr_off, protect_off
' Note: Default internal osc is set to 4MHz

SleepyTime:
'BCF STATUS, RP0 ;Bank 0
'BSF PORTA, 0 ;Set RA0 data latch
PORTA.0 = 1

'MOVLW H’7’ ;Turn off
'MOVWF CMCON0 ;comparators
CMCON0 = 7

'BSF STATUS, RP0 ;Bank 1
'BCF ANSEL, 0 ;RA0 to digital I/O
ANSEL.0 = 0

'BCF TRISA, 0 ;Output high to
TRISA.0 = 0

'CALL CapDelay ;charge capacitor
PAUSE 100 ' change to suite your RC circuit

'BSF PCON, ULPWUE ;Enable ULP Wake-Up
PCON.5 = 1

'BSF IOCA, 0 ;Select RA0 IOC
IOCA.0 = 1

'BSF TRISA, 0 ;RA0 to input
TRISA.0 = 1

'MOVLW E’10001000’ ;Enable interrupt
'MOVWF INTCON ;and clear flag
INTCON = %00001000 ' Note bit 7 is clear since we're not vectoring to an int handler

'SLEEP ;Wait for IOC
@ SLEEP

INTCON.0 = 0 ' clear int flag on wake-up

Main: ' Do whatever you need here on wakeup
' insert your code here

TOGGLE PORTC.5 ' do your stuff here before entering sleep mode again
GOTO SleepyTime ' do the ultra low-power wake-up thing again afterwards
END
An interesting note on this one is that is works whether you clear the int flag or not!

brid0030
- 13th February 2008, 18:14
Above and beyond, Bruce. You are the greatest.