PDA

View Full Version : Won't go back to SLEEP after 1st Interrupt



jellis00
- 16th June 2009, 23:33
Usin PIC16F690 in PICkit2 LPDM board with PBASICPro. My below listed code places the MCU into SLEEP mode after powerup as intended. I confirmed this by connecting an ampmeter and it reads only 400 uamps on powerup after executing the sequence at the Main label thru the @SLEEP statement. However, after the 1st interrupt is received and it is awakened, it doesn't go back into deep SLEEP after the Int_handler is completed. I can see this as confirmed by the ampmeter reading of 2.2 mAmps after the interrupt. The way my code is structured, once the Int_handler is serviced and it resumes back to the Main label, it should go back into deep SLEEP and only be consuming 400 uamps again.
Can anyone see why it isn't going back into SLEEP mode after the interrupt as intended?
---------------


' -----[ Device Declaration ]----------------------------------------------
'
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
' For PM assembler only use following instead
'@device pic16F690, intrc_osc_noclkout, bod_off, pwrt_off, wdt_off, mclr_off,
' protect_off

' -----[ Revision History ]------------------------------------------------
' Version 1.0.4 on 6/16/2009: Includes changes to minimize power during Sleep

' -----[ Declare Variables & Aliases ]-----------------------------
'
diff VAR Byte ' Difference between bat_mon and Vthr
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing
led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery
bat_mon VAR PortA.0 ' Set RA0 as battery low power monitor
meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt
open_valve VAR PORTC.2 ' Set RC2 as valve solenoid open command
close_valve VAR PORTC.3 ' Set RC3 as valve solenoid close command

' -----[ Declare Constants ]----------------------------------------
'
k CON 10 ' Calibration factor for flow meter...# pulses per gal
Vthr CON 3 ' Assumes Low Battery Monitor threshold = 3 volts

' -----[ Initialization ]--------------------------------------------------
Init:
' Setup Timer0 as an 8-bit counter with the clock input on RA2.
' 1:1 TMR0 prescaler
' TMR0 counts on high-to-low transitions
OPTION_REG = %00111000 ' PORTA pullups disabled, TMR0 clock source is RA2,
' high-to-low transitions, prescaler to TMR0
TMR0 = 256 - k ' preload TMR0 to overflow after k counts

' Initialization of inputs/outputs..commented out..duplicated in Int_handler
open_Valve = 0 ' Initialize RC2 (open_valve) at Low value
close_valve = 0 ' Intialize RC3 (close_valve) at Low value
TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0
TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt

'Interrupts Settings
FLUSH_INT_FLAG VAR INTCON.0 ' RA3 (FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Timer0 overflow flag bit
INTCON = %10101000 ' Enable global, TMR0 & RABIE (RA3 on-change-INT)
IOCA = %00001000 ' Enable RA3 as on-change-INT

' -----[ Main Code ]-------------------------------------------------------
'Set INT Handler
ON INTERRUPT GOTO Int_handler

'Start...normal code here
MAIN:
' Perform following steps to save power during Sleep mode
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref during Sleep to save power
ANSEL= %11111011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bit2 as digital for RA2 pulse count interrupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Set TOCK1, MCLR and all PortA pins High before Sleep
' to save power
@ sleep
@ NOP
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change

DISABLE
Int_handler:
'Initialize registers for interrupt ops
' A/D & Comparators disabled
ANSEL=0 ' Set PortA to digital I/O for use with RA2 and RA3
ANSELH=0 ' Analog module disabled
CM1CON0=0 ' Disable comparators
CM2CON0=0
' Port Settings
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
TRISB = %00000000 ' Set all PORTB pins to outputs
TRISC = %11110000 ' Set lower 4 pins of PartB as outputs for LEDs
PORTA = %00000000 ' PortA pins all set to Low
PORTC = %00000000 ' LEDs off, PULSOUT RC3 provides a high-going pulse

High bat_mon ' For testing..simulate battery monitor input is Low or High
DEFINE WRITE_INT 1
'Write 13, bat_mon ' Remove comments on Write statements for test only
'Write 15, Vthr
diff = Vthr - bat_mon
'Write 17, diff
If diff > 2 Then 'Battery is low..light the low battery monitor light
HIGH led2
PAUSE 3000 ' Light Low Battery LED for 3 secs as warning
ENDIF
'Write 5, bat_mon ' Remove comment for test only
IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change
REPEAT
' Wait until the external Flush interrupt is at high level...limits
' interrupt to switch closure only and not for switch opening
Until flush = 1
PULSOUT open_valve,2000 ' Generate 20 msec pulse to RC3 to open valve
HIGH led1 ' Light indicator that valve is open & water flowing
Pause 1000
'Write 7, flush ' Write RA3 (FLUSH) value during testing
' Put code here to start a timer to run for 50 secs as a fail safe
' to prevent overflow of toilet tank in case of sensor failure.
'PULSOUT close_valve,2000 ' Generate 20 msec pulse to RC4 to close valve
dummy = flush ' Clear mismatch condition
FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable
'INTCON = %10001000 ' global & RABIE (RA3 on-change-INT)
' ..preclude TMRO overflow interrupt..test only
Endif
IF TMR0_INT_FLAG = 1 Then ' Interrupt was a TMR0 overflow..volume reached
PULSOUT close_valve,2000 ' Generate 20 msec pulse to RC4 to close valve
'WRITE 11, TMR0 ' Write TMR0 value..remove comment for test only
dummy = TMR0 ' Clear mismatch condition
TMR0_INT_FLAG = 0 ' clear overflow flag
TMR0 = 256 - k ' reload TMR0 to overflow after k counts
'INTCON = %10100000 ' global & TMR0 interrupts..preclude RA3 interrupt..
' test only
ENDIF
RESUME
ENABLE
' If the user program ends by getting to the last statement of the program
' at an END instruction, the MCU will SLEEP and await a wakeup.
END

