Welcome, Guest
Username: Password: Secret Key Remember me

TOPIC: timer0 and counter pulse

Re: timer0 and counter pulse 6 years 6 months ago #16405

  • mast
  • mast's Avatar
  • Offline
  • Fresh Boarder
Hello,
i search a code for make a counter with a 18f452 / 20Mhz. if i andestand the input is PA4, but i can't find any code for that. i want to make a little speedometer for my bike with a reed switch, all on a 128x64 glcd.

if you can help me.

thanks

Re: timer0 and counter pulse 6 years 6 months ago #12837

  • majenko
  • majenko's Avatar
  • Offline
  • Fresh Boarder
  • Thanks received: 62
There are two basic ways of doing this, and you need to decide which is best for you.

1. Count the pulses in a given time period - say 6 pulses in a second, is 6 RPS, or 6*60*60 RPH - multiply that by the circumference of your wheel (in miles, or KM), and you have the MPH or KPH.

2. Measure the time between two consecutive pulses. Take the reciprocal (1/time) to get the frequency (RPS), and then do the same calculations as method 1.

Method 1 is simpler to do, as your timing doesn't have to be quite as precise - you are measuring intervals of, say, 1 second. With method 2 you need to measure the time much more accurately - you want the time between pulses, which is much much shorter. However, method 2 will give you a much faster display - method 1 will only allow an update once per second (or whatever time period you sample over), whereas method 2 can update on every wheel revolution.

Personally, I'd use method 1 as it's so much simpler, and put up with the slower display update.

