Maker Pro
Maker Pro

PIC 12F675 PULSE COUNTING

Hi guys.. appreciate some help please with a 12f675 project. A rotating wheel produces 8 pulses per revolution. For each second second a minimum of 8 pulses or more must occur. Should the wheel stop or slow down an output signal must signal an event by setting a port output low. I only use PIC assembly programming and MPLAB IDE templates etc. I've included my code which gives an ouput on GPIO,1 for every 8 inputs switched at GPIO,0 ( I use a pic simulator to check my programs)
I'm not sure how to combine my code into a 1 sec time frame, so as long as 8 pulses or more occur every second then OK less than 8 is bad. I thought along the lines of maybe a 1 sec period is reset on every 8 pulses but whenever the number of pulses fall short of 1 sec an output signal is flagged up. Any help with an example code would be appreciated.


;******************************************************************************
; *


LIST P=12F675 ; list directive to define processor
#INCLUDE <P12F675.INC> ; processor specific variable definitions
;------------------------------------------------------------------------------
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

;***** VARIABLE DEFINITIONS (examples)

;example of using Shared Uninitialized Data Section
INT_VAR UDATA_SHR 0x20
w_temp RES 1 ; variable used for context saving
status_temp RES 1 ; variable used for context saving

RESET_VECTOR CODE 0x000 ; processor reset vector

goto main ; go to beginning of program
;call 0x3FF
; movlw 60h ; retrieve factory calibration value
; bsf STATUS,RP0 ; set file register bank to 1
;movwf OSCCAL ; update register with factory cal value
; 3460 @ 3F8
TIME EQU 42H
COUNT EQU 31H
COUNTA EQU 30H
COUNTB EQU 34H

; ======================== .25sec delay ===================================
DELAY1

MOVLW .25
MOVWF COUNT ; THIS SECTION PROVIDES A .25 SEC TIMMING PERIOD
TIMEA CLRF TMR0
LOOPC MOVF TMR0,W
SUBWF TIME,W
BTFSS STATUS,Z
GOTO LOOPC
DECFSZ COUNT
GOTO TIMEA
RETLW 0


; ======================= 1 SECOND DELAY =================================
DELAY

MOVLW .100
MOVWF COUNT ; THIS SECTION PROVIDES A 1 SEC TIMMING PERIOD
TIMEC CLRF TMR0
LOOPA MOVF TMR0,W
SUBWF TIME,W
BTFSS STATUS,Z
GOTO LOOPA
DECFSZ COUNT
GOTO TIMEC
RETLW 0

;===========================================================
main
bsf STATUS,RP0 ; select bank 1
vrcon=0
movlw 60h ; retrieved factory calibration value
movwf OSCCAL ; put value into mem loc file reg address 90


CLRF ANSEL
movlw B'00000001' ; SET BIT 0 INPUTS GPIO 1>7 AS OUPUTS
movwf TRISIO ; SET BITS 2,3 AS INPUTS
movlw B'00000111'
movwf OPTION_REG
MOVLW .39
MOVWF TIME

bcf STATUS,RP0 ; select bank 0
CLRF GPIO
MOVLW 07H
MOVWF CMCON ;cmcon=7 ;turn off comparitor
CLRF ADCON0
clrwdt
clrf TMR0
;======================== BEGINING OF PROGRAM ============================
BEGIN
MOVLW .8
MOVWF COUNT
CHK BTFSC GPIO,0
GOTO CHK
;CALL DELAY1
BCF GPIO,1
CHK2 BTFSS GPIO,0
GOTO CHK2
;CALL DELAY1
DECFSZ COUNT
GOTO CHK
BSF GPIO,1
CALL DELAY1
BCF GPIO,1
GOTO BEGIN
END
 
You need to count one second in the background.
This is a very complex thing to do and I have attached a project that counts up to 20 seconds.
You can pull it apart and add your count to 8.
I have called it .txt ,, ,, Just rename it .asm
 

Attachments

  • StroopFinal.txt
    12.4 KB · Views: 172
You need to count one second in the background.
This is a very complex thing to do and I have attached a project that counts up to 20 seconds.
You can pull it apart and add your count to 8.
I have called it .txt ,, ,, Just rename it .asm
Thanks for your prompt reply, will take a look at it. I'ts a robot drive wheel which has 8 reflective strips around the inner facing side. An opto coupler circuit receives the IR light source reflected back from each strip. If no pulses are received within a 1sec time frame the drive system can be shut down. I'm currently using a triggered 555 timer which continually resets a 1 sec time period while in motion. This arrangement works well but not ideal.
 
Wouldn't it be simpler to go with a Pic that has a the ability to use a 32Khz clock xtal for TMR1 this gives a precise 1 sec pulse or division thereof.
M.
 
