COUNT is not counting again


Closed Thread
Results 1 to 34 of 34
  1. #1
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Unhappy COUNT is not counting again

    My excerpted code as listed below all works until it gets to the point where it is suppose to count the input pulses to pin RA1 during each loop of a REPEAT...UNTIL epoch and write the count valuable to a variable Cin. Then the accumulated count for all epochs is incremented for each epoch by adding Cin to i. The accumulated count is then suppose to be written to EEPROM after the accumulated count reaches its limit and exits the loop.
    I know the loop is working because I see the LED blinking on each loop and because the WRITE statement is actually writing over the FF value in EEPROM. However, the Cin value that is written is always zero (0), indicating that COUNT is actually not counting. Therefore, the loop is never exiting, because i=i+Cin is always zero and the WRITE 7,i statement is therefore never executed. For the life of me I can't figure out why this is happening.
    I had a similar problem when I first wrote this code and solved the problem by adding the missing ANSEL =0 and ANSELH = 0 statements, which are in this code now, so that can't be the problem. I checked my register settings and I can see no reason why COUNT is not counting. Can anyone see what is wrong?
    Code:
    ' -----[ Title ]-----------------------------------------------------------*
    '                                                                          *
    ' File...... Toilet_Meter.BAS                                              *
    ' Compiler.. PICBASIC PRO Compiler from microEngineering Labs              *
    ' Purpose... PIC16F690 microcontroller for Toilet Meter Project            *
    ' Author.... John R. Ellis,                         *
    ' Started... 2/20/2009                                                     *
    '                                           *
    ' Updated... Version 1.0.6 on 5/2/2009                                    *
    ' Program Size:  255 Words                                                 *                                                            *
     ' -----[ Program Description ]---------------------------------------------*
    '  This Program is for a PIC16F690 installed in a PICkit2 Starter Kit      *
    '  Purpose:   
    '  1)  Monitor an input for an external Interrupt from flush      *
    '  2)  On Interrupt, command latching solenoid to open valve  *
    '  3)  Measure flow meter output to determine when 1.6        *
    '       gallons have passed                                                *
    '  4)  On 1.6 gallons, command latching solenoid to close       *
    '  5)  Put Microcontroller back in Sleep State to await next    *
    '       Flush Interrupt                                                      *
    ' 
    ' This Program uses the PIC16F690 to control a solenoid operated water valve
    ' and to measure the volume of water flowing through a flow meter.
    ' This program places the MCU in sleep mode most of the time until it receives 
    ' an interrupt from the activation of the toilet flush handle that closes a 
    ' contact limit switch that grounds an input pin of the microcontroller as an 
    ' interrupt.  I/O pin connections to the PIC16F690 are as follows:
    '
    ' RA1...is connected as an input from the meter to count pulse inputs, which 
    '       are simulated by multiple manual depressions of a switch on the PICKIT2 
    '       demo board during program testing.
    ' RA3...is connected as an interrupt input from the FLUSH contact limit Switch.     
    ' RC0...is connected as an output to an LED and is slowly flashed when the valve 
    '       is open.  It is also flashed even more slowly when the battery is low.
    ' RC3...is connected as an output to the latching solenoid that opens or 
    '       closes the valve.  During program testing with the PICkit2 demo
    '       board it is connected to an LED to show when the pulse is sent.      
     
    ' -----[ Device Declaration ]----------------------------------------------
    '
    '@device pic16F690, intrc_osc_noclkout, BOD_OFF, PWRT_OFF, wdt_off,mclr_off,
    ' protect_off
     
    ' -----[ Revision History ]------------------------------------------------
    '
    ' -----[ Variables Initialization ]----------------------------------------
    '
     k             CON 15  ' Calibration factor for flow meter...# pulses per gal
     i             VAR Byte   ' Index used in Gallon counter Repeat...Until loop
     Cin           VAR Byte   ' Storage variable for count from COUNTER
     
    ' -----[ Initialization ]--------------------------------------------------
    '
     
    'Registers Settings
    Init:
    ADCON1 = %01110000  ' Set PORTA to digital I/O & FRC (clock derived from a 
    '                                 dedicated internal oscillator)
    TRISA = %00000010   ' Set all PORTA pins except RA1 to outputs
    TRISB = %00000000   ' Set all PORTB and PORTC pins to outputs
    TRISC = %00000000
    PORTC = %00000000 ' Pre-set PORTB pins low, turning LEDs off
    ANSEL = 0           ' Set PortA to digital I/O; Unselect any of the A/D channels
    ANSELH = 0
    TRISA.1 = 1         ' Set RA1 as input port for meter pulse inputs
    PortA.1 = 0         ' Pre-set RA1 at Low value
    INTCON = %10010000  ' Set INTCON register to enable interrupts
     
    ' -----[ Main Code ]-------------------------------------------------------
     MAIN:
        'Send PWM pulse to latching solenoid to open valve
            'Generates 10 millisec pulse on RC3 output pin
             LOW PORTC.3            ' Initialize output pulse polarity
             PULSOUT PORTC.3,1000   ' Generate 10 msec pulse to RC3               
      
        ' Valve should be open at this point and water flowing
                
        ' Start measuring output of flow meter at RA1 input pin
        Cin = 0           ' Initialize pulse count variable to zero
        i = 0            ' Initialize total pulse count index to zero
        REPEAT ' Assume it takes k accumulated pulses for required gallons
            ' Count the number of pulses from Hall Effect Magnetic Sensor in 5 sec
            ' epochs and add count from each epoch to total accumulation and then 
            ' shutoff the valve when count meets i>k criteria.
            Count PORTA.1,5000,Cin
            WRITE 5,Cin    ' Write count into EEPROM location 5 during
                          ' pre-production testing
             'Slowly blink LED during water flow  
               HIGH PORTC.0         ' If we get here, Blink the LED once
               PAUSE 100
               LOW PORTC.0
            i = i + Cin              ' Add count to total pulse accumulation indexer
         'When i >= k, required gallons have flowed by the meter
         UNTIL i = k
         WRITE 7,i  'Store result as test of code..not in production
         'Write 8,i.LowByte
         GoTo ShutValve  
     
    ShutValve: 'Send PWM pulse to latching solenoid to close valve
                PULSOUT PORTC.3,1000   ' Generate required 10 msec pulse to RC3
      
        ' Valve should be closed at this point and no water flowing
    END

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    John,

    You've Enabled Interrupts, but there aren't any handlers defined.
    That usually causes everything to Lock-Up from "Continuous Interruptus".

    Interrupts have nothing to do with the COUNT statement.
    If it was to exit sleep mode? Don't enable the GIE bit.

    But the way you're doing it, you're going to miss a lot of pulses.
    It really should use interrupts to count the pulses.
    <br>
    DT

  3. #3
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT isn't counting again

    Darrell,
    Thanks for the reply. I commented out the INTCOM statement and the program still runs as I was describing above, but still doesn't count input pulses.
    As far as missing pulses, the rate at which the incoming pulses occur is much, much slower than the loop rate, so I don't think it will miss that many pulses.
    At any rate, I will look into how to do this with interrupts, but I still would like to figure out why the COUNT statement is not counting. Any ideas??

  4. #4
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Hello jellis00,
    Have you verified the presence and level of the pulses you are counting?
    What happens if i = i + cin >15 then will it not overshoot the until and never make the statement true ? Maybe UNTIL i >= k would be better ?
    Looked at the data sheet, no schmitt triggers to worry about, porta on change interrupts are available. I notice your code does not loop, one shot as is. I really did not write any code <font color=red>AND I DID NOT TEST THIS,</font color> but here is what I was thinking you might do differently. I would actually make the int handler a bit smaller and tidier but you get the jist.
    Code:
    ' -----[ Title ]---------------------------------------------------------- -*
    '                                                                           *
    ' File...... Toilet_Meter.BAS                                               *
    ' Compiler.. PICBASIC PRO Compiler from microEngineering Labs               *
    ' Purpose... PIC16F690 microcontroller for Toilet Meter Project             *
    ' Author.... John R. Ellis,                                                 *
    ' Started... 2/20/2009                                                      *
    '                                                                           *
    ' Updated... Version 1.0.6 on 5/2/2009                                      *
    ' Program Size:  255 Words                                                  *                                                            *
     ' -----[ Program Description ]---------------------------------------------*
    '  This Program is for a PIC16F690 installed in a PICkit2 Starter Kit       *
    '  Purpose:   
    '  1)  Monitor an input for an external Interrupt from flush                *
    '  2)  On Interrupt, command latching solenoid to open valve                *
    '  3)  Measure flow meter output to determine when 1.6                      *
    '       gallons have passed                                                 *
    '  4)  On 1.6 gallons, command latching solenoid to close                   *
    '  5)  Put Microcontroller back in Sleep State to await next                *
    '       Flush Interrupt                                                     *
    ' 
    ' This Program uses the PIC16F690 to control a solenoid operated water valve
    ' and to measure the volume of water flowing through a flow meter.
    ' This program places the MCU in sleep mode most of the time until it receives 
    ' an interrupt from the activation of the toilet flush handle that closes a 
    ' contact limit switch that grounds an input pin of the microcontroller as an 
    ' interrupt.  I/O pin connections to the PIC16F690 are as follows:
    '
    ' RA1...is connected as an input from the meter to count pulse inputs, which 
    '       are simulated by multiple manual depressions of a switch on the PICKIT2 
    '       demo board during program testing.
    ' RA3...is connected as an interrupt input from the FLUSH contact limit Switch.     
    ' RC0...is connected as an output to an LED and is slowly flashed when the valve 
    '       is open.  It is also flashed even more slowly when the battery is low.
    ' RC3...is connected as an output to the latching solenoid that opens or 
    '       closes the valve.  During program testing with the PICkit2 demo
    '       board it is connected to an LED to show when the pulse is sent.      
     
    ' -----[ Device Declaration ]----------------------------------------------
    '
    '@device pic16F690, intrc_osc_noclkout, BOD_OFF, PWRT_OFF, wdt_off,mclr_off,
    ' protect_off
     
    ' -----[ Revision History ]------------------------------------------------
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
    ' -----[ Variables Initialization ]----------------------------------------
    '
     k             CON 15     ' Calibration factor for flow meter...# pulses per gal
     i             VAR Byte   ' Index used in Gallon counter Repeat...Until loop
     Cin           VAR Byte   ' Storage variable for count from COUNTER
     
    ' -----[ Initialization ]--------------------------------------------------
    '
     
    'Registers Settings
    Init:
    ADCON1 = %01110000  ' Set PORTA to digital I/O & FRC (clock derived from a dedicated internal oscillator)
                        ' 
    TRISA = %00000010   ' Set all PORTA pins except RA1 to outputs
    TRISB = %00000000   ' Set all PORTB and PORTC pins to outputs
    TRISC = %00000000
    PORTC = %00000000   ' Pre-set PORTB pins low, turning LEDs off
    ANSEL   = 0         ' Set PortA to digital I/O; Unselect any of the A/D channels
    ANSELH  = 0
    TRISA.1 = 1         ' Set RA1 as input port for meter pulse inputs
    PortA.1 = 0         ' Pre-set RA1 at Low value
    INTCON  = %10011000 ' Set INTCON register to enable interrupts
     
    ' -----[ Main Code ]-------------------------------------------------------
     on interrupt goto Int_Handler
     
     MAIN:
        'Send PWM pulse to latching solenoid to open valve
            'Generates 10 millisec pulse on RC3 output pin
             LOW PORTC.3            ' Initialize output pulse polarity
             PULSOUT PORTC.3,1000   ' Generate 10 msec pulse to RC3               
      
        ' Valve should be open at this point and water flowing
                
    Log:
         WRITE 7,i  'Store result as test of code..not in production
         'Write 8,i.LowByte
         GoTo ShutValve  
     
    ShutValve:                         ' Send PWM pulse to latching solenoid to close valve
                PULSOUT PORTC.3,1000   ' Generate required 10 msec pulse to RC3
    @ sleep
    Disable                                   ' Valve should be closed at this point and no water flowing
    Int_Handler:
        ' Start measuring output of flow meter at RA1 input pin
        Cin = 0           ' Initialize pulse count variable to zero
        i   = 0           ' Initialize total pulse count index to zero
        REPEAT ' Assume it takes k accumulated pulses for required gallons
            ' Count the number of pulses from Hall Effect Magnetic Sensor in 5 sec
            ' epochs and add count from each epoch to total accumulation and then 
            ' shutoff the valve when count meets i>k criteria.
            Count PORTA.1,5000,Cin
            WRITE 5,Cin    ' Write count into EEPROM location 5 during
                           ' pre-production testing
                           ' Slowly blink LED during water flow  
               HIGH PORTC.0         ' If we get here, Blink the LED once
               PAUSE 100
               LOW PORTC.0
            i = i + Cin              ' Add count to total pulse accumulation indexer
         'When i >= k, required gallons have flowed by the meter
         UNTIL i >= k
         goto Log
    return
    enable
    END
    Last edited by Archangel; - 5th May 2009 at 08:27.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  5. #5
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    This could be really easy with Timer0 configured to count external pulses.

    Here's one version;
    Code:
    @  device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off
    
      T0_CLK VAR PORTA.0 ' for testing, RA0 provides external clock input to RA2
      Time CON 100       ' pause delay time
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0      ' all digital
      ANSELH=0     ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins output TMR0 count to LEDs
      TRISA = %11111110 ' RA0 = pulse output to RA2 TMR0 clock input
             
    Main:
      TMR0 = 0          ' clear TMR0 count
      REPEAT
        HIGH T0_CLK     ' rising edge on T0CKI
        PAUSE Time
        LOW T0_CLK      ' trigger TMR0 counter on falling edge on T0CKI
        PAUSE Time
        PORTC = TMR0    ' show Timer0 external clock count on LEDs
      UNTIL TMR0 = 15
      PAUSE 1000
      GOTO Main
    If you prefer interrupts, just preload Timer0 to over-flow after 15 pulses, and do whatever
    you need in the interrupt.

    You don't need to worry about missing any pulses, and you can do lots of other stuff while
    waiting for the counter to trigger.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  6. #6
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Angry COUNT is not counting again

    Joe and Bruce, thanks for the excellent inputs! I didn't totally grasp Joe's suggested use of the TMR0 as a counter, mainly because the wiring on microcontroller board doesn't enable me to use RA0 to generate a clock input to RA2 as Bruce's approach suggests.
    However, I have gone back to the drawing board to try to count the input pulses from the external sensor by counting them as interrupts. I am enclosing my new code below for reference. I tried to set up the Int-Handler to test for either a RA2/INT or a RA1 on change interrupt by means of two IF_Then blocks. Unfortunately it doesn't appear to recognize any interrupts. I know this because I inserted a LED blink at the very start of the Int_handler to tell me when an interrupt has been recognized and it never blinks for either a RA2/INT or a RA1 on change interrupt. If the RA1 interrupt is received it would increment an index counter, i, for each pulse. I also put the write statement in the If_Then block for RA1 on change interrupt so I could use the PICkit2 to read the EEPROM memory address for the value and it never changes from the FF value. These two tests tell me that my interrupt handler isn't working. Can anyone tell me what I have done wrong from this code??
    Code:
    ' -----[ Device Declaration ]--------------------------------------------------*
    '
    @device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off 
    
    ' -----[ Variables Initialization ]--------------------------------------------*
    '
     k             CON 15  ' Calibration factor for flow meter = # pulses per gal
     i             VAR Byte   ' Index used in Gallon counter Repeat...Until loop
     
    ' -----[ Initialization of Registers ]-----------------------------------------*
    '
    
    'Register Settings
    TRISA = %00001010   ' Set PORTA pins RA1 and RA3 to inputs, others as outputs
    TRISB = %00000000   ' Set PORTB pins as outputs
    TRISC = %01000000   ' Set PORTC pin RC6 to input, all others as outputs
    PORTC = %0000000    ' Pre-set PORTC LED pins low, turning LEDs off
    'A/D & Comparators disabled
        ADCON1 = %01110000  ' Set PORTA to digital I/O & FRC (clock derived from a 
                          ' dedicated internal oscillator)
        ANSEL=0             ' Set PortA to digital I/O
        ANSELH=0            ' Analog module disabled
        CM1CON0=0
        CM2CON0=0
    TRISA.1 = 1         ' Set RA1 as input port for simulated meter pulse inputs
    TRISA.3 = 1         ' Set RA3 as Master Reset input port
    PORTA.1 = 1         ' Pre-set RA1 at High value
    
    ' Setup  Interrupts
    INTCON = %10011000  ' Enable RA2/Int external interrupt and PORTA interrupts on
                        ' change
    IOCA = %00000010    ' Enable RA1 for interrupt on change for pulses received
                        ' from momentary switch, activation which simulates external HS1 sensor pulses
    on interrupt goto Int_Handler
    i=0                 ' Initialize counter index to zero
    
    ' -----[ Main Code ]-----------------------------------------------------------*
    MAIN:
        INTCON = %10011000         ' Clear interrupt flags
        IF i < k Then         'k is 15 pulse threshold
            ' Keep the valve open...do nothing..let water flow
        Else
            'i >= 15....1.6 gallons reached...Close the valve 
            PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
        ENDIF
        GOTO Main   'Main program loops while waiting for RA1 on change interrupt to count pulses
    
    Int_Handler:
        Disable                    ' No interrupts past this point
        'Blink LED on receipt of this interrupt  
            HIGH PORTC.0         ' Blink the LED once
            PAUSE 100
            LOW PORTC.0
        If INTCON = %10011010 Then  'RA2/INT external interrupt received
            PULSOUT PORTC.3,1000      ' Generate 10 msec pulse to RC3 to open valve
        Endif
        If INTCON = %10011001 Then  ' Flow meter interrupt pulse received on PORTA
            i = i + 1    'Increment pulse count value
            WRITE 7,i  'Store updated count result
        ENDIF
        Resume                     ' Return to main program
        Enable
    END
    Last edited by jellis00; - 7th May 2009 at 05:11.

  7. #7
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Hello, here is some spaghetti, you can remove the extra junk but it counts.
    Code:
    '*******************************************************************************
    '
    'jellis00
    ' File...... Toilet_Meter.BAS                                              *
    ' Compiler.. PICBASIC PRO Compiler from microEngineering Labs              *
    ' Purpose... PIC16F690 microcontroller for Toilet Meter Project            *
    ' Author.... John R. Ellis,                         *
    ' Started... 2/20/2009                                                     *
    '                                           *
    ' Updated... Version 1.0.6 on 5/2/2009                                    *
    '*******************************************************************************
    '
    '
    '
    ' -----[ Device Declaration ]--------------------------------------------------*
    ' __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON & _CP_OFF
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF &_CP_OFF
    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
    ' -----[ Variables Initialization ]--------------------------------------------*
    '
     k             CON 15  ' Calibration factor for flow meter = # pulses per gal
     i             VAR Byte   ' Index used in Gallon counter Repeat...Until loop
     
    ' -----[ Initialization of Registers ]-----------------------------------------*
    '
    
    'Register Settings
    TRISA = %00001010   ' Set PORTA pins RA1 and RA3 to inputs, others as outputs
    TRISB = %00000000   ' Set PORTB pins as outputs
    TRISC = %01000000   ' Set PORTC pin RC6 to input, all others as outputs
    PORTC = %0000000    ' Pre-set PORTC LED pins low, turning LEDs off
    'A/D & Comparators disabled
        ADCON1 = %01110000  ' Set PORTA to digital I/O & FRC (clock derived from a 
                          ' dedicated internal oscillator)
        ANSEL=0             ' Set PortA to digital I/O
        ANSELH=0            ' Analog module disabled
        CM1CON0=0
        CM2CON0=0
    TRISA.1 = 1         ' Set RA1 as input port for simulated meter pulse inputs
    TRISA.3 = 1         ' Set RA3 as Master Reset input port
    PORTA.1 = 1         ' Pre-set RA1 at High value
    GIE VAR INTCON.1
    OPTION_REG = %01110000    ' CLOCK ON RISING EDGE  'enable timer 0 count mode on RA.2
        
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler INT_INT, _Interrupt_Handler, PBP, yes
      endm
      INT_CREATE ; Creates the interrupt processor
      INT_ENABLE  TMR0_INT     ; enable Timer 0 interrupts
      INT_ENABLE   INT_INT     ; enable external (INT) interrupts
    ENDASM
    ' Setup  Interrupts
    INTCON = %10011000  ' Enable RA2/Int external interrupt and PORTA interrupts on
                        ' change
    'IOCA = %00000010    ' Enable RA1 for interrupt on change for pulses received
                        ' from momentary switch, activation which simulates external HS1 sensor pulses
    'on interrupt goto Int_Handler
    i=0                 ' Initialize counter index to zero
     GIE = 0         ' Clear interrupt flags
    ' -----[ Main Code ]-----------------------------------------------------------*
    
    flush:if portA.1 = 1 then
           
          goto main
          else
          endif  
          goto flush
    MAIN:
        IF i < k Then
        goto main        'k is 15 pulse threshold
    Else
            if i >= k then
            PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
            WRITE 7,i  'Store updated count result
            I=0 ' CLEAR COUNTER FOR NEXT FLUSH
        ENDIF
        endif
        GOTO flush   'Main program loops while waiting for RA1 on change interrupt to count pulses
    Disable 
    Interrupt_Handler:   ' only get here if interrupt occured
            
            PULSOUT PORTC.0,500         ' Blink the LED once
            i = i + 1    'Increment pulse count value
    GIE = 0 
    @ INT_RETURN ;    Resume                     ' Return to main program
    
    
    Enable
    
    END
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  8. #8
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Non interrupt version;
    Code:
      @ device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off 
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TMR0 = 0          ' clear TMR0 count       
      
    Main:
      IF TMR0 < K  THEN
                        ' Keep the valve open...do nothing..let water flow
      ELSE
        TMR0 = 0        ' clear TMR0 count
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
       ' WRITE 7, TMR0   ' write count if you need to?
        HIGH PORTC.0    ' LED toggle stuff
        PAUSE 500
        LOW PORTC.0 
      ENDIF
      GOTO Main
      
      END
    With DT interrupts; Note that now you need to use the MPASM
    assembler & config settings for MPASM.
    Code:
     @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
      
      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    TMR0_INT,  _FlusO_Matic, PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TMR0 = 241        ' preload TMR0 to overflow after 15 counts
        
      @ INT_ENABLE TMR0_INT ; enable TMR0 counter interrupt
      
    Main:
      PAUSE 1
      GOTO Main
      
    FlusO_Matic:
      TMR0 = 241       ' reload TMR0 to overflow after 15 counts
      PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
     ' WRITE 7, TMR0   ' write count if you need to?
      @ INT_RETURN
      
      END
    Then of course, you can do pretty much the same by just watching the Timer0
    interrupt flag;
    Code:
     @ device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off 
    
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TMR0 = 241        ' preload TMR0 to overflow after 15 counts
      
      TMRO_INT_FLAG VAR INTCON.2 ' Timer0 overflow flag bit   
      INTCON = 0        ' not using interrupts + clear Timer0 int flag
      
    Main:
      WHILE TMRO_INT_FLAG = 0
      WEND
      PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
     ' WRITE 7, TMR0   ' write count if you need to?
      TMRO_INT_FLAG = 0 ' clear overflow flag
      TMR0 = 241        ' reload TMR0 to overflow after 15 counts
      GOTO Main
      
      END
    And, last, but not least, there's the old stand-by ON INTERRUPT;
    Code:
    @ device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off 
    
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TMR0 = 241        ' preload TMR0 to overflow after 15 counts
      
      TMRO_INT_FLAG VAR INTCON.2 ' Timer0 overflow flag bit   
      INTCON = %10100000 ' enable global & Timer0 interrupt
      
      ON INTERRUPT GOTO FlushOMatic
      
    Main:
      PAUSE 1
      GOTO Main
      
      DISABLE  
    FlushOMatic:
      PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
     ' WRITE 7, TMR0   ' write count if you need to?
      TMRO_INT_FLAG = 0 ' clear overflow flag
      TMR0 = 241        ' reload TMR0 to overflow after 15 counts
      RESUME
      ENABLE
        
      END
    All kept really simple & fairly easy to follow/modify...;o}
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  9. #9
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Bruce, I really liked the code you posted for a Non-interrupt version to do my counting. I prefer it over the other options you posted, since I won't get into the problems I have seen in trying to handle interrupts in noisy signal envoirnments. It is concise with minimal executable statements, low memory requirement and should execute efficiently.
    It looked to me like it should run with my PIC16F690 almost as is. So I set up a pinout so that my momentary push button switch that I have been using to simulate the external sensor pusles will connect the RA2 pin to ground each time I depress the switch. I presumed this would be enough of a "clock" transition to increment the TMR0 counter. However, I haven't yet been able to see it run since I am having a compile problem with assembler errors that I can't understand or trace. I am attaching a screen snapshot (.jpg image) that shows the errors in lower left. Can you clarify what these errors are telling me?
    Attached Images Attached Images  

  10. #10
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Make sure you're using the PM assembler, and not MPASM. Or change to the MPASM
    config line I've already shown in the DT interrupts version.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  11. #11
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Unhappy COUNT is not counting again

    Bruce,
    OK, I am using PBP compiler via MicroStudio that uses MSPM assembler. So I made the config change. Now I get a different, but single assembler error: " Error[118]: Overwriting previous address contents[2007]" When I click on it, it points to the @__config statement.
    Again I don't know what this is telling me...can you advise.
    BTW, is there anywhere that you can get error listings for the MSPM assembler so you know what they mean?

  12. #12
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  13. #13
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default Count

    Thanks, Mister e, for the link. The article by Melanie on how to set configuration fuses answered my error question and also a lot of others I have had about the subject. I edited my .incl file per her instructions to eliminate overwrite by the @__config statement and it now compiles without errors.
    Now that it finally runs, I have another question for Bruce. The Non-interrupt code runs fine, but I am not seening any pulse counts show up in TMR0 value when I write it during execute and then use READ in PICKkit2 to read the memory address....it is continuously zero. I thought maybe it was because my simulation mode for pulses wasn't working so I put a voltmeter on the RA2 pin while running the program and depressing the switch button to simulate pulses. What I saw was that RA2 was at 1.8 volts when the switch was open and of course it went to ground when I depress it. Isn't the 1.8 volt transition enough to trigger the TMR0 to count the pulses?

  14. #14
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Bruce, I see now in 16F690 data sheet that for TTL the minimum Vih threshold is 2.0 volts and for Schmidt trigger it is 0.8 volts. Would my switch grounding interface appear to RA2 as TTL or Schmidt trigger? Since the RA2 input is 1.8 v when open and I am grounding it to create a simulated pulse, I don't know whether this is enough downward transition or not. If not, what can I do about it. I thought the open circuit voltage level of RA2 would be over 2.0 volts.

  15. #15
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Do you see where it states TMR0 = 0 ' clear TMR0 count

    This clears the timer0 count. If you need to write the timer0 count value to EEPROM first,
    then simply move the TMR0 = 0 below where you have WRITE 7, TMR0. Then you will clear
    the TMR0 count after you write it to EEPROM.

    It's not rocket science...;o}

    A TTL input requires 2V to VDD. As long as power is 4.5V ≤ VDD ≤ 5.5V, which just means
    VDD is greater than or equal to 4.5V and less than or equal to 5.5V. Then it meets the Vih
    logic 1 threshold.

    A Schmitt Trigger tytpe input requires 0.8V * VDD to VDD.

    If you were operating from a 5V supply, then 0.8 * 5V = 4V, which is what you'll need to
    apply as a minimum to the input for it to recognize a logic 1.

    Ground is ground. Your switch is for sure taking the input to ground.

    With 4.5V ≤ VDD ≤ 5.5V, Vil is met when the input is at Vss, up to 0.8V. But check the
    column under Conditions to be sure. It varies a bit with different VDD levels.

    Look at PINOUT DESCRIPTION – PIC16F690. Now look at RA2 for what type of input T0CKI
    is under the Input Type column.

    Now look at RA5. When you use RA5 as a general purpose I/O-pin, it only needs TTL level
    voltages. When you flip the switch to make it the Timer1 clock input, now it's a Schmitt
    Trigger input.

    Check out the BLOCK DIAGRAM OF RA5 to find out why.

    It's all right there. Just takes time to learn how to find & decipher it all...;o}

    And, when that doesn't work, download the latest Errata sheet for the PIC you're using.
    Microchip screws up once in a while, and makes changes to datasheets....;o}
    Last edited by Bruce; - 8th May 2009 at 03:55. Reason: And, when that doesn't work...!
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  16. #16
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Bruce, I moved the TMR0 = 0 clear statement after the WRITE statement. However, that is not the problem. I can see while running the code that the TMR0 value is never exceeding the value of K so it never enters the ELSE block and therefore never gets to the WRITE statement which leaves the EEPROM address at inital value of FF continuously.
    All this is telling me that my approach to simulating the input pulses by momentarily grounding the RA2 port with my switch closure is not triggering the TMR0 count, but not quite sure what to do about that...I don't yet have access to the meter so I can use real pulse inputs from the sensor.
    I understand what you are saying about the threshold value for Vih. However, my 16F690 is running off 5.0 volts, so I would have expected the voltage at RA2 to be near 5.0 volts when the switch is open (not grounded). Yet what I see is 1.8 volts, which is obviously not enough for Vih. This doesn't make sense to me, but explains why the TMR0 value is not incrementing. Any ideas why the RA2 port voltage would be at 1.8 vdc rather than 5.0 vdc when it is unloaded?
    I also didn't quite understnd your comments about RA5. My code is a close modification of the Non-interrupt version code you posted above and doesn't even mention RA5 (see current code posting below). Are you saying I have to use RA5 somehow in generating the "clock" input to RA2??
    Code:
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = 2TMR0 clock input for simulated meter pulse inputs
      TMR0 = 0          ' clear TMR0 count       
      
    Main:
      IF TMR0 < K  THEN
        ' Keep the valve open...do nothing..let water flow
        HIGH PORTC.0    ' Light LED continuously while water is flowing
      ELSE
        WRITE 7, TMR0   ' write before TMR0 cleared
        TMR0 = 0        ' clear TMR0 count
        Low PORTC.0     ' Blink LED on each clear after TMR0 >= K
        PAUSE 500
        HIGH PORTC.0    
        PAUSE 500
        LOW PORTC.0
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3 
      ENDIF
      GOTO Main
      END

  17. #17
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Bruce, I may have stumbled onto part of my problem. I checked the switch interface more closely and discovered that the wire I was inserting into a female header that was connected to RA2 from the switch was not making good contact. Now when I check the voltage on RA2 pin when it is open output it reads 3.2 vdc. Still a long ways from VDD or Vih, but yet when I now depress the switch I am getting TMR0 count values. However, I notice that only 3-4 depressions of the switch causes TMR0 to obviously exceed the K value and trigger the ELSE block where it is written to memory and then cleared. I presume that this means there is a lot of switch bounce on the momentary switch depressions, each bounce being counted as a pulse by TMR0. Yet I can't figure out why it even works when the RA2 voltage transitions are only from 3.2 volts to ground. Any ideas?
    Maybe Interrupts would still be the better approach to do the counting, where the interrupt would trigger on the first switch closure and should ignore the switch bounces while further interrupts are disabled during the Int-handler. What do you think?

  18. #18
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jellis00 View Post
    However, my 16F690 is running off 5.0 volts, so I would have expected the voltage at RA2 to be near 5.0 volts when the switch is open (not grounded). Yet what I see is 1.8 volts, which is obviously not enough for Vih. This doesn't make sense to me, but explains why the TMR0 value is not incrementing. Any ideas why the RA2 port voltage would be at 1.8 vdc rather than 5.0 vdc when it is unloaded?
    RA2 is set as an input by the tris register, so the impeadence is relativly high, your meter MAY be enough load to reduce the voltage read, install a pull up resistor from RA2 to VDD to bring it up to the 5v level or enable WPUA (sect 4.3) data sheet.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  19. #19
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Joe, I enabled a WPUA.2 = 1 on RA2. However, with this change the voltage on RA2 when open circuit output is still at 3.2 vdc rather than Vih or close to Vdd. My code now looks like below. Interestingly the WRITE 7, TMR0 in the IF block never shows a value other than zero. However, just a couple of momentary switch activations will enter into the ELSE block where the WRITE 9, TRM0 statement shows a value of greater than K each time. So it looks like a lot of switch bounce going on, but the thing I don't understand is why the WRITE 7, TMR0 statement isn't showing any TMR0 values< K.
    I also notice that if I comment out the LED blink statements in the IF block, the WRITE 7 statement doesn't write anything because the memory address shows a continuous FF value. Strange things that I don't understand. But at least it looks like the TMR0 is counting whether the value shows up correctly or not.
    Tomorrow I am going to try to generate another method of simulating the external sensor input pulses to eliminate the switch bounce problem. I thought this might be possible by using one of the I/O pin outputs in a similar blink sequence loop as I am using for the LED, and then route that output into RA2. Do you think this would work? I will try to use one of the I/O pins that has a CMOS output.

  20. #20
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    This time with the code:
    Code:
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
      K CON 15    ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = 2TMR0 clock input for simulated meter pulse inputs
      TMR0 = 0          ' clear TMR0 count
      WPUA.2 = 1        ' enable weak pull-up on RA2       
      
    Main:
      IF TMR0 < K  THEN
        WRITE 7, TMR0   ' write count during testing
        ' Keep the valve open...do nothing..let water flow
        HIGH PORTC.0    ' Blink Light LED while water is flowing
        Pause 500
        LOW PORTC.0
        PAUSE 500
      ELSE
        WRITE 9, TMR0   ' write count during testing before clearing
        TMR0 = 0        ' clear TMR0 count
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3 
      ENDIF
      GOTO Main
      END

  21. #21
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jellis00 View Post
    This time with the code:
    Code:
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
      K CON 15    ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = 2TMR0 clock input for simulated meter pulse inputs
      TMR0 = 0          ' clear TMR0 count
      WPUA.2 = 1        ' enable weak pull-up on RA2       
      
    Main:
      IF TMR0 < K  THEN
        WRITE 7, TMR0   ' write count during testing
        ' Keep the valve open...do nothing..let water flow
        HIGH PORTC.0    ' Blink Light LED while water is flowing
        Pause 500
        LOW PORTC.0
        PAUSE 500
      ELSE
        WRITE 9, TMR0   ' write count during testing before clearing
        TMR0 = 0        ' clear TMR0 count
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3 
      ENDIF
      GOTO Main
      END
    try masking the interrupt just before write and reenable right after.
    Code:
    eecon1 = 6 ' enables eeprom write
    intcon.7 = 1 
    write  address, data
    intcon.7 =0
    Last edited by Archangel; - 8th May 2009 at 09:35.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  22. #22
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    FYI, there's a new DEFINE for that
    Code:
    DEFINE WRITE_INT 1
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  23. #23
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    This code;
    Code:
     @ device  pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off 
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
      
    ' Port setup
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
      PORTA = 0
      TRISC = %11110000 ' lower 4 pins outputs
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TMR0 = 0          ' clear TMR0 count       
      
    Main:
      IF TMR0 < K  THEN
                        ' Keep the valve open...do nothing..let water flow
      ELSE
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3
        WRITE 7, TMR0   ' write count if you need to?
        TMR0 = 0        ' clear TMR0 count
        HIGH PORTC.0    ' LED toggle stuff
        PAUSE 500
        LOW PORTC.0 
      ENDIF
      GOTO Main
      
      END
    With the schematic attached - works. It writes 15 to EEPROM after precisely
    15 press/release actions on the switch.

    Tested on the PICkit 2 low pin count demo board.

    The cap on RA3 is 0.01uF, which helps eliminate contact bounce from the switch.

    The switch on the PICkit 2 demo board connects to RA3, so a wire runs directly from
    RA3 to RA2. Remove the cap, and switch bounce causes problems. It's a really simple
    fix.

    If your circuit is powered from 5V, and you measure 5V between the PIC VDD/VSS pins,
    and you only see 3.2V on RA2 with a pull-up to VDD, then check your circuit. There's a
    problem somewhere with your wiring or connections.
    Attached Images Attached Images  
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  24. #24
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default COUNT is not counting again

    Quote Originally Posted by mister_e View Post
    FYI, there's a new DEFINE for that
    Code:
    DEFINE WRITE_INT 1
    I don't see this DEFINE listed in Appendix B of the PICBASIC PRO manual, which supposedly lists all DEFINEs.
    Can you explain how you would use this to replace the code statements Joe lists to mask interrupts while writing? Do you just precede the WRITE statement with DEFINE WRITE_INT1? After the WRITE, do you still have to re-enable the interrupt? I guess if you have to do all this, I don't see how it is any more efficient than using Joe's 4 statements.

  25. #25
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    If DEFINE WRITE_INT isn't in your manual, then you probably have an older version of PBP
    or an old manual before this new define option was added.

    Newer versions of PBP include a check for this in the WRITE library. If you have DEFINE
    WRITE_INT 1 declared, it automatically disables interrupts before the write, and re-enables
    interrupts immediately after the write is complete.

    It just saves you from having to remember to do it yourself.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  26. #26
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Thumbs up COUNT is not counting again

    PROBLEM SOLVED ON THIS THREAD.

    Thanks, Bruce, for clarification on DEFINE. I will use this in all future programs where I have write statements.

    Joe S., the 0.01 uF capacitor definitely solved my switch bounce problem. The code now works perfectly and always counts exactly 15 pulses when it activates the external pulse to the valve solenoid.

    Your guys are stupendous! I learned more in the interchanges during this thread about programming PIC MCUs than I have learned in weeks reading different sources.

    Thanks again and keep up the good work!

  27. #27
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mister_e View Post
    FYI, there's a new DEFINE for that
    Code:
    DEFINE WRITE_INT 1
    That should save someone some brain damage. Where did you learn that? Das Book ?
    Joe S., the 0.01 uF capacitor definitely solved my switch bounce problem. The code now works perfectly and always counts exactly 15 pulses when it activates the external pulse to the valve solenoid.
    Credit to where credit is due . . . BRUCE . . . always on target.
    After the WRITE, do you still have to re-enable the interrupt? I guess if you have to do all this, I don't see how it is any more efficient than using Joe's 4 statements.
    Maybe not more efficient, but way easier.
    Last edited by Archangel; - 8th May 2009 at 19:17.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  28. #28
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Angry Now same working code won't work with PCB Pro??

    I thought I had this problem licked. Then I purchased PCB PRO and tried to run the same code that ran in PCB. I get all an "Overwriting prrevious address contents" assembly error and many "Symbol not previously defined erros" as related to the ANSEL, ANSELH, CM1CON and CM2CON statements as shown in the attached image. These errors sort of sound like a problem with the CONFIG statement not being commented out in the .inc file. I did make sure I commented out the @ __device statement in the 16F690.incl file that came with PCB PRO so it isn't overwritten by the !__config statement in the code.
    Can't figure thwhy this code now won't assemble. Can any of you advise me why my code would run in PCB and won't assemble in PCB PRO??

    Here is the current code as adapted from Bruce's "Non-Interrupt version" in his above post.
    Code:
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF 
      i var Byte     ' Indexer for use in For..Next loop
      K CON 15     ' Calibration factor for flow meter = # pulses per gal
      
    ' 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
      
    ' A/D & Comparators disabled
      ANSEL=0           ' all digital
      ANSELH=0          ' analog module disabled
      CM1CON0=0
      CM2CON0=0
    ' Port setup
      PORTA = 0         ' Clear the port register latches
      PORTB = 0
      PORTC = 0         ' LEDs off, PULSOUT RC3 provides a high-going pulse
    ' Set or clear the data direction registers
      TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs
      TRISB = %11111111 
      TRISC = %11110000 ' lower 4 pins outputs
    
      'VRCON = %00000000 ' turns the Vref Module OFF by clearing bit 7, 6, 4
      TMR0 = 0          ' clear TMR0 count       
      
    Main:
      IF TMR0 < K  THEN
                        ' Keep the valve open...do nothing..let water flow
      ELSE
        PULSOUT PORTC.3,1000  ' Generate required 10 msec pulse to RC3..close valve
        DEFINE WRITE_INT 1
        WRITE 7, TMR0  ' write count if you need to during testing
        TMR0 = 0        ' Clear timer count
        For i = 1 to 3 ' Blink LED 3x to indicate valve turned off
            HIGH PORTC.0    
            PAUSE 500
            LOW PORTC.0
        Next   
      ENDIF
      GOTO Main        ' Loop to Main to wait for next meter flow input
    Attached Images Attached Images  

  29. #29
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    The first error indicates you have not commented out the __config line if the 16F690.INC
    file that's used with the MPASM assembler. Make sure you do before compiling if you insert
    the MPASM @ __config directive in your code.

    The remaining errors indicate it's not finding the Microchip P16F690.INC file, which defines
    register locations/names.

    Make sure your path statement includes information on where you have MPLAB installed, or
    modify the 16F690.INC file to point directly to it.

    INCLUDE "C:\Program Files\Microchip\MPASM Suite\P16F690.INC"
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  30. #30
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Unhappy Path was the problem...now I have a new problem

    Quote Originally Posted by Bruce View Post
    "Make sure your path statement includes information on where you have MPLAB installed, or modify the 16F690.INC file to point directly to it."
    I guess when I upgraded to PB Pro and installed it, MPLAB must have ended up in a different place. Thanks for catching this...I could have spent a long time looking and not thinking of this.
    Now I have a different problem. Although I was going to try to do the counting with a NonInterrupt version of using the TMR0 overflow counter as you described above, I discovered as I progressed on my app design that I really need to do the counting with an interrupt and also another interrupt for checking on an external switch closure. I therefore am trying to use the below code where I have the interrupt handler doing two IF..THEN checks of the flag bits to handle either the TMR0 overflow while using RA2 input to TMR0 as switch for counting, or the RABIE on-change-interrupt for the RA3 input from a switch closure to ground. The TMR0 interrupt works in this code, however, the RABIE on-change-interrupt does not. I can't figure out why. Can you see whay the RABIE isn't working??
    Code:
    ' -----[ Device Declaration ]----------------------------------------------
    '
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF
     
    ' -----[ Variables & Aliases Intitialization ]-----------------------------
    '
    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
    valve VAR PORTC.3   ' Set RC3 as valve solenoid open/close command
    low_bat VAR PortA.0 ' Set RA0 as battery low power monitor
    meter VAR PORTA.2   ' Set RA2 as input for Hall Sensor meter pulse Interrupt
    flush VAR PORTA.3   ' Set RA3 as input for sensing flush switch closure Int
    bat_mon VAR Byte    ' bat_mon value when Vtrh multiplied by low_bat
    
    
    ' -----[ Constants Initialization ]----------------------------------------
    '
     k             CON 10   ' Calibration factor for flow meter...# pulses per gal
     i             VAR Byte ' Index used in Gallon counter loop
     Vthr          CON 4    ' Low Battery Monitor threshold
     
    ' -----[ Initialization ]--------------------------------------------------
    '
    'EEPROM PRESETS
    'DATA @0,0
    
    'OSC DEFINE
    'DEFINE OSC 4
    
    ' 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
      
    'Register Settings
    Init:
    TRISA = %11111111   ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
    TRISB = %00000000   ' Set all PORTB and PORTC pins to outputs
    TRISC = %00000000
    PORTC = %00000000	' Pre-set PORTC pins low, turning LEDs off
    TMR0 = 256-K        ' Preload TMR0 to overflow after k counts
    
    'A/D & Comparators disabled
      ADCON0 = %01110000  ' Set PORTA to digital I/O & FRC (clock derived from a 
      ADCON1 = %00000000  ' dedicated internal oscillator)
      ANSEL=0           ' Set PortA to digital I/O
      ANSELH=0          ' Analog module disabled
      CM1CON0=0
      CM2CON0=0
    TRISC.3 = 0       ' Set RC3 as output port for valve latching solenoid control
    Low Valve         ' Initialize RC3 (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 METER switch closure
    High meter        ' Initialize RA2 (meter) at High value for METER pulse inputs
                      ' RA2 = TMR0 clock input for simulated meter pulse inputs
    High flush        ' Initialize RA3 (flush) at High value for flush interrupt  
      
    'Interrupts Settings
    FLUSH_INT_FLAG VAR INTCON.0  ' RA3 (FLUSH) On-change-interrupt flag bit
    TMRO_INT_FLAG VAR INTCON.2   ' Timer0 overflow flag bit 
    INTCON = %10101000           ' Enable global, TMR0 & RABIE (RA3 on-change-INT)
    IOCA = %00000000             ' Enable RA3 as on-change-INT
    
    ' -----[ Main Code ]-------------------------------------------------------
    'Set INT Handler
    ON INTERRUPT GOTO Int_handler   
    
    'Start...normal code here
    MAIN:
        PORTC = %00000000   ' Turn all LEDs off
        PAUSE 1
        'SLEEP = 65,535     ' Put MC in Sleep state at power up 
        ' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
      GOTO Main        ' Loop to Main to wait for next Flush interrupt
    
      DISABLE 
    Int_handler:
      IF FLUSH_INT_FLAG = 1 Then  ' Interrupt was from RA3 on change    
        DEFINE WRITE_INT 1
        write  9, flush     ' Write RA3 (FLUSH) value during testing
        PULSOUT valve,1000  ' Generate required 10 msec pulse to RC3 to open valve
        High led1           ' Light indicator that valve is open & water flowing
        Low low_bat         ' Simulate battery monitor input is low  
        'Put code here to Wakeup the Microcontroller
        
        ' 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.
            'Goto Shutvalve
        High flush             ' Clear the interrupt
        FLUSH_INT_FLAG = 0     ' Clear interrupt flag
      Endif
      IF TMRO_INT_FLAG = 1 then  ' Interrupt was a TMR0 overflow..volume reached
        PULSOUT valve,6000  ' Generate required 20 msec pulse to RC3..close valve  
        WRITE 5, TMR0      ' Write TMR0 value..remove comment for test only
        bat_mon = low_bat * Vthr
        Write 7, bat_mon    ' Remove comment for test only  
        If bat_mon < Vthr Then
            'Light the low battery monitor light
            HIGH led2
        ENDIF
        TMR0 = 256-k              ' Reload TMR0 to overflow after k counts
        TMRO_INT_FLAG = 0         ' Clear overflow flag
      ENDIF
      LOW led1
      Low led2
      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

  31. #31
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Question Fixed part of the problem

    I discovered one of DT's posts that explained part of my problem was that I wasn't properly clearing the mismatch. When I did that the On-interrupt for RA3 worked. However, I noticed in the same DT post his statement "Keep in mind that you will get an interrupt on both the Press and Release of the button. You will eventually need to change the interrupt handler to determine which Edge occurred." I am using a momentary switch button that grounds RA3 for this On-interrupt and now I see happening what he was warning about...I get an intterupt on press AND release. However, I don't quite grasp how to modify my interrupt handler "to determine which Edge occurred." Obviously I want the interrupt to respond only to the press and not the release. Is there a way to filter out the release action to prevent the 2nd interrupt?

  32. #32
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by jellis00 View Post
    I discovered one of DT's posts that explained part of my problem was that I wasn't properly clearing the mismatch. When I did that the On-interrupt for RA3 worked. However, I noticed in the same DT post his statement "Keep in mind that you will get an interrupt on both the Press and Release of the button. You will eventually need to change the interrupt handler to determine which Edge occurred." I am using a momentary switch button that grounds RA3 for this On-interrupt and now I see happening what he was warning about...I get an intterupt on press AND release. However, I don't quite grasp how to modify my interrupt handler "to determine which Edge occurred." Obviously I want the interrupt to respond only to the press and not the release. Is there a way to filter out the release action to prevent the 2nd interrupt?
    Page 37 of the data sheet, Option Reg allows you to control rising or falling edge on RA2, you might have to move your ports around a bit . . .
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  33. #33
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    If your switch grounds the input pin to generate the interrupt, and it returns high when the
    switch is released, just wait for the pin to return high before exiting the interrupt.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  34. #34
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default Your suggestion solved problem

    By following your suggestion for basically debouncing it works. Thanks for advice!

Similar Threads

  1. Can't get COUNT to count
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 23rd March 2009, 23:14
  2. Remain counting while sending out a pulse
    By ultiblade in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 10th January 2007, 15:51
  3. hardware counting while software runs
    By Archangel in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 2nd October 2006, 03:26
  4. continious counting process (capture)
    By asynch in forum General
    Replies: 1
    Last Post: - 17th February 2006, 07:42
  5. Count command
    By hawk72501 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 6th September 2005, 19:04

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts