Announcement

Collapse
No announcement yet.

For/Next Loop not working

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • For/Next Loop not working

    I have set up this device to respond to a capacitive touch sensor and all works well except a third and final loop (variable W3 in program) which is to repeat the main program W3 times.

    What happens is, when I touch the sensor, things start working as planned. When I remove my hand, the device finishes a cycle and shuts off and apparently goes back to look at the sensor because if I place my hand near again, I get the sequence I'm expecting which continues but again if I remove my hand it doesn't cycle through W3 times.

    I've attached the code. I'm using the PIC 16LF1823
    -Keith
    Attached Files

  • #2
    If you're just touching a floating pin to control things, that's not going to work very well. The capacitive-touch peripheral works by measuring frequency.

    Here's some code that works on a 16F1937.

    Code:
    #CONFIG
        ; set CONFIG1 for internal oscillator
        __config _CONFIG1, _FOSC_INTOSC
        ; set CONFIG2 for int osc pll controlled by OSCCON register,
        ;low-voltage programming on
        __config _CONFIG2, _PLLEN_OFF & _LVP_ON
        ; see file PIC16F1937.INFO (in PBP installation) for more options
    #ENDCONFIG
    
    OSCCON = %01111000	' Set internal osc to 8MHz with a 4x PLL enabled
     	'(4 x 8MHz = 16MHz).
    DEFINE OSC 16	' Tell PBP that the device will clock at 16MHz
    
    ANSELA = %00000000	' PortA all digital
    ANSELB = %00110000	' PortB.4 and B.5 analog inputs
    ANSELD = %00000000	' PortD all digital
    ANSELE = %00000010	' PortE.1 analog input
    
    WPUB = %00001111	' Enable pull-ups on pins 0-3 of PORTB (RB0-3)
    OPTION_REG = %01111111	' Pull-ups enabled by individual WPUx values
    
    PORTA = %00000000	' Init all PORTA bits to low condition
    TRISA = %00000000	' Make all pins on PORTA outputs
    
    ' Set LCD Data port
    DEFINE LCD_DREG  PORTC
    ' Set starting data bit (0 or 4) of 4-bit bus
    DEFINE LCD_DBIT  0
    ' Set LCD Register Select (RS) port
    DEFINE LCD_RSREG  PORTB
    ' Set LCD Register Select (RS) bit
    DEFINE LCD_RSBIT  6
    ' Set LCD Enable (E) port
    DEFINE LCD_EREG  PORTB
    ' Set LCD Enable (E) bit
    DEFINE LCD_EBIT  7
    ' Set LCD bus width (4 or 8 bits)
    DEFINE LCD_BITS  4
    ' Set number of lines on LCD
    DEFINE LCD_LINES  2
    ' Set command delay time (microseconds)
    DEFINE LCD_COMMANDUS  1500
    ' Set data delay time (microseconds)
    DEFINE LCD_DATAUS  44
    
    PAUSE 200   ' Pause to allow LCD to initialize
    
    
    
    touch_threshold CON 100         ' reading less than this value indicates a touch
    
    channel         VAR BYTE        ' Specifies the virtual channel number 
    touch_states    VAR BYTE        ' Holds the state of each touch pad as a bit
    CPS_value       VAR BYTE        ' Stores the timer value from each pad in turn
    
    CPSCON0    = %10001101		     ' Enable cap sense using Timer0
    OPTION_REG = %11100011           ' Set Timer0 to clock source, prescaler 1:16 
    
    '''''''''''''' Main Loop ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    DO
        GOSUB ReadCPS               ' Call the subroutine that checks for touch               
        PORTA = touch_states        ' Display the touch state bits on the LEDs
    LOOP        			        ' Do it forever
    
    ''''''''''''''' Subroutines ''''''''''''''''''''''''''''''''''''''''''''''''''''
    ReadCPS:
    touch_states = %00000000    ' clear states of touch pads in result variable
        FOR Channel = 0 TO 5    ' loop through 6 channels
            ' Use LOOKUP to convert channel number to hardware (actual) channel.
            ' Place the actual channel-selection number in register CPSCON1
            LOOKUP channel, [14, 10, 13, 15, 12, 11], CPSCON1
            TMR0 = 0            ' Clear the Timer0 count value
            PAUSE 10            ' Count for 10ms
            CPS_value = TMR0    ' Record the Timer0 count value
            IF CPS_value < touch_threshold THEN  ' If this channel's reading is less than threshold...
            	touch_states.0[channel] = 1	' Set this channel's state bit to indicate touch
            ENDIF
            GOSUB display_readings  ' Call a sub to display actual readings.  Used to set threshold.
        NEXT channel
    RETURN
    	
    display_readings:
        IF Channel = 0 THEN	LCDOUT $fe, $80     ' Move cursor to home position
    	IF Channel = 3 THEN LCDOUT $fe, $c0     ' Move to second LCD line
    	LCDOUT DEC3 CPS_value, "  "	            ' Display the cap sense time
    RETURN
    Charles Leo
    ME Labs, Inc.
    http://melabs.com

    Comment


    • #3
      No Charles, I'm using a discrete sensor from Azoteq.

      I'm thinking it has to do with hardware now. As in my other recent post, I'm driving an LEDs anode via a p-Channel Mosfet and using another pin to sink the Cathode.

      It seems that the Mosfet's gate is somehow floating even and somehow reseting the PIC.
      When it comes out of PWM, does it re-establish itself as an input.-Keith

      Comment


      • #4
        The PWM command leaves the pin configured as an input. HPWM leaves it configured as an output.

        You may use a HIGH or LOW command on the pin immediately after the PWM command to set the state of the pin and make it an output.
        Charles Leo
        ME Labs, Inc.
        http://melabs.com

        Comment


        • #5
          Bingo. It all makes sense now.-Keith

          Comment

          Working...
          X