Counter not counting !!!


Closed Thread
Results 1 to 25 of 25

Hybrid View

  1. #1
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default

    Hi,

    Ok I added an interrupt and wrote the program from what you said. Althouth I get zero on the LCD, seems that the interrupt is not working, can you help me debug it? Do I need to initialize some parameter . I am using the pic16f88
    Ken


    ' Internal Oscillation program
    ' LCD
    ' Main loop display the counts and the interrupt routine counts

    '/////////////////////////
    '// Define section //
    '/////////////////////////

    INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
    @ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_ON
    OSCCON=$60 ' use internal 4MHZ osc

    CMCON = 7 ' Turn OFF the comparators so pins can be used as digital I/O-pins

    '///////////////////////////
    '// Interrupt section //
    '///////////////////////////
    OPTION_REG = %00111000
    'Transition on TOCKI (RA4),
    'Increment on falling edge
    'Prescalar assigned to WDT for a 1:1 TMR0 ratio.
    INTCON.2 = 0 ' Clear Timer0 int flag
    INTCON.5 = 1 ' Enable Timer0 int
    TMR0 = $FF ' Set TMR0 to 255. So one more tick and TMROIF will be set.

    '/////////////////////////
    '// LCD configuration //
    '/////////////////////////

    DEFINE LCD_DREG PORTB ' Set LCD Data port
    DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 0 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2500
    DEFINE LCD_DATAUS 250
    DEFINE CHAR_PACING 2000
    pause 1000


    '/////////////////////////
    '// PIN configuration //
    '/////////////////////////

    TRISA = %11110111 ' Set PORTA to all input
    ' Set PORTA.4 (TOCKI) to input for timer0
    TRISB = %00001111 ' Set PORTB to all output
    PortA = 0

    '///////////////////////////////////////////////
    '// Variable Declaration and initialization //
    '///////////////////////////////////////////////

    Revolution var word
    Counter var word
    oldCounter var word
    feet var word
    feet_left var word
    feet_right var word

    revolution = 0
    Counter = 0
    feet = 0
    PortB.2 = 1 'Put to 5v via a resistor and a pushbutton to ground for reset

    ON INTERRUPT GOTO LapCount

    Mainloop:
    if PortB.2 = 0 then
    goto Reset_variables
    endif

    lcdout $FE,1, "Cter:",dec Counter, " Rev:",dec Revolution
    lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12 'This will save feet, and the // will print the decimal to two decimal point
    pause 20
    GOTO Mainloop

    Reset_variables:
    revolution = 0
    Counter = 0
    feet= 0
    lcdout $FE,1, "Counter:",dec Counter , " Rev:",dec Revolution
    lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12
    pause 20

    GOTO Mainloop

    disable
    LapCount:
    If INTCON.2 = 1 then
    Counter = Counter + 1
    endif
    toggle PORTB.3
    TMR0 = $FF ' Indicate we're in interrupt handler
    INTCON.2 = 0 ' Clear TMR0 Interrupt Flag (Bit 2)

    'Calculate the distance

    if Counter =4 then
    Revolution = Revolution + 1
    Counter =0
    endif

    feet_left = Revolution *3
    feet_right = Revolution *25
    feet_right = feet_right / 100
    feet= feet_left +feet_right

    Resume
    Enable
    end

  2. #2
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default

    by the way I connected the sensor to portA.4
    ken

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by lerameur View Post
    Hi,

    Ok I added an interrupt and wrote the program from what you said. Althouth I get zero on the LCD, seems that the interrupt is not working, can you help me debug it? Do I need to initialize some parameter . I am using the pic16f88
    Ken


    ' Internal Oscillation program
    ' LCD
    ' Main loop display the counts and the interrupt routine counts

    '/////////////////////////
    '// Define section //
    '/////////////////////////

    INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
    @ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_ON
    OSCCON=$60 ' use internal 4MHZ osc

    CMCON = 7 ' Turn OFF the comparators so pins can be used as digital I/O-pins

    '///////////////////////////
    '// Interrupt section //
    '///////////////////////////
    OPTION_REG = %00111000
    'Transition on TOCKI (RA4),
    'Increment on falling edge
    'Prescalar assigned to WDT for a 1:1 TMR0 ratio.
    INTCON.2 = 0 ' Clear Timer0 int flag
    INTCON.5 = 1 ' Enable Timer0 int
    TMR0 = $FF ' Set TMR0 to 255. So one more tick and TMROIF will be set.

    '/////////////////////////
    '// LCD configuration //
    '/////////////////////////

    DEFINE LCD_DREG PORTB ' Set LCD Data port
    DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 0 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2500
    DEFINE LCD_DATAUS 250
    DEFINE CHAR_PACING 2000
    pause 1000


    '/////////////////////////
    '// PIN configuration //
    '/////////////////////////

    TRISA = %11110111 ' Set PORTA to all input
    ' Set PORTA.4 (TOCKI) to input for timer0
    TRISB = %00001111 ' Set PORTB to all output
    PortA = 0

    '///////////////////////////////////////////////
    '// Variable Declaration and initialization //
    '///////////////////////////////////////////////

    Revolution var word
    Counter var word
    oldCounter var word
    feet var word
    feet_left var word
    feet_right var word

    revolution = 0
    Counter = 0
    feet = 0
    PortB.2 = 1 'Put to 5v via a resistor and a pushbutton to ground for reset

    ON INTERRUPT GOTO LapCount

    Mainloop:
    if PortB.2 = 0 then
    goto Reset_variables
    endif

    lcdout $FE,1, "Cter:",dec Counter, " Rev:",dec Revolution
    lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12 'This will save feet, and the // will print the decimal to two decimal point
    pause 20
    GOTO Mainloop

    Reset_variables:
    revolution = 0
    Counter = 0
    feet= 0
    lcdout $FE,1, "Counter:",dec Counter , " Rev:",dec Revolution
    lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12
    pause 20

    GOTO Mainloop

    disable
    LapCount:
    If INTCON.2 = 1 then
    Counter = Counter + 1
    endif
    toggle PORTB.3
    TMR0 = $FF ' Indicate we're in interrupt handler
    INTCON.2 = 0 ' Clear TMR0 Interrupt Flag (Bit 2)

    'Calculate the distance

    if Counter =4 then
    Revolution = Revolution + 1
    Counter =0
    endif

    feet_left = Revolution *3
    feet_right = Revolution *25
    feet_right = feet_right / 100
    feet= feet_left +feet_right

    Resume
    Enable
    end
    Code:
    TRISA = %11110111 ' Set PORTA to all input
    <font color=red> PortA.3 as output</font color>
    ' Set PORTA.4 (TOCKI) to input for timer0
    TRISB = %00001111 ' Set PORTB to all output
    <font color=red> PortB.0:3 as inputs</font color>
    PortA = 0
    For starters, check this to see if it is what you really want.
    PortA.4 is Schmitt Trigger input so a pulldown resistor as shown in the opto's datasheet will be a necessity, it says it outputs min 3.0v so it should swing the S T input OK. The 16F88 has a ton of analog you need to attend to if you want to use it, I am not seeing any code to do that.
    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.

  4. #4
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default

    Hi,

    the hardware seems good, like I said it works at slow speed. In my case I have to use port RA4 right? to get the timer0 from my program.
    I looked through the datasheet and nowhere there is mention on how to disable the schmitt trigger.

    ken

  5. #5
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Lightbulb

    Hi, Ken

    IF you want your Thing to work properly ...

    You HAVE to use QUICK Interrupts and not " On Interrupt" ... especially if using a LCD.

    So, Have a look to asm interrupts or Darrel Instant Interrupts ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

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


    Did you find this post helpful? Yes | No

    Default

    Why not just let hardware handle most all of this for you?
    Code:
    ' include your hardware/config stuff here
    
    Revs VAR BYTE ' holds up to 255 revolutions
    ANSEL = 0     ' disable A/D so RA4 is digital
    CMCON = 7     ' disable comparators
    OPTION_REG = %00110001 ' RA4 = count input
    ' inc count every 4th falling edge with 1:4 prescale
    ' assigned to TMR0
    
    Mainloop:
        TMR0 = 0      ' clear count before pause
        PAUSE 20      ' Adjust this to set how long it counts revolutions here  
        Revs = TMR0   ' TMR0 counts 1 rev for every 4 pulses
        LCDOUT $FE,1,"Revs: ",DEC Revs
    
        ' do other stuff here, then return to get more counts
        GOTO Mainloop
    This will be a LOT faster than interrupting on every single pulse, and counting
    in software. You should be able to give the wheel a pretty good spin without
    missing anything.
    Regards,

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

  7. #7
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default

    HI, I am not able to make this code work, always leaves me with ORevs = 1 on the LCD.
    I also change the oscillation to 20 Mhz but did not see any difference.
    ken



    ' Internal Oscillation program
    ' LCD
    ' Main loop display the counts and the interrupt routine counts

    '/////////////////////////
    '// Define section //
    '/////////////////////////

    INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
    @ DEVICE pic16F88, INTRC_OSC, MCLR_ON
    OSCCON=$60 ' use internal 4MHZ osc
    ANSEL = 0 : ADCON1 = 7
    CCP1CON = 0 'CCP1 module off


    '/////////////////////////
    '// LCD configuration //
    '/////////////////////////

    DEFINE LCD_DREG PORTB ' Set LCD Data port
    DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 0 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2500
    DEFINE LCD_DATAUS 250
    DEFINE CHAR_PACING 2000
    pause 1000


    '/////////////////////////
    '// PIN configuration //
    '/////////////////////////

    TRISA = %11111111 ' Set PORTA.4 (TOCKI) to input for timer0
    TRISB = %00001111 ' Set PORTB
    PortA = 0

    '///////////////////////////////////////////////
    '// Variable Declaration and initialization //
    '///////////////////////////////////////////////

    Revs var word
    ORevs var word

    ANSEL = 0 ' disable A/D so RA4 is digital
    CMCON = 7 ' disable comparators
    OPTION_REG = %00110001 ' RA4 = count input
    ' inc count every 4th falling edge with 1:4 prescale
    ' assigned to TMR0

    Mainloop:
    TMR0 = 0 ' clear count before pause
    PAUSE 20 ' Adjust this to set how long it counts revolutions here
    Revs = TMR0 ' TMR0 counts 1 rev for every 4 pulses
    ORevs = Revs +1
    LCDOUT $FE,1,"ORevs: ",DEC ORevs

    GOTO Mainloop
    end

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


    Did you find this post helpful? Yes | No

    Default

    As Joe already mentioned earlier, RA4 T0CKI is a Schmitt Trigger input. If your sensor doesn't output a minimum voltage of 0.8 * VDD for logic 1 and 0.2 * VDD or less for logic 0, then the Schmitt Trigger input isn't seeing the correct logic levels, and TMR0 isn't counting your pulses.

    Here's a quick little test program to show how it works when RA4/T0CKI is connected to an I/O-pin to increment the counter.
    Code:
    @ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_OFF
    
    DEFINE HSER_BAUD 2400
    
    Loops VAR BYTE
    Revs var BYTE
    
    OSCCON=$60 ' use internal 4MHZ osc
    
    ANSEL = 0  ' disable A/D so RA4 is digital
    CMCON = 7  ' disable comparators
    
    TRISA.4=1  ' RA4/T0CKI = input (Timer0 clock input)
    PORTB.5=1  ' USART TX pin idles high
    PORTB.0=1  ' clock output pin to RA4 starts high
    TRISB.0=0  ' clock out pin to RA4/T0CKI = output
    TRISB.5=0  ' USART TX = output
    
    ANSEL = 0     ' disable A/D so RA4 is digital
    CMCON = 7     ' disable comparators
    OPTION_REG = %10110001 ' clk on RA4/T0CKI, falling edge, 1:4 prescale
    
    Mainloop:
        TMR0 = 0      ' clear count before each pass
        
        ' output 8 clocks on RB0 to RA4/T0CKI
        FOR Loops = 0 TO 7
          PORTB.0=1   ' RB0 connects to RA4/T0CKI
          PAUSE 5
          PORTB.0=0   ' counter increments on falling edge
          PAUSE 5
        NEXT Loops
          
        Revs = TMR0   ' get TMR0 count
        IF OPTION_REG.0 THEN
           HSEROUT ["Counts at 1:4 prescale: ",dec Revs,13,10]
        ELSE
           HSEROUT ["Counts at 1:2 prescale: ",dec Revs,13,10]
        ENDIF
        OPTION_REG.0 = OPTION_REG.0 ^ 1 ' toggle 1:4 or 1:2 prescale
        GOTO Mainloop 
        
        end
    It works great, but only as long as the input signal meets the threshold levels the Schmitt Trigger input buffer on RA4/T0CKI expects.
    Last edited by Bruce; - 20th February 2009 at 17:32. Reason: Quckie test program
    Regards,

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

Similar Threads

  1. Conway's Game Of Life
    By wellyboot in forum mel PIC BASIC Pro
    Replies: 45
    Last Post: - 28th May 2020, 07:14
  2. Replies: 42
    Last Post: - 14th January 2008, 12:38
  3. 20 Digit Virtual LED Counter
    By T.Jackson in forum Code Examples
    Replies: 9
    Last Post: - 19th November 2007, 06:02
  4. Replies: 4
    Last Post: - 18th June 2007, 14:38
  5. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 18:27

Members who have read this thread : 0

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