Menu

2 counters using 2 timers

Help
JANIS
2017-02-12
2017-02-23
  • JANIS

    JANIS - 2017-02-12

    Hello! I need make project with 2 encoders, so here the required two counters. If want to organize the pulse counting, here is Necessary to use two timers with the Ability to activate the external oscillator input? FOr PIC16F886 is Possible to organize two counters using timers? How to do it? How to do it? maybe I need another controller? thanks ....

     
  • kent_twt4

    kent_twt4 - 2017-02-13

    If quadrature encoder?, for counting, there was discussion here https://sourceforge.net/p/gcbasic/discussion/629990/thread/0dc31884/#6e4d

    The 18f2331/4331 devices have a hardware QEI module for counting or velocity measurement.

     
  • JANIS

    JANIS - 2017-02-13

    Thank you, kent!
    encoders will be used as the counters, directional control is not required. Perhaps for counter mode Could Be used capture modules ccp1 and ccp2? The 18f2331/4331 devices have input for only 1 encoder.

     
  • JANIS

    JANIS - 2017-02-13

    ok, I have created two counters using timer1 and timer2. How do I read the counter values?
    This code does not work:

    main:
    timer1 (counter_1)
    locate 0,1
    print counter_1
    timer2(counter_2)
    locate 1,1
    print counter_2
    goto main

     
  • kent_twt4

    kent_twt4 - 2017-02-13

    Forget that only one QEI module in the 18f4331 series, oops!

    More information is needed for people to help, please define the task at hand. Like for example, I want to use rotary encoders (model no. and datasheet) to measure speed, on two dc motors, in the forward direction only? Or?

    There are rotary encoder counter examples in the GreatCowBasic/Demo folder of GCB@SYN installation, that may fit the bill?

     
  • JANIS

    JANIS - 2017-02-13

    thank you, kent!
    the counter everything is in order. I Created counters using timer1 and timer0. but I need to read the timer value and print on the LCD. How properly Organized timer reading?

    This code does not work:
    main:
    timer1 (counter_1)
    locate 0,1
    print counter_1
    timer2(counter_2)
    locate 1,1
    print counter_2
    goto main

     
  • kent_twt4

    kent_twt4 - 2017-02-13

    dim TimerValue1 as word
    TimerValue0 = Timer0
    TimerValue1 = Timer1

     
  • JANIS

    JANIS - 2017-02-13

    thank you kent!

     
  • JANIS

    JANIS - 2017-02-23

    I finally finished the project. Encoders are used as pulse counters, Which has detect pulses for two chains. The system will have to be check of chain breakage. If one chain is broken, then Pulse counter detect the difference . If both chains is broken, then detect the Absence of a pulses. I use the timer_0 and timer_1 as counters. timer_2 is used for working time indication. This code is a good example. Also I published circuit diagramm. If anyone is interested,you can ask questions about this project, I will answer. Thanks kent!

     
  • JANIS

    JANIS - 2017-02-23
    #chip 16F886, 4'' 886    8mhz ir max
       #config osc=int'' var nerakstit
    #define LCD_IO 8
    #define LCD_RS Portc.5
    #define LCD_Enable Portc.7
    #define LCD_RW Portc.6
    #define LCD_DATA_PORT PortB
    dir Portc.5 out
    dir Portc.6 out
    dir Portc.7 out
    dir PortB out
    cls
    ''#include <maths.h>
    ''+++++ DIGITAL INPUTS & OUTPUTS
    
    #define button_set_enter porta.1  ''  button - SETTINGS DISPLAYS SCHROLL
    dir porta.1 in
    #define button_up_down porta.0 '' button + , - , reset
    dir porta.0 in
    #define run_in porta.2  ''  run signal from chains drive
    dir porta.2 in
    #define FAULT portc.2  '' fault relays
    dir portc.2 out
    #define LED portc.3   '' LED
    dir portc.3 out
    
    
    set LED on
     ''--------------------------------------- reklama
    locate 0,0
    print "WATCHDOG 2017 "
    wait 1 s
    'Scroll display one character right (all lines)  lcdcmd 28
    repeat 14
    lcdcmd 28
    wait 100 ms
    end repeat
    
    set LED off
    
    'Scroll display one character left (all lines)   lcdcmd 24
    ''repeat 32
    ''lcdcmd 24
    ''wait 40 ms
    ''end repeat
    
    lcdcmd 2  '' OBLIGATI   pec schroll disp. komandam jadod si komanda, lai atgrieztu parbiides sakuma poz.
     cls
    
    
    
    
      ''-----------------------------------------
    
    'inittimer1 osc, ps1_8 ' pie 20 mhz oscilatora presc 1/8  overflow timer1 notiek 9,536 reizes
    ''inittimer1 osc, ps1_4 ' pie 20 mhz oscilatora presc 1/4  overflow timer1 notiek 19,07 reizes                '' aprekinu skatit sub clock
    ''cleartimer 1
    ''on interrupt Timer1Overflow call clock
    ''===========================================
    '' timer2 prieks laika atskaites
    
    inittimer2 PS2_16, 0  ''  timer2 prescaler, postscaler   ( pec tabulas helpaa postscaler ja ir 0, tad 1:1)
     '' Fosc=4MHz; Fosc=4/4=1MHz; 1000kHz/16 =(PS2_16) =62,5kHz
    '' 62500/255=245 reizes sekunde ir timer2overflow;  255 jo 8 bit timer2 (POSTSCALER UN PRESCALER skatit no datasheet!!!)
    cleartimer 2
    
    TMR2IE = 1  '' tas ir tas pats , kas timeroverflow
    
    full=0
    sec=0
    min=0
    hours=0
    sec_detect=0
    
    enc_1=0
    enc_2=0
    enc_count_1=0
    enc_count_2=0
    ''===========================
    
    ''  define taimer1 priekš atrdarbigas ieejas
    inittimer1 ext, ps1_1
    cleartimer 1
    
    #define enc_count_2 portc.0
    dir portc.0 in
    
    ''==========================
    ''  define taimer0 priekš atrdarbigas ieejas
    inittimer0 ext, ps0_1 '
    cleartimer 0
    
    #define enc_count_1 porta.4
    dir porta.4 in
    ''============================
    ''T0SE=0
    '' T0CS=1
    ''T1GINV=0
     ''T0SE=0''T1CON=0b10000000
     ''========== frontes detektoru mainigie prieks encoderiem
    enc_1=0
    now_enc1=0
    prev_enc1=0
    enc_2=0
    now_enc2=0
    prev_enc2=0
    ''=============
    pushtime_1=0
    now1=0
    prev1=0
    aa=0
    pushtime_2=0
    now2=0
    prev2=0
    bb=1
    now3=0
    prev3=0
    
    now_run=0
    prev_run=0
    sec_disp=0
    ind_time=0
    ind_time2=0
    no_pulse_flt=0
    diff_flt=0
    cnt_detect1=0
    cnt_detect2=0
    ''dim TimerValue1 as word
    dim pulse_ind, diff_flt, no_pulse_flt as bit
    
    
    epread 1, set_reset_pulse  '' pulsu skaits pie kura noresetojas abi skaititaji sinhroni
    epread 2, set_det_cyc  '' detektesanas laiks sekundes, kad tiek salidzinatas skaititaju vertibas
    epread 3, set_delta '' pielaujama max  difference starp skaititaju vertibam nolasisanas bridi
    
    if !button_up_down then '' pieturot pogu up_down_reset starta bridi, tiek ierakstitas defaulta vertibas mainigajos
    set_reset_pulse=15
    set_det_cyc=2
    set_delta=4
    end if
    epwrite 1, set_reset_pulse
    epwrite 2, set_det_cyc
    epwrite 3, set_delta
    ''==============
    
    ''=================
    main:
    
    ''''TimerValue0 = Timer0 , taa nolasa taimeru esoso vertibu
    ''TimerValue1 = Timer1
    ''SetTimer 2, 0 , ieraksta taimeri
    
    
    ''======= timer2 darbojas visu laiku (8 bit)
    starttimer 2
    
    
    ''=====================================
    if !button_set_enter then  ''pogas nospiesanas laika ieture
    pushtime_1++
     sec_disp=0
    else
    pushtime_1=0
    end if
    
    ''===============
    
      ''TOOGLE SW  frontes detektors  (pie frontes detektora veiksmigi var realizet beeper pievienosanu)
    now1=!button_set_enter & pushtime_1=>50
    if now1>prev1 then
    pushtime_1=0
     aa++  '' beeper=on
     cls        ''  nodzesh no displeja veco informaciju. saja vieta, jo dzesanai vajag tikai 1 ciklu
    ''else
    ''beeper=off
    end if
    prev1=now1
    ''  DISPLAY CASES
    select case aa
    
    case 0   '' MAIN DISPLEJS
     MAIN_disp
    case 1''  enc. pulsu indikacija, testa displejs
    test_disp
      case 2
    reset_cnt '' iestata pulsu skaita nonullesanu, reize abiem counteriem (max 255, jo timer0 ir 8bit)
    case 3
    set_detect_cyc''iestata salidzinasanas ciklu sekundees  ( ik paec cik sekundem salidzina abu encoderu pulsu skaitu)
     case 4
    set_cnt_delta'' iestata maximalo pulsu starpibu, kada pielaujama cikla laikaa.(pielaujamaa kluda)
     case 5             ''
    aa=0
      end select
    
    ''==========================================
    ''RUN frontes detektors dazadu mainigo nonullesanai
    
    now_run=!run_in
    if now_run>prev_run then
    cls 'vajag, lai mervienibas parbiditos pa labi vai pa kreisi, ja mainas 1 cip, 2 cip , un 3 ciparu skaitli
    enc_1=0
    enc_2=0
    enc_count_1=0
    enc_count_2=0
    sec_detect=0
    cnt_diff=0
    sec=0
    min=0
    hours=0
    end if
    prev_run=now_run
    ''====================
    if !run_in then
    ''  ENCODER_1 count
     now_enc1=enc_count_1
    if now_enc1>prev_enc1 then enc_1++
    prev_enc1=now_enc1
    
    ''=======================
    
    ''  ENCODER_2 count
     now_enc2=enc_count_2
    if now_enc2>prev_enc2 then enc_2++
    prev_enc2=now_enc2
    
    
    end if
    ''==========================
    
    '' COUNTERS (ENCODERS) RESET - sinronizacija
    
    if (enc_1 > set_reset_pulse) or (enc_2 > set_reset_pulse) Then
    cls
    enc_1=0
    enc_2=0
    end if
    
    ''=================
    '' aprekina differenci starp enkoderiem , abs - absoluta vertiba
     cnt_diff= abs (enc_1 - enc_2)
     ''===========================
    '' detektesanas laiks - 1sec => ieraksta encoderu pulsus mainigaja, kuru salidzina nakamaja sekundee
    set_pre_detect_cyc = (set_det_cyc - 1)
    if sec_detect = set_pre_detect_cyc Then ''  = !!!
    cnt_detect1=enc_1
    cnt_detect2=enc_2
    end if
    '' ===== impulsu sinhronisma & impulsu neesamibas => FAULTA detektesana pec ietatita laika ( sec_detect no sub interrupt (CLOCK))
    
    if sec_detect >set_det_cyc Then
    sec_detect=0
    set pulse_ind off
    if cnt_diff>set_delta then set diff_flt on ''  > !!!!
    if (enc_1=cnt_detect1) or (enc_1=cnt_detect2) then set no_pulse_flt on'' ja 1 sec laika nav pulsu skaits palielinajies, tad faults
    end if
    
    if diff_flt or no_pulse_flt then set FAULT on '' OFF ir zem disp. case_1
    
    
    ''======  ja nav main displejs, tad laika atskaite, lai parlektu uz main displeju
    if aa<>0 Then
    if sec_disp=>50 Then
    cls
    aa=0
    sec_disp=0
    end if
    end if
    
    ''==============================================================================
    
    '=======================
    
    
    wait 10 ms ''  vajag lai parslegtos case normali
    
    goto main
    
    
    ''  CLOCK
    sub Interrupt
    TMR2IF = 0   '' overflow karodzins janonulle, lai pec tam varetu nakamaja cikla uzvilkties atkal
    full++
    if full=245 then
    sec_disp++
    if !run_in then '' LAIKA ATSKAITE PIE RUN
    sec++
    sec_detect++
    end if
    end if
    if sec>59 then
    if !run_in then '' LAIKA ATSKAITE PIE RUN
    min++
    sec=0
    end if
    end if
    if min>59 then
    if !run_in then  '' LAIKA ATSKAITE PIE RUN
    hours++
    min=0
    end if
    end if
    if hours>99 then hours=0
    
    if full<50 then
    set LED on
    Else
    set LED off
    end if
    
    
    
    end sub
    
    sub MAIN_disp
    locate 0,0
    print "RUNTIME="
    if hours<10 then
    locate 0,8
    print "0"
    locate 0,9
    print hours
    Else
    locate 0,8
    print hours
    end if
    locate 0,10
    print ":"
    if min<10 Then
    locate 0,11
    print "0"
    locate 0,12
    print min
    else
    locate 0,11
     print min
    end if
    locate 0,13
    print ":"
    if sec<10 Then
    locate 0,14
    print"0"
    locate 0,15
    print sec
    Else
    locate 0,14
    print sec
    end if
    ''===========================
    if pulse_ind=on Then
    locate 1, 0
    print "DIFF="
    Else
    locate 1, 0
    print "DIFF "
    end if
    ''=======================
    if pulse_ind=off then
    ind_time++
    end if
    if ind_time=50 then
    ind_time=0
    set pulse_ind on
    end if
    
    ''==========================
    locate 1,5
    print cnt_diff
    
    if !button_up_down then
    if FAULT=on then cls ''  lai nodzestu displeju pilniba. FAULT=on prieks 1 cikla
    set FAULT off ''  FAULTA RESETS ja ir MAIN vai test displejs
    set diff_flt off
    set no_pulse_flt off
    end if
    
    
    if FAULT & full>120 then '' & full < 120 - mirgoshanai
    locate 1, 8
     if diff_flt =on then print "CNT_DIFF"
     if (diff_flt =off & no_pulse_flt =on) then print "NO_PULSE"
    Else
    locate 1, 8
    if (no_pulse_flt=off & diff_flt =on) or (no_pulse_flt=on & diff_flt =off) then print "        "
    if (no_pulse_flt=on & diff_flt =on) then print "NO_PULSE"
    end if
    
    
    end sub
    
    sub test_disp
    
    
    locate 0,0
    print "enc_1="
    print enc_1
    
    locate 1,0
    print "enc_2="
    print enc_2
    
    
    if pulse_ind=on Then
    locate 1, 9
    print "DIFF="
    Else
    locate 1, 9
    print "DIFF "
    end if
    if pulse_ind=off then
    ind_time2++
    end if
    if ind_time2=50 then
    ind_time2=0
    set pulse_ind on
    end if
    
    locate 1,14
    print cnt_diff
    
    ''=======================
    
    if !button_up_down then
    if FAULT=on then cls ''  lai nodzestu displeju pilniba. FAULT=on prieks 1 cikla
    set FAULT off ''  FAULTA RESETS ja ir MAIN vai test displejs
    set diff_flt off
    set no_pulse_flt off
    end if
    
    
    if FAULT & full>120 then '' & full < 120 - mirgoshanai
    locate 0, 8
     if diff_flt =on then print "CNT_DIFF"
     if (diff_flt =off & no_pulse_flt =on) then print "NO_PULSE"
    Else
    locate 0, 8
    if (no_pulse_flt=off & diff_flt =on) or (no_pulse_flt=on & diff_flt =off) then print "        "
    if (no_pulse_flt=on & diff_flt =on) then print "NO_PULSE"
    end if
    
    end sub
    
    
    sub  reset_cnt'' impulsu skaita iestatijums, pie kura nonullejas abi counteri
    
    locate 0,0
    print "RESET CNT: "
    ''======================
    call butt_up_down_act
    
    ''+++++++++++++++++++++++++
    now3=!button_up_down & pushtime_2>2 & pushtime_2<20
    if now3>prev3 then
    sec_disp=0 '' lai neparlektu uz MAIN displeju
    cls    ''vajag, lai mervienibas parbiditos pa labi vai pa kreisi, ja mainas 1 cip, 2 cip , un 3 ciparu skaitli
    if increment Then set_reset_pulse++
    if decrement & set_reset_pulse > 10 Then set_reset_pulse--
    epwrite 1, set_reset_pulse
    end if
    prev3=now3
    ''============================
    locate 1, 5
    print set_reset_pulse
     print " pulses"
    
    end sub
    
    
    sub set_detect_cyc
    
    locate 0,0
    print "DETECT CYCLE: "
    ''======================  minimalais = 2 sec.
    call butt_up_down_act
    
    ''+++++++++++++++++++++++++
    now3=!button_up_down & pushtime_2>2 & pushtime_2<20
    if now3>prev3 then
    sec_disp=0 '' lai neparlektu uz MAIN displeju
    cls''vajag, lai mervienibas parbiditos pa labi vai pa kreisi, ja mainas 1 cip, 2 cip , un 3 ciparu skaitli
    if increment & set_det_cyc <15 Then set_det_cyc++''
    if decrement& set_det_cyc >2  Then set_det_cyc--
    epwrite 2, set_det_cyc
    end if
    prev3=now3
    ''============================
    locate 1, 5
    print set_det_cyc
     print " sec"
    
    end sub
    
    sub set_cnt_delta
    
    locate 0,0
    print "COUNT DELTA: "
    
    ''======================
    call butt_up_down_act
    
    ''+++++++++++++++++++++++++
    now3=!button_up_down & pushtime_2>2 &  pushtime_2<20
    if now3>prev3 then
    sec_disp=0 '' lai neparlektu uz MAIN displeju
    cls''vajag, lai mervienibas parbiditos pa labi vai pa kreisi, ja mainas 1 cip, 2 cip , un 3 ciparu skaitli
    if increment & set_delta < 100 Then set_delta++
    if decrement  Then set_delta--
    epwrite 3, set_delta
    end if
    prev3=now3
    ''============================
    locate 1, 5
    print set_delta
     print " pulses"
    
    end sub
    
    
    sub butt_up_down_act
    
    if !button_up_down then
    pushtime_2++
    Else
     pushtime_2=0
    end if
    
    now2=!button_up_down & pushtime_2=50
    if now2>prev2 Then  bb++
    prev2=now2
    select case bb
    case 1
    increment=1
    decrement=0
    
    case 2
    increment=0
    decrement=1
    
    case 3
    bb=1  ''  !!!!!!!!!!!!!(lai nebutu poga 3x jaspiezh
    end select
    
    locate 1, 0 ''    inc vai dec indikacija
    if bb=1 then print "+"
    if bb=2 then print "-"
    
    end sub
    
     
  • JANIS

    JANIS - 2017-02-23

    my circuit diagramm was wrong. this is correct

     
  • kent_twt4

    kent_twt4 - 2017-02-23

    Very well done! The schemetic is a really nice touch. Haven't soaked in everything from the code yet :).

    The encoders are somehow physically coupled to the chain idler gear shafts? How long is the conveyor?

     
  • JANIS

    JANIS - 2017-02-24

    Conveyor Chain is approximately 8m long. Encoders must be independently connected to the chain via a special gear.

     
  • Anobium

    Anobium - 2017-02-24

    Impressive. Got a video?

    I award you the Virtual Great Cow BASIC Solution of the Month - because, this sounds so impressive!

     
  • JANIS

    JANIS - 2017-02-26

    Thank you Anobium!
    What video? All conveyor chains, or only Watchdog?

     
  • JANIS

    JANIS - 2017-02-26

    Watchdog video I can to film tomorrow!

     
  • JANIS

    JANIS - 2017-02-27

    I need to prepare for the filming itself, it is necessary to prepare a text, my English is bad :( :(

     
  • JANIS

    JANIS - 2017-03-01
     
  • kent_twt4

    kent_twt4 - 2017-03-01

    Thanks for the YouTube video. You need a joystick with all those menus, haha. Very nice project.

     
  • JANIS

    JANIS - 2017-03-01

    Thanks Kent! But my project 1.5 years ago - Na HID lamp dimmer is also interesting. Na HID lamp dimmer is made in 20 copies and has been working for 1.5 years! !!! Circuit diagramm and programmcode then published here. In the project using interrupt for thyristor firing angle zero cross detection. this project was also deserved the prize Virtual Great Cow BASIC Solution of the Month :) as Anobium promise for this project....

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.