So you have two problems - 1: How to accurately time 1 second (for example; I'll stick to 1 second for simplicity, but the actual time is up to you) and 2: how to count the pulses.

So, the chip has a timer in it, which can be tuned to get a 1 second pulse easy enough - the data sheet will show you how to set the registers for that. And there's many on-line examples, and even sites that will let you enter the clock frequency (20MHz) and select a required time period, and it will generate the code for you.

Then you have to count the pulses. Say you have 29" wheels - that's about 91 inches circumference - add a little for the tyre, say 93 inches. Approximately 681 revolutions per mile. At 20MPH, that's 681*20 in an hour, or about 13626 PPH. Drop that to seconds (divide by 3600), and you get about 3.8 pulses per second.

I could count those by hand - well within the capabilities of a microcontroller running at 20MHz without the need for any fancy counting peripherals...

So, here's how I'd do it:

1. Set up a timer to trigger an interrupt at 1 second intervals.
2. Have a revolution counter variable (set as "volatile").
3. In the main loop of the program, poll an input (any input will do), and increment the counter every time it activates.
4. In the interrupt routine calculate the speed from the number of pulses counted, and zero the counter.

Updating the display could be done in the main loop, or in the interrupt routine - depending on how long it takes.

To simplify the display updating you could theoretically connect the reed switch to an interrupt driven input (INT0) and use an interrupt routine to count the pulses, thus leaving the main loop free to just update the display at its leisure.

Yes, you could use a timer peripheral to count the pulses (pretty much zero CPU usage), and that would give you probably the most reliable operation, but is it worth it when you're only getting a few pulses per second to count?

Re: timer0 and counter pulse 6 years 6 months ago #12833

  • mast
  • mast's Avatar
  • Offline
  • Fresh Boarder
thank you for explication majenko,

i find this one for mikroe, but i prefere Sf. this code work i don't know how but work when i push on PB0. i try to make this code for Sf
program Km1


dim velocita as float
dim spazio as float
dim circonferenza as float
dim tempo as integer
dim output as string[17]

' Lcd module connections
dim LCD_RS as sbit at RD2_bit
    LCD_EN as sbit at RD3_bit
    LCD_D4 as sbit at RD4_bit
    LCD_D5 as sbit at RD5_bit
    LCD_D6 as sbit at RD6_bit
    LCD_D7 as sbit at RD7_bit

    LCD_RS_Direction as sbit at TRISD2_bit
    LCD_EN_Direction as sbit at TRISD3_bit
    LCD_D4_Direction as sbit at TRISD4_bit
    LCD_D5_Direction as sbit at TRISD5_bit
    LCD_D6_Direction as sbit at TRISD6_bit
    LCD_D7_Direction as sbit at TRISD7_bit
' End Lcd module connections


sub procedure interrupt               'inizio procedura interrupt
    if testbit(intcon,1) then         'se rilevo cambiamento su rb0..
    spazio = spazio + circonferenza
    delay_ms(5)
     'delay_ms(1000)
    end if                            'fine cambiamento
    clearbit(intcon,1)                'rimetto tutto a posto per prossima ril.
end sub

main:
     porta = 0                        'azzero tutte le porte
     portb = 0
     portc = 0
     portd = 0
     porte = 0

     trisa = 0                        'tutte le porte in uscita tranne la rb0
     trisb = %00000001
     trisc = 0
     trisd = 0
     trise = 0

     setbit(intcon,4)                 'abilito l'int su rb0

     setbit(intcon,7)                 'abilito l'int generale

     spazio   = 0                     'resetto lo spazio
     tempo    = 1                     'tempo = 1 secondo

     circonferenza = 0.85             'circonferenza in metri

     Lcd_Init()                  ' Initialize LCD on PORTd
     'Lcd_Cmd(_LCD_TURN_OFF)          ' Turn off cursor
     Lcd_Out(1, 1, "CONTAKM 1.00    ")' Print text at LCD
     Lcd_Out(2, 1, "     by Matteo  ")' Print text at LCD



     delay_ms(1000)
     Lcd_Cmd(_Lcd_Clear)
     Lcd_Out(1, 10, "km/h")           ' Print text at LCD
     Lcd_Out(2, 1, "000000 km")       ' Print text at LCD


     CONTEGGIO:

     spazio = 0
     delay_ms(1000)                   'passa 1 secondo e rifaccio il calcolo
     velocita = ((spazio / tempo)*3.6)'formula che da la velocita
     floatToStr(velocita, output)

    ' Lcd_Cmd(_LCD_TURN_OFF)          ' Turn off cursor
     Lcd_Out(1, 1, output)            ' Print text at LCD
     
     goto CONTEGGIO
end.

Re: timer0 and counter pulse 6 years 6 months ago #12838

  • be80be
  • be80be's Avatar
  • Offline
  • Senior Boarder
  • Posts: 79
  • Thanks received: 90
Here This is in Swordfish i did it awhile back with some help from Mike
Device = 18F1220
Clock = 8 // 8MHz clock
Config OSC = INTIO2, WDT = OFF, LVP = OFF
Include "IntOSC8.bas"
Include "LCD.bas" 
Include "utils.bas" 
Include "Convert.bas"
 
// some LCD options...
#option LCD_DATA = PORTB.4
#option LCD_RS = PORTB.2
#option LCD_EN = PORTB.3
Dim button As PORTA.0 
Dim timer0_ON As T0CON.7
Dim timer0_OFF As T0CON.7
Dim TMR0 As TMR0L
 
//////////// sets up the timer0
Sub set_timer ()
T0CON.7 = 1 //sets timer0 on
T0CON.6 = 0  //sets to 16 bit timer
T0CON.5 = 1 //sets transition on T0CKI pin
T0CON.4 = 1 //sets hight to low transtion
T0CON.3 = 0 // turns on prescaler
T0CON.2 = 1
T0CON.1 = 1  //sets prescaler to 1:256
T0CON.0 = 1
TMR0 = 0 
INTCON.5 = 1
End Sub 
//////////////////////////////////////
Sub Get_fq()
     Dim Acc_byte0 As Byte      'You can't use a . here  so I change theat to underscore
    Dim Acc_byte1 As Byte
    Dim Acc_byte2 As Byte
    Dim value As LongWord
 
//
// Timer0 frequency counter example, Mike McLaren, K8LH
//
  TMR0H = 0                // clear Timer0 registers
  TMR0L = 0                //
 
  Input(PORTA.4)           // gate Timer0 counter "on"
  DelayMS(10)            //
  Output(PORTA.4)          // gate Timer0 counter "off"
 
  Acc_byte0 = 0            // count bits 00..07 (prescaler)
  Acc_byte1 = TMR0L        // count bits 08..15
  Acc_byte2 = TMR0H        // count bits 16..23
  //
//  toggle timer0 "source edge select" bit to 'bump' the prescaler
//  until it overflows into the TMR0L register
//
  While (TMR0L = Acc_byte1)
    T0CON.4 = 1            // toggle T0SE "source edge select" bit
    T0CON.4 = 0            //
    Dec(Acc_byte1)         //
                   //
 
 While true (TMR0L = Acc_byte1)
    value = Acc_byte1
 
      LCD.MoveCursor (2,1)
   LCD.Write(BinToStr (value))
 Wend
Wend    
End Sub 
 
//////////////////////////////////////
ADCON1=$70     //sets portb Digital
timer0_ON = 1   // turns timer0 on
timer0_OFF = 0  // turns timer0 off
SetAllDigital
While true
        //set_timer
 
    Repeat
        If button = 1 Then
 
        EndIf
 
        WriteAt(1,1,"Frequency Counter")
        DelayMS(500)
    Until button = 0 
         Cls  
        Get_fq       // just for testing           
Wend

Re: timer0 and counter pulse 6 years 6 months ago #12871

  • mast
  • mast's Avatar
  • Offline
  • Fresh Boarder
thank you be80be
Time to create page: 0.245 seconds