bogdan
- 18th June 2009, 00:24
...use DT_interrupts...

...for low power consumption why you didn`t use timer1+external_32.768khz_crystal instead of timer0...the pic will stay more in sleep (timer1=16bit)

jellis00
- 19th June 2009, 04:42
Appreciate your inputs, but don't know what you mean by DT_Interrupts. Could you explain?
I am using the TMR0 overflow interrupt to count pulses up to a maximum of 256 pulses. That is adequate for my application. Why would I want to change over to TMR1 interrupt for 16 bits if 8 bits is enough?
I do understand your suggestion to reduce clock speed from my current use of internal clock at 4 MHz. However I don't want to add the costl of an external crystal and capacitors. Is there a way for me to reduce clock speed at the Main code just before SLEEP and then reset clock to 4 MHz when it enters interrupt?? My understanding from the data sheet is that the clock speed has to be part of the @ config statement that is read by the compiler and can't be changed during runtime.
Any suggestions from anyone on how to modify this code just before the @ SLEEP statment to reduce power would be appreciated. The current 400 uamps seems excessive for SLEEP mode....most posts indicate SLEEP mode for nanoWatt MCU like 16F690 should be more like a few uamps...not hundreds of uamps. >>>>

jellis00
- 19th June 2009, 04:46
I forgot to mention in my last post that the real problem I am looking for advice on is why my code doesn't put the MCU back into SLEEP mode after servicing the interrupts. Can anyone advise me? It is in SLEEP mode on power up, but after servicing the 1st interrupt will never go back into SLEEP mode as indicated by 400 uamps consumption.

Jerson
- 19th June 2009, 06:46
How about clearing the interrupt flags before you 'Sleep' ? Also, I think you need to read RB3 to clear the flag.

jellis00
- 19th June 2009, 17:27
Jerson, thanks for your comments. However, your comments confuse me slightly: 1) I thought my code does clear the mismatch condition for both types of interrupts at the end of each IF-THEN block for each interrupt before RESUME where i read the Ports (dummy = flush or dummy = TMR0);
2) I also thought my code does clear the intterupt flags for both types( FLUSH_INT_FLAG = 0 and TMR0_INT_FLAG = 0).
Your comment about reading RB3 also confuses me since I am not using the RB3 as an intterupt.
Can you please take another look at my interrupt service routine and clarify whether these coded statements are actually clearing the interrupts? Thanks!

Jerson
- 20th June 2009, 04:51
Well yes, you are right. I guess I wasn't thinking straight when I wrote this. You are indeed clearing the RA3 port(not RB3). TMR0 needs to be cleared by writing to the flag register which you seem to be doing. The dummy=TMR0 is not needed.

Only thing left would be to clear the flags before you 'sleep' rather than at the end of the interrupt. This will clear any conditions that occur between the interrupt end and going to sleep.

Sorry for confusing you.

jellis00
- 21st June 2009, 18:48
Thanks again Jerson. From everything I have read I thought the clearing of the mismatch and the clearing of the interrupt must occur before the RESUME statement at the end of an interrupt service routine?? Your suggestion to put them in the MAIN loop before the SLEEP statement is something I had not heard. I will try it to see.
I did find part of the problem. I commented out the @ NOP statement after the @ SLEEP statement and now the power consumption is as follows:
1) On Power up in the MAIN loop: 400 uamps
2) During ops after Interrupt in Int_Handler: 4 mamps
3) After completion of Int_Handlr (not sure whether program is at the SLEEP statement in the MAIN loop or not): drops back to 1.74 mamps.
But it is obviously not back into deep sleep since it didn't go to 400 uamps after the Int_Handlr.
4) If I remove power and then reapply power it goes to 400 umaps again.

Any other ideas on why it apparently isn't going into deep sleep after the Int_Handlr??

jellis00
- 21st June 2009, 20:16
I tried Jerson's suggestion to move the clearing of mismatch and interrupt flags to MAIN loop just before SLEEP statement instead of at the end of the Int_Handlr and it didn't work. It appeared to create continuous interrupts into the Interrupt handler without activation of any of the switches to do so.
When I put the clearing of mismatches and interrupt flags back at the end of the Int_Handlr just before RESUME the interrupts work correctly again.
Therefore, this suggestion to get the MCU back into deep sleep after servicing the interrupts didn't work.
Any other suggestions from anyone out there on how to get this back into deep SLEEP after the interrupts are services??

Archangel
- 22nd June 2009, 00:33
Disable WDT ?

jellis00
- 22nd June 2009, 03:56
Thanks, Joe. I changed the @ _config to WDT_OFF and it lowered power consumption slightly during the operations while in the Int_Handler sequence, but MCU still doesn't go back into SLEEP mode after the 1st Interrupt is serviced....still at 1700 uamps as opposed to 400 uamps after power up into MAIN sequence.
Anyone else have any ideas?

Darrel Taylor
- 22nd June 2009, 06:44
Yes, turn off the WDT ... and the BOR ... and the PORTAB Pull-Ups.
400uA is too high for sleep mode.

But the real problem is with ANSEL.
As trivial as it might seem, I think this will make a huge difference.

In the Main loop ...

ANSEL= %11110011

Archangel
- 22nd June 2009, 08:12
Yes, turn off the WDT ... and the BOR ... and the PORTAB Pull-Ups.
400uA is too high for sleep mode.

But the real problem is with ANSEL.
As trivial as it might seem, I think this will make a huge difference.

In the Main loop ...

ANSEL= %11110011

I have the demo board he's using, and found changing Tris to TRISA = %00001000 instead of all inputs helped too. Pinned out the ports and found the Ports A & B to be hot without turning WPUA & WPUB off, but as no load didnt affect sleep draw all that much, the thing is my trusty ElCheapo low impeadance $6.00 Chinese meter gives me much higher numbers than 400 µA , but it does indicate the change reliably.

jellis00
- 22nd June 2009, 22:59
Darrell and Joe, thanks so much for both of your inputs. I have experimented with your suggested changes and the lowest I was able to get the current to on Power Up was 350 microamps with the settings shown in my latest Main code excerpt listed below.
Here is the experiment sequence I went thru and the resultant current loads as shown on my Micronta Multimeter:
1) My Original Code + WDT_off: 400 microamps on powerup; settled to 1070 microamps after 1st interrupt sequence. (Note: all PortAB pullups were already off, as suggested by Darrell, in my original code by virtue of the OPTION_REG = %00111000 setting in my Initialization code)
2) Previous 1) + BOR_OFF by setting BOR_SBODEN in _config and PCON.4 = 0 in MAIN: 350 microamps on powerup; settled to 1020 microamps after 1st interrupt service.
3) Previous 2) + ANSEL=%1110011 as suggested by Darrell: no apparent changes...350 microamps on powerup; settled to 1020 microamps after 1st interrupt service. This was lowest case power achieved.
l4) Previous 3) + TRISA = %00001000 as suggested by Joe: current on powerup went back up to 1020 microamps and settled to 1020 microamps after 1st interrupt service.
Obviously Cases 2 & 3) were lowest power condition achieved by your suggested changes, but still in excess of what I expected, although the impedance of my meter may be making these reading higher than actual.

However, none of these changes solved my real problem which is "how to get the MCU to return to SLEEP mode at same current as on powerup after the 1st interrupt service is processed". Although all apparent steps in the code stop after the 1st interrupt and it appears the MCU is in SLEEP, the current never returns to the lower power up condition.
Neither of your comments mentioned anything that appeared in my code to be preventing return to the SLEEP mode in the MAIN loop after the 1st interrupt service. Any ideas????

' -----[ Device Declaration ]----------------------------------------------
' For MSASM assembler use following:
@ __config _INTRC_OSC_NOCLKOUT & _BOR_SBODEN & _WDT_OFF & _MCLRE_OFF & _CP_OFF
' For PM assembler only use following instead
'@device pic16F690, intrc_osc_noclkout, _bor_sboden, pwrt_off, wdt_off, mclr_off,
' protect_off
' The above config is inteded to set CONFIG = %0000110111010100 for hex 0DD4 or
' FCMEN on (1), IESO on(1), BOREN (01), CPD off (1), CP off (1), /MCLR is
' digital input (0), /PWRTE off (1), WDTE off (0), INTOSCIO (100).

' -----[ Declare Variables & Aliases ]-----------------------------
'
diff VAR Byte ' Difference between bat_mon and Vthr
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing
led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery
bat_mon VAR PortA.0 ' Set RA0 as battery low power monitor
meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt
open_valve VAR PORTC.2 ' Set RC2 as valve solenoid open command
close_valve VAR PORTC.3 ' Set RC3 as valve solenoid close command

' -----[ Declare Constants ]----------------------------------------
'
k CON 10 ' Calibration factor for flow meter...# pulses per gal
Vthr CON 3 ' Assumes Low Battery Monitor threshold = 3 volts

' -----[ Initialization ]-------------------------------------------
Init:
' Setup Timer0 as an 8-bit counter with the clock input on RA2.
' 1:1 TMR0 prescaler
' TMR0 counts on high-to-low transitions
OPTION_REG = %00111000 ' PORTA/B pullups disabled, Interrupt on falling
' edge of RA2/INT, TMR0 clock source is RA2,
' increment on high-to-low transitions, prescaler to
' TMR0, TMR0 Rate 1:2
TMR0 = 256 - k ' preload TMR0 to overflow after k counts

' Initialization of inputs/outputs
open_Valve = 0 ' Initialize RC2 (open_valve) at Low value
close_valve = 0 ' Intialize RC3 (close_valve) at Low value
TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0
TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt

' Interrupts Settings
FLUSH_INT_FLAG VAR INTCON.0 ' Alias RA3(FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Alias Timer0 overflow flag bit
INTCON = %10101000 ' Enable interrupts: global, TMR0 overflow, & RABIE
IOCA = %00001000 ' Enable RA3 as on-change-INT

' Set INT Handler
ON INTERRUPT GOTO Int_handler

'-----[ Main Code Starts Here ]------------------------------------------------
MAIN:
' Perform following steps to save power during Sleep mode
OSCCON = %0100011 ' Switch to 1 MHz internal oscillator
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 pulse count
' TMR0 overflow interrupt & RA3 On-Change intterupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
CM1CON0.7 = 0 ' Turn off comparators during Sleep
CM2CON0.7 = 0
PCON.4 = 0 ' Turn off BOR during Sleep
WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely
'TRISA = %00001000 ' Trick from Joe S. to reduce SLEEP power...why???
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Write Port A all High to clear mismatch and save
' power during SLEEP
PortB = %11111111 ' Set all Port B and C pins High to save power
PortC = %11111111 ' in Sleep mode
@ sleep
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change

Darrel Taylor
- 22nd June 2009, 23:56
(Note: all PortAB pullups were already off, as suggested by Darrell, in my original code by virtue of the OPTION_REG = %00111000 setting in my Initialization code)
Actually, when OPTION_REG.7 = 0, the pull-ups are ENABLED.
A single pin with a 0V input can easily draw 250uA from the pull-up.


Neither of your comments mentioned anything that appeared in my code to be preventing return to the SLEEP mode in the MAIN loop after the 1st interrupt service.
That's what my ANSEL point was about.

By turning ON/OFF the analog function on PORTA.3 (flush), you were inadvertently triggering PORTA change interrupts when no changes were made to the input state of the RA3 pin.
That alone would cause it to lock up in the ISR.

Perhaps there are more problems as well.
For sure, there's an awful lot of stuff that doesn't need to be there.

I will look further.
<br>

Darrel Taylor
- 23rd June 2009, 02:21
And if AN3 had been on RA3 ... That might have made sense.

But it isn't :o
On a 690, it's on RA4, so my ANSEL point was stupid.

Still looking though.
<br>

jellis00
- 23rd June 2009, 02:32
To hopefully assist you in identifying why my code doesn't put the MCU into sleep after the execution of the 1st interrupt service, I am including here the pinouts in my current configuration. These are the same pinouts I had for the powere consumption summary of 4 cases I previously posted.


'------------------------- 16F690 Port Assignments ----------------------------
' I/O pin connections to the PIC16F690 MCU are as follows:
' PORTA.0 (19) RA0 connected as ICSPDAT when used for ICSP & also to a low
' battery monitor R/C circuit for normal ops.
' PORTA.1 (18) RA1 connected as ICSPCLK when used for ICSP.
' PORTA.2 (17) RA2 connected to external Flush contact limit switch which
' connects to ground when activated and serves as On-change Interup
' During testing connects to a grounded momentary-on switch on the
' PICkit2 board to simulate external limit switch On-change Interup
' PORTA.3 (04) RA3 connected during testing to an external flow meter to detect
' flow meter pulse inputs.
' During testing it connects to a grounded momentary-on switch
' on the PICkit2 board as a clock input to TMR0 for counting of
' pulses and as an overflow interrupt.
' PORTA.4 (03) RA4 connected to pin 6 of the ICSP header for use in programming.
' PORTA.5 (02) RA5 not connected.
' PORTB.0 ( ) RB0 not connected.
' PORTB.1 ( ) RB1 not connected.
' PORTB.2 ( ) RB2 not connected.
' PORTB.3 ( ) RB3 not connected.
' PORTB.4 (13) RB4 connected via a 10 ohm resistor to power the Wireless option.
' PORTB.5 (12) RB5 connected to Hall Effect sensor circuit #2.
' PORTB.6 (08) RB6 connected to Hall Effect sensor circuit #1.
' PORTB.7 (09) RB7 connected to pin R/T SEL on the TRM-XXX-LT transceiver.
' PORTC.0 (11) RC0 connected as an output to an LED & is on when the valve
' is opened.
' PORTC.1 (12) RC1 connected as an output to an LED & is on when battery is low.
' PORTC.2 (13) RC2 connected as an output to relay RL1 that actuates the
' + latching line of a solenoid to open the valve.
' During program testing on the PICkit2 demo board it is connected
' to an LED to show when the pulse is sent.
' PORTC.3 (14) RC3 connected as an output to relay RL2 that actuates the
' - latching line of a solenoid to close the valve.
' During program testing on the PICkit2 demo baord it is connected
' to an LED to show when the pulse is sent.
' PORTC.4 (15) RC4 not connected.
' PORTC.5 (16) RC5 connected to pin PDN on the TRM-XXX-LT transceiver.
' PORTC.6 (17) RC6 connected to pin RSSI on the TRM-XXX-LT transceiver.
' PORTC.7 (18) RB7 connected to pin R/T SEL on the TRM-XXX-LT transceiver.

' -----[ Device Declaration ]----------------------------------------------
' For MSASM assembler use following:
@ __config _INTRC_OSC_NOCLKOUT & _BOR_SBODEN & _WDT_OFF & _MCLRE_OFF & _CP_OFF

jellis00
- 23rd June 2009, 02:37
Sorry for having posted incorrect info in previous post, but I noticed that I had the descriptions reversed on RA2 and RA3. In the actual code you will see that I am using RA3 as the flush On-change interrupt and RA2 as the pulse count input to TMR0 overflow interrupt....just the reverse of the pinout descriptions.

jellis00
- 23rd June 2009, 03:10
Darrel,
I did some experimenting with TRISA to follow up on Joe's suggestion that didn't work when I tried it. However, I discovered that if I place the following TRISA statement ahead of the @ SLEEP in the MAIN loop
TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs
then it appears the MCU does go into sleep after the 1st interrupt with the same power as was shown at PowerUp....in this case, 350 microamps.
Unfortunately I don't know why. I still have the following statement in the Int_Handlr that makes all PortA inputs during the ISR.
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used in the ISR
Can you explain why this change to TRISA in the MAIN loop makes it work and without it, it won't??
So that you and anyone else who ever referes to this thread can see the final solution, here is the code that appears to work. Power consumed during apparent SLEEP (350 microamps) is still higher than I would like, but possibly I am not seeing accurate values on my ampmeter???


' -----[ Device Declaration ]----------------------------------------------
' For MSASM assembler use following:
@ __config _INTRC_OSC_NOCLKOUT & _BOR_SBODEN & _WDT_OFF & _MCLRE_OFF & _CP_OFF
' For PM assembler only use following instead
'@device pic16F690, intrc_osc_noclkout, _bor_sboden, pwrt_off, wdt_off, mclr_off,
' protect_off
' The above config is inteded to set CONFIG = %0000110111010100 for hex 0DD4 or
' FCMEN on (1), IESO on(1), BOREN (01), CPD off (1), CP off (1), /MCLR is
' digital input (0), /PWRTE off (1), WDTE off (0), INTOSCIO (100).

' -----[ Revision History ]------------------------------------------------
' Version 1.0.6 on 6/19/09: Replaced 2nd IF-THEN block with REPEAT-UNTIL to
' flash leds correctly during flow and low battery
' Version 1.0.7 on 6/21/09: Eliminated @ NOP in MAIN; Reformated Port
' Assignments list; Changed IntCloc from 4 to 1 MHz;
' WDT_OFF and comparators off to save power.
' Version 1.0.8 on 6/22/09: Changes to MAIN to minimize power during Sleep:
' Set BOR_SBODEN; set PCON.4 =0; ANSEL =%11110011,
' TRISA = %00001000 in MAIN to reduce Sleep power.

' -----[ Declare Variables & Aliases ]-----------------------------
'
diff VAR Byte ' Difference between bat_mon and Vthr
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing
led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery
bat_mon VAR PortA.0 ' Set RA0 as battery low power monitor
meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt
open_valve VAR PORTC.2 ' Set RC2 as valve solenoid open command
close_valve VAR PORTC.3 ' Set RC3 as valve solenoid close command

' -----[ Declare Constants ]----------------------------------------
'
k CON 10 ' Calibration factor for flow meter...# pulses per gal
Vthr CON 3 ' Assumes Low Battery Monitor threshold = 3 volts

' -----[ Initialization ]-------------------------------------------
Init:
' Setup Timer0 as an 8-bit counter with the clock input on RA2.
' 1:1 TMR0 prescaler
' TMR0 counts on high-to-low transitions
OPTION_REG = %00111000 ' PORTA/B pullups enabled, Interrupt on falling
' edge of RA2/INT, TMR0 clock source is RA2,
' increment on high-to-low transitions, prescaler to
' TMR0, TMR0 Rate 1:2
TMR0 = 256 - k ' preload TMR0 to overflow after k counts

' Initialization of inputs/outputs
open_Valve = 0 ' Initialize RC2 (open_valve) at Low value
close_valve = 0 ' Intialize RC3 (close_valve) at Low value
TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0
TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt

' Interrupts Settings
FLUSH_INT_FLAG VAR INTCON.0 ' Alias RA3(FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Alias Timer0 overflow flag bit
INTCON = %10101000 ' Enable interrupts: global, TMR0 overflow, & RABIE
IOCA = %00001000 ' Enable RA3 as on-change-INT

' Set INT Handler
ON INTERRUPT GOTO Int_handler

'-----[ Main Code Starts Here ]------------------------------------------------
MAIN:
' Perform following steps to save power during Sleep mode
OPTION_REG.7 = 1 ' Disable PortA/PortB pull-ups
OSCCON = %0100011 ' Switch to 1 MHz internal oscillator
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 pulse count
' TMR0 overflow interrupt & RA3 On-Change intterupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
CM1CON0.7 = 0 ' Turn off comparators during Sleep
CM2CON0.7 = 0
PCON.4 = 0 ' Turn off BOR during Sleep
WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely
TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Write Port A all High to clear mismatch and save
' power during SLEEP
PortB = %11111111 ' Set all Port B and C pins High to save power
PortC = %11111111 ' in Sleep mode
@ sleep
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change

'------{ Begin Interrupt Handler }---------------------------------------------
DISABLE ' Disable interrupts during interrupt handler
Int_handler:
OPTION_REG.7 = 0 ' Enable PortA/PortB Pullups
WDTCON = %0001000 ' Turn WDT on for ops
'Initialize registers for interrupt ops
' A/D & Comparators disabled
ANSEL=0 ' Set PortA to digital I/O for use with RA2 and RA3
ANSELH=0 ' Analog module disabled
CM1CON0=0 ' Disable comparators
CM2CON0=0
' Port Settings
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
TRISB = %00000000 ' Set all PORTB pins to outputs
TRISC = %11110000 ' Set lower 4 pins of PartB as outputs for LEDs
PORTA = %00000000 ' PortA pins all set to Low
PORTC = %00000000 ' LEDs off, PULSOUT RC3 provides a high-going pulse

High bat_mon ' For testing..simulate battery monitor input is Low or High
DEFINE WRITE_INT 1
'Write 13, bat_mon ' Remove comments on Write statements for test only
'Write 15, Vthr
diff = Vthr - bat_mon
'Write 17, diff
IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change
REPEAT
' Wait until the external Flush interrupt is at high level...limits
' interrupt to switch closure only and not also for switch opening
Until flush = 1
PULSOUT open_valve,2000*2 ' Generate 20 msec pulse to RC3 to open valve
'HIGH led1 ' Light indicator that valve is open & water flowing
Write 7, flush ' Write FLUSH value..remove comment for test only
' Put code here to start a timer to run for 50 secs as a fail safe
' to prevent overflow of toilet tank in case of sensor failure.
'PULSOUT close_valve,2000 ' Generate 20 msec
' pulse to RC4 to close valve
Endif
' Valve is open and water is flowing
REPEAT
' Wait for flow to reach 1.6 gallons
' Flash flow light while water flowinguntil pulse counter overflows
High led1
Pause 125/10
Low led1
Pause 500/10
If diff > 2 Then ' Battery is low..flash the low battery monitor light
HIGH led2 ' while water is flowing
PAUSE 125/10
Low led2
Pause 500/10
ENDIF
'Write 5, bat_mon ' Remove comment for test only
Until TMR0_INT_FLAG = 1 ' Until flow meter pulse counter overflows
PULSOUT close_valve,2000*2 ' Generate 20 msec pulse to RC4 to close valve
WRITE 11, TMR0_INT_FLAG ' Write TMR0 value..remove comment for test only
dummy = flush ' Clear mismatch condition
FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable RA3 on interrupt
TMR0_INT_FLAG = 0 ' Clear overflow flag
TMR0 = 256 - k ' Reload TMR0 to overflow after k counts
RESUME Main ' Resume Main Program
ENABLE
'-------{ End of Interrupt Handler }-----------------------------------------

' If the user program ends by getting to the last statement of the program
' at an END instruction, the MCU will SLEEP and await a wakeup.
END

Jerson
- 23rd June 2009, 09:31
Jellis

This may be totally irrelevant. How do you measure the sleep current? Are you measuring only the CPU current or the total circuit including all its peripherals. Maybe you are measuring the total current of all peripherals included. In that case, you should also look at the possibility that some peripheral is getting biased due to the active state of your PIC output to it.

I have many devices in the field that use the sleep mode and the total system current is in the region of 40-100uA. 40uA is typical for the PIC. Rest should be related to your circuit and its peripherals.

It will be helpful if you can post a schematic to assist in identifying your issue.

Jerson

Acetronics2
- 23rd June 2009, 13:15
Hi,Jerson

You're right ...



' Perform following steps to save power during Sleep mode
OPTION_REG.7 = 1 ' Disable PortA/PortB pull-ups
OSCCON = %0100011 ' Switch to 1 MHz internal oscillator
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 pulse count
' TMR0 overflow interrupt & RA3 On-Change intterupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
CM1CON0.7 = 0 ' Turn off comparators during Sleep
CM2CON0.7 = 0
PCON.4 = 0 ' Turn off BOR during Sleep
WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely
TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Write Port A all High to clear mismatch and save
' power during SLEEP
PortB = %11111111 ' Set all Port B and C pins High to save power
PortC = %11111111 ' in Sleep mode
@ sleep


seen any ADC power down in those lines ???

Alain

jellis00
- 26th June 2009, 06:45
Jellis

This may be totally irrelevant. How do you measure the sleep current? Are you measuring only the CPU current or the total circuit including all its peripherals. Maybe you are measuring the total current of all peripherals included. In that case, you should also look at the possibility that some peripheral is getting biased due to the active state of your PIC output to it.

I have many devices in the field that use the sleep mode and the total system current is in the region of 40-100uA. 40uA is typical for the PIC. Rest should be related to your circuit and its peripherals.

It will be helpful if you can post a schematic to assist in identifying your issue.

Jerson
I am measuring the SLEEP power by inserting in series my ampmeter at the Vcc input to the MCU. I am not measuring the circuit power to peripherals because they are either not connected during my test or for those that are powered by a pin from the PIC, they are shut down.

I am also enclosing a copy of the schematic for my design, including peripherals, per your request. If you see any precautions I should take as far as setting interfaces to peripherals before SLEEP to save power, I would greatly appreciate your suggestions.

Jerson
- 26th June 2009, 14:27
Schematic is not really readable, but looks ok to me.

I'd like to know if you can get proper sleep ;) when you put the INTCON=% instruction just before the @sleep instruction : it clears the flags and sets up for the next interrupt.

Another item which causes me a little worry is the RESUME main. Why shouldn't it resume where it interrupted??

jellis00
- 26th June 2009, 17:35
Thanks for reply, Jerson.
I tried both of your suggestions and don't see any change in current....350 microamps on power up and 350 microamps after ISR and return to SLEEP.
It is getting frustrating to figure out why the SLEEP power is so high. I would suspect my ampmeter giving high readings except for the fact that when the ISR is running I see it fluctuating in current between about 1.200 and 4.4 milliamps, which is what I would expect during ops.
Any additional suggestions greatly welcomed!

Jerson
- 27th June 2009, 06:02
You need to keep the timer interrupt off till it is started by the FLUSH button press. Once you're done with the flushing, you should turn off the TIMER0 interrupt again before sleeping.

Right now, the timer is interrupting even when it is not needed. That may be the cause ..... :)

jellis00
- 27th June 2009, 23:50
Thanks again Jerson for your help on this.
I implemented your suggestions by keeping TMR0 disabled during the MAIN and Interrupt Service Routine until just before the IF-THEN block starts checking for pulse inputs from the FlowMeter. However, I see no changes in the current flow on PowerUp or on return to SLEEP after the ISR......350 microamps in both modes. I have included my latest code that includes these changes so you can see how I did it. If I didn't do it right, please advise.
Still very frustrated on solving this problem.


' -----[ Device Declaration ]----------------------------------------------
' For MSASM assembler use following:
@ __config _INTRC_OSC_NOCLKOUT & _BOR_SBODEN & _WDT_OFF & _MCLRE_OFF & _CP_OFF
' The above config is inteded to set CONFIG = %0000110111010100 for hex 0DD4 or
' FCMEN on (1), IESO on(1), BOREN (01), CPD off (1), CP off (1), /MCLR is
' digital input (0), /PWRTE off (1), WDTE off (0), INTOSCIO (100).

' -----[ Revision History ]------------------------------------------------
' Version 1.0.7 on 6/21/09: Eliminated @ NOP in MAIN; Reformated Port
' Assignments list; Changed IntCloc from 4 to 1 MHz;
' WDT_OFF and comparators off to save power.
' Version 1.0.8 on 6/22/09: Changes to MAIN to minimize power during Sleep:
' Set BOR_SBODEN; set PCON.4 =0; ANSEL =%11110011,
' TRISA = %00001101..Set RA0, RA2 & RA3 as inputs in
' MAIN before SLEEP permits return to SLEEP after ISR.
' Version 1.0.9 on 6/25/09: Moved INTCON statement to just before SLEEP in MAIN.
' Version 1.0.10 on 6/27/09: Delayed turning on TMR0 until after Flush interrupt
' -----[ Declare Variables & Aliases ]-----------------------------
'
diff VAR Byte ' Difference between bat_mon and Vthr
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing
led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery
bat_mon VAR PortA.0 ' Set RA0 as battery low power monitor
meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt
open_valve VAR PORTC.2 ' Set RC2 as valve solenoid open command
close_valve VAR PORTC.3 ' Set RC3 as valve solenoid close command

' -----[ Declare Constants ]----------------------------------------
'
k CON 10 ' Calibration factor for flow meter...# pulses per gal
Vthr CON 3 ' Assumes Low Battery Monitor threshold = 3 volts

' -----[ Initialization ]-------------------------------------------
Init:
' Setup Timer0 as an 8-bit counter with the clock input on RA2.
' 1:1 TMR0 prescaler
' TMR0 counts on high-to-low transitions
OPTION_REG = %00111000 ' PORTA/B pullups enabled, Interrupt on falling
' edge of RA2/INT, TMR0 clock source is RA2,
' increment on high-to-low transitions, prescaler to
' TMR0, TMR0 Rate 1:2
TMR0 = 256 - k ' preload TMR0 to overflow after k counts

' Initialization of inputs/outputs
open_Valve = 0 ' Initialize RC2 (open_valve) at Low value
close_valve = 0 ' Intialize RC3 (close_valve) at Low value
TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0
TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt

' Interrupts Setting Alias'
TMR0_Enable VAR INTCON.5 ' Alias for On_Off switch of TMR0 counter
FLUSH_INT_FLAG VAR INTCON.0 ' Alias RA3(FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Alias Timer0 overflow flag bit

' Set INT Handler
ON INTERRUPT GOTO Int_handler

'-----[ Main Code Starts Here ]------------------------------------------------
MAIN:
' Perform following steps to save power during Sleep mode
OPTION_REG.7 = 1 ' Disable PortA/PortB pull-ups
OSCCON = %0100011 ' Switch to 1 MHz internal oscillator
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 pulse count
' TMR0 overflow interrupt & RA3 On-Change intterupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
CM1CON0.7 = 0 ' Turn off comparators during Sleep
CM2CON0.7 = 0
PCON.4 = 0 ' Turn off BOR during Sleep
WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely
TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Write Port A all High to clear mismatch and save
' power during SLEEP
PortB = %11111111 ' Set all Port B and C pins High to save power
PortC = %11111111 ' in Sleep mode
' Interrupt Settings
INTCON = %10001000 ' Enable interrupts: global & RABIE, but TMR0 disabled
IOCA = %00001000 ' before SLEEP. Enable RA3 as on-change-INT
@ sleep
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change

'------{ Begin Interrupt Handler }---------------------------------------------
DISABLE ' Disable interrupts during interrupt handler
Int_handler:
OPTION_REG.7 = 0 ' Enable PortA/PortB Pullups
WDTCON = %0001000 ' Turn WDT on for ops
'Initialize registers for interrupt ops
' A/D & Comparators disabled
ANSEL=0 ' Set PortA to digital I/O for use with RA2 and RA3
ANSELH=0 ' Analog module disabled
CM1CON0=0 ' Disable comparators
CM2CON0=0
' Port Settings
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
TRISB = %00000000 ' Set all PORTB pins to outputs
TRISC = %11110000 ' Set lower 4 pins of PartB as outputs for LEDs
PORTA = %00000000 ' PortA pins all set to Low
PORTC = %00000000 ' LEDs off, PULSOUT RC3 provides a high-going pulse
TMR0_Enable = 1 ' Enable the TMR0 pulse counter for overflow interrupt

IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change
REPEAT
' Wait until the external Flush interrupt is at high level...limits
' interrupt to switch closure only and not also for switch opening
Until flush = 1
PULSOUT open_valve,2000*2 ' Generate 20 msec pulse to RC3 to open valve
'HIGH led1 ' Light indicator that valve is open & water flowing
Write 7, flush ' Write FLUSH value..remove comment for test only
' Put code here to start a timer to run for 50 secs as a fail safe
' to prevent overflow of toilet tank in case of sensor failure.
'PULSOUT close_valve,2000 ' Generate 20 msec
' pulse to RC4 to close valve
Endif
' Valve is open and water is flowing
REPEAT
' Wait for flow to reach 1.6 gallons
' Flash flow light while water flowinguntil pulse counter overflows
High led1
Pause 125/10
Low led1
Pause 500/10
If diff > 2 Then ' Battery is low..flash the low battery monitor light
HIGH led2 ' while water is flowing
PAUSE 125/10
Low led2
Pause 500/10
ENDIF
'Write 5, bat_mon ' Remove comment for test only
Until TMR0_INT_FLAG = 1 ' Until flow meter pulse counter overflows
PULSOUT close_valve,2000*2 ' Generate 20 msec pulse to RC4 to close valve
WRITE 11, TMR0_INT_FLAG ' Write TMR0 value..remove comment for test only
dummy = flush ' Clear mismatch condition
FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable RA3 on interrupt
TMR0_INT_FLAG = 0 ' Clear overflow flag
TMR0 = 256 - k ' Reload TMR0 to overflow after k counts
RESUME ' Resume Main Program
ENABLE
'-------{ End of Interrupt Handler }-----------------------------------------

' If the user program ends by getting to the last statement of the program
' at an END instruction, the MCU will SLEEP and await a wakeup.
END

bogdan
- 28th June 2009, 02:47
take a look..(DS41262C-page 210)

"If the GIE bit
is set (enabled), the device executes the instruction
after the SLEEP instruction, then branches to the interrupt
address (0004h). In cases where the execution of
the instruction following SLEEP is not desirable, the
user should have a NOP after the SLEEP instruction"

...did you try

@ sleep
@ nop

?

I'm not expert neither....

Jerson
- 28th June 2009, 02:51
Jellis

Can you try it this way ? What I'm suggesting is to clear the mismatch, enable the mismatch interrupt and then sleep



IOCA = %00001000 ' Enable RA3 as on-change-INT ***this could be made permanent before main***
' clear the mismatch condition
dummy = flush
INTCON = %10001000 ' Enable interrupts: global & RABIE, but TMR0 disabled ** and RABIF is cleared **
@ sleep
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change

jellis00
- 28th June 2009, 20:34
I tried placing @ NOP statement after SLEEP and it made no difference....MCU ran as desired in either case and power on Powerup and after 1st ISR still at 350 microamps.


Jellis

Can you try it this way ? What I'm suggesting is to clear the mismatch, enable the mismatch interrupt and then sleep



IOCA = %00001000 ' Enable RA3 as on-change-INT ***this could be made permanent before main***
' clear the mismatch condition
dummy = flush
INTCON = %10001000 ' Enable interrupts: global & RABIE, but TMR0 disabled ** and RABIF is cleared **
@ sleep
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change


I also tried changing my code just before SLEEP to this suggestion and it also made no difference in operation or power consumption.

I am at a total loss as to what to do next. I have experimented with the code in many ways to see if I can get the Powerup/SLEEP power consumption lower but without success.:mad:

Darrel Taylor
- 29th June 2009, 00:13
Two suggestions.


Take a 100K resitor from +5V to your ammeter, and the other lead to ground.
If your meter is working correctly, you should get a reading of 50uA.
<br>
Remove the inputs from any of the pins that you can.
Compile and load this program ...

ASM ; 16F690
ifdef PM_USED ; For PM assembler
device INTRC_OSC_NOCLKOUT ; Oscillator Selection
device FCMEN_OFF ; Fail-Safe Clock Monitor
device IESO_OFF ; Internal External Switchover
device BOD_OFF ; Brown-out Detect
device CPD_OFF ; Data Code Protection
device PROTECT_OFF ; Code Protection
device MCLR_OFF ; Master Clear Reset
device PWRT_OFF ; Power-up Timer
device WDT_OFF ; Watchdog Timer

else ; For MPASM assembler
cfg= _INTRC_OSC_NOCLKOUT ; Oscillator Selection
cfg=cfg& _FCMEN_OFF ; Fail-Safe Clock Monitor
cfg=cfg& _IESO_OFF ; Internal External Switchover
cfg=cfg& _BOR_OFF ; Brown-out Reset
cfg=cfg& _CPD_OFF ; Data Code Protection
cfg=cfg& _CP_OFF ; Code Protection
cfg=cfg& _MCLRE_OFF ; Master Clear Reset
cfg=cfg& _PWRTE_OFF ; Power-up Timer
cfg=cfg& _WDT_OFF ; Watchdog Timer
__CONFIG cfg

endif
ENDASM

END ; Enter Comma (sleep forever with no hope of waking)

jellis00
- 29th June 2009, 02:21
T
<br>
Remove the inputs from any of the pins that you can.
Compile and load this program ...

ASM ; 16F690
ifdef PM_USED ; For PM assembler
device INTRC_OSC_NOCLKOUT ; Oscillator Selection
device FCMEN_OFF ; Fail-Safe Clock Monitor
device IESO_OFF ; Internal External Switchover
device BOD_OFF ; Brown-out Detect
device CPD_OFF ; Data Code Protection
device PROTECT_OFF ; Code Protection
device MCLR_OFF ; Master Clear Reset
device PWRT_OFF ; Power-up Timer
device WDT_OFF ; Watchdog Timer

else ; For MPASM assembler
cfg= _INTRC_OSC_NOCLKOUT ; Oscillator Selection
cfg=cfg& _FCMEN_OFF ; Fail-Safe Clock Monitor
cfg=cfg& _IESO_OFF ; Internal External Switchover
cfg=cfg& _BOR_OFF ; Brown-out Reset
cfg=cfg& _CPD_OFF ; Data Code Protection
cfg=cfg& _CP_OFF ; Code Protection
cfg=cfg& _MCLRE_OFF ; Master Clear Reset
cfg=cfg& _PWRTE_OFF ; Power-up Timer
cfg=cfg& _WDT_OFF ; Watchdog Timer
__CONFIG cfg

endif
ENDASM

END ; Enter Comma (sleep forever with no hope of waking)
[/list]
I copied this code into my MicroCode Studio editor, assembled it with PICBasic Pro compiler, programmed it into my 16F690 that is installed in a PICkit2 Low Pin Development Board, and then tried to run the program. I get the following Assembler errors:
"Overwriting previous address contents (2007)
Symbol not previously defined (_FCMEN_OFF)
Symbol not previously defined (_IESO_OFF)
Symbol not previously defined (_BOR_OFF)
SYmbol not previously defined (_CPD_OFF)"

I presumed this was because I had the _config file commented out in the 16F690.INC file, so decommented it and tried again. Same errors ocurred. Any suggestions.
Question: If I get this program to run, what will that tell me? Are you saying that with the 16F690 programmed this way I can then measure the power consumed when running and it will tell me the lowest possible power for the 16F690 before adding any other code??

Darrel Taylor
- 29th June 2009, 05:12
First off, do the resistor test. Make sure the meter's working.
Never assume the reading you get is what you are actually testing.

For the "Overwriting previous address contents (2007)" error, see this post ...
http://www.picbasic.co.uk/forum/showpost.php?p=6775&postcount=5

I'm not sure what you mean by "decommented it", you should have Commented it.

The idea is to eliminate your code and config's as the problem.
If you still get high current readings with the chip locked in sleep mode, then you need to look at the hardware.
By itself, the chip disables pull-ups, puts all pins in input mode, with all analog channels enabled. Current due to noise will be minimal.
<br>

Archangel
- 29th June 2009, 09:00
John,
add this to your config: _FCMEN_OFF , this disables the fail safe clock monitor, made about 200 micro amp difference here.