Wouldn't it be simpler to go with a Pic that has a the ability to use a 32Khz clock xtal for TMR1 this gives a precise 1 sec pulse or division thereof.
M.
Hi Minder.. Could do except I need a simple compact design with few components for this task. I have plenty of pic16f876's I could use if need be. My 1 sec time frame is not that crytical though, I can alternatively have a circuit to continue monitoring pulses until such time they stop so if no pulses are received within a 1sec time or there about an output signal is produced.
 
Can you put your checking and decrementing of count into your delay routine. You may need to adjust your timing for the extra stuff you are doing.
Adam
 
If you have 2 free timers, you can use one as a counter. You configure it to work from the internal signal connected to, say T0CKI. It'll increment every time you get a pulse. Then in your "every-second" interrupt (which you build using the second timer) you just read this timer and if it's less than 8 then you put out your signal. After reading the timer, you reset it to 0 for the next period. This completely frees up your main loop.
 
If you have 2 free timers, you can use one as a counter. You configure it to work from the internal signal connected to, say T0CKI. It'll increment every time you get a pulse. Then in your "every-second" interrupt (which you build using the second timer) you just read this timer and if it's less than 8 then you put out your signal. After reading the timer, you reset it to 0 for the next period. This completely frees up your main loop.
Thanks North Guy..I need to figure this out. I understand what youre saying and sounds like a good idea, thanks again.
 
Here's another possible solution.

If the wheel is turning at 8rpm, then due to its inertia it is reasonable to assume that pulses will be equi-spaced. So make a 125ms timer that sets a flag as soon as that time is reached.

At the start of a loop look for a pulse and then start the timer. If the next pulse appears before the flag sets, then repeat the loop. If the flag sets first, raise the alarm.
 
If you have 2 free timers, you can use one as a counter. You configure it to work from the internal signal connected to, say T0CKI. It'll increment every time you get a pulse. Then in your "every-second" interrupt (which you build using the second timer) you just read this timer and if it's less than 8 then you put out your signal. After reading the timer, you reset it to 0 for the next period. This completely frees up your main loop.

Yep that's a good one!
Adam
 
Yep that's a good one!
Adam
Here's another possible solution.

If the wheel is turning at 8rpm, then due to its inertia it is reasonable to assume that pulses will be equi-spaced. So make a 125ms timer that sets a flag as soon as that time is reached.

At the start of a loop look for a pulse and then start the timer. If the next pulse appears before the flag sets, then repeat the loop. If the flag sets first, raise the alarm.

Thanks Adam.. Yes another good idea, the wheel has 8 reflective segments per revolution, at this stage as long as more than 8 pulses are received within a 1sec time slot then all is ok. When the wheel stops rotating for more than 1sec then an output is flagged up. The time frame allows for stalling.
 
Use 1 sec or more to prevent false triggering. You are much better to accumulate.
Thanks Colin, not had chance to experiment since loosing the the use of my right hand however should be able to get back to normal shortly. This mobile robot project has to go into reverse should the robot stall or get cornered. A low logic state occurs on no wheel rotation so while in motion a logic high continues. A high logic level must also exist prior to moving off to prevent a false reverse state.
 

CDRIVE

Hauling 10' pipe on a Trek Shift3
This mobile robot project has to go into reverse should the robot stall or get cornered. A low logic state occurs on no wheel rotation so while in motion a logic high continues. A high logic level must also exist prior to moving off to prevent a false reverse state.
This doesn't address a false reverse state but I couldn't resist posting this because it exemplifies why I love Picaxe so much. This code snippet brings Pin C.2 low if it counts less than 8 pulses per second. Sensing a false reverse state would be equally simple.

Chris

Code:
High C.2
Freq:

  Count C.1, 1000, w1 ; count pulses in 1sec and load w1 with value
  If w1 <  8 Then
        Low C.2
  End If

Goto Freq
 
Last edited:
This doesn't address a false reverse state but I couldn't resist posting this because it exemplifies why I love Picaxe so much. This code snippet brings Pin C.2 low if it counts less than 8 pulses per second. Sensing a false reverse state would be equally simple.

Chris

Code:
High C.2
Freq:

  Count C.1, 1000, w1 ; count pulses in 1sec and load w1 with value
  If w1 <  8 Then
        Low C.2
  End If

Goto Freq
[/QUOTE
Hi thanks Chris for your reply. I only use pic asm so not familiar with other programming languages, but get the idea.
 
This doesn't address a false reverse state but I couldn't resist posting this because it exemplifies why I love Picaxe so much. This code snippet brings Pin C.2 low if it counts less than 8 pulses per second. Sensing a false reverse state would be equally simple.

Chris

Code:
High C.2
Freq:

  Count C.1, 1000, w1 ; count pulses in 1sec and load w1 with value
  If w1 <  8 Then
        Low C.2
  End If

Goto Freq
Thanks Chris.. I use PIC ASM so not familiar with other programming languages, however can probably figure it out.
Kind regards.
 
Top