Pulse-In function example

General discussion on mikroBasic.
Author
Message
User avatar
marko
mikroElektronika team
Posts: 916
Joined: 02 Feb 2005 16:09
Location: Europe
Contact:

Pulse-In function example

#1 Post by marko » 15 Sep 2006 09:11

This code demonstrates using Pulse-In Function (similar to PBP "PULSIN" command) for counting pulses in given time period. This a blocking call. This demo waits for input signal (high level) to start counting pulses. It counts pulses for 1000 miliseconds. Then it prints results on LCD which is connected on PORTB. Here is the link for download:

Download pulsein.zip

---
Best Regards
"Good ideas are not complicated, they are
complex, but we are making it easy !!!"

jomref
Posts: 8
Joined: 25 Feb 2007 19:17

#2 Post by jomref » 19 Feb 2008 22:11

Using TMR0 in 16bit counter and 8MHz osc with 1:8 prescale do I get a TMR rollover every ms(millisec). Trying to figure Pulsein_demo but I must have a bad day. Can anyone help me with this simple math?

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#3 Post by janni » 19 Feb 2008 23:41

jomref wrote:Using TMR0 in 16bit counter and 8MHz osc with 1:8 prescale do I get a TMR rollover every ms(millisec)?
Nope, every 262ms in timer mode. You'll get ca. 1ms with 8 bit Timer0 mode.

drumissimo
Posts: 18
Joined: 17 Jan 2007 03:07
Location: PA
Contact:

pulsin command

#4 Post by drumissimo » 20 Feb 2008 05:32

Marko,

To continue with the "wishlist" request, could the duration in the function below be time the pulse is at a certain transition (either high or low)?
Which would actually measure the pulse width in milliseconds for any input pin?

sub function Pulse_In(dim byref port as byte, dim pin, state as byte, dim duration as word)as word

regards,
drumissimo
Otis

Acetronics
Posts: 715
Joined: 27 Dec 2006 14:33
Location: Le Tréport , FRANCE

#5 Post by Acetronics » 26 Aug 2008 10:41

Hi, Marko

PULSIN returns the time a pin stays in a given state, and not how many pulses were incoming during a given time ...

What you described is "COUNT" called function ...

Alain

trust issues
Posts: 231
Joined: 14 Nov 2004 19:43

#6 Post by trust issues » 26 Aug 2008 11:19

Haha looks like you guys beat me to it. I finished a design for a Pulse In library for P18's and have just been working on one for P16's.
Mine has 2 methods, one for accuracy between 0-3Khz and one for above that.

DDJ
Posts: 15
Joined: 30 Jun 2008 07:10

#7 Post by DDJ » 27 Aug 2008 10:47

Hi Guys
Does the pulse_in function really just measure the time and not the pulses? If so, which function measures pulses and where do I find it ?
Is it similar to "counter" in proton ?

Thanks

Charlie
Posts: 2744
Joined: 01 Dec 2004 22:29

#8 Post by Charlie » 27 Aug 2008 12:33

Is it similar to "counter" in proton
No. MB does not have a counter command. You will have to use a timer for that.
Regards Charlie M.

DDJ
Posts: 15
Joined: 30 Jun 2008 07:10

How ?

#9 Post by DDJ » 27 Aug 2008 13:13

How do I use a counter to measure pulses ? Please explain in step by step if possible.
Thanks

Charlie
Posts: 2744
Joined: 01 Dec 2004 22:29

#10 Post by Charlie » 27 Aug 2008 13:54

Well to use the counter command here is a example.
Dim puls as word

Main:

puls = Counter,PORTA.0,1000 ' count a pulse every secondon porta.1
rpm=puls*60 ' convert pulses per second to Revs per min.

and print to a LCD.

But..... Mb don't have the counter command. so you will have to do it the hard way. sorry.
Regards Charlie M.

DDJ
Posts: 15
Joined: 30 Jun 2008 07:10

Counter

#11 Post by DDJ » 27 Aug 2008 15:15

Thanks Charlie

By saying I have to do it the hard way round, is that with a counter. Please have a look at my code. I'm trying to measure pulses from a cd4093 and write them to a lcd. I have a capacitive fuel sensor connected to the cd4093. I have the bargraph on the 2nd line of a 8x2 lcd and the pulses on the first line. I just don't know how to convert the pulse count to a value on the lcd.

Code: Select all

'Pulse-in LCD 8 x 2
'16F684
program pulse
dim count1 as word
dim bar as byte
dim border as byte
dim location as byte
dim text3 as string[4]
    text4 as string[4]
dim counter,
    msec,
    num_impulse as word
    text1 as word
    txt         as char[30]

sub procedure interrupt
   inc(counter)                               ' Increment value of counter on every interrupt
   if counter = 1 then                        ' Has 1ms elapsed?
     counter = 0                              ' Clear the counter
     inc(msec)                                ' Increment msec on every 1 ms
   end if
   TMR0 = 5
   ClearBit(INTCON, T0IF)                     ' Clear the TMR0IF flag
   SetBit(INTCON, T0IE)                       ' Enable TMR0 interrupt
end sub

sub function Pulse_In(dim byref port as byte, dim pin, state as byte, dim duration as word)as word
dim tmp as word                               ' Temporary variable
    old as byte                               ' Previous pin state value

  while TestBit(port, pin) = state            ' Wait for pulses
  wend                                        ' Note that the program will stop here
                                              '   if there are no pulses

  while TestBit(port, pin) <> state           ' Wait for rising (falling) edge
  wend                                        ' Note that the program will stop here
                                              '   if there are no pulses

  tmp  = 0                                    ' Clear temporary variable
  msec = 0                                    ' Clear number of ms
  old  = TestBit(port, pin)                   ' Get current pin state

  while duration > msec                       ' Check if duration is reached
     if (TestBit(port, pin)) <> old then      ' Check if pin state has changed
        inc(tmp)                              ' Increment number of pulses
        old = TestBit(port, pin)              ' Get current pin state
     end if
  wend

    result = (tmp >> 1) + 1                   ' Assign result value
end sub
sub procedure LCD_BarGraph_Init
      bar = 0
     for location = 64 to 104 step 8
     Lcd_Cmd(location)
     border = bar or 21
     LCD_Chr_CP(0)
     LCD_Chr_CP(border)
     LCD_Chr_CP(bar)
     LCD_Chr_CP(bar)
     LCD_Chr_CP(bar)
     LCD_Chr_CP(bar)
     LCD_Chr_CP(border)
     LCD_Chr_CP(0)
     bar = bar or 32
     bar = bar >> 1
     next location
end sub
sub procedure LCD_BarGraph_Draw(dim Row as byte, dim Column_Start as byte, dim Column_End as byte, dim Value as byte)
    while Value >= 5
          Lcd_Chr(Row, Column_Start, 5)
          Column_Start = Column_Start + 1
          Value = Value - 5
    wend
    while Column_Start <> Column_End + 1
          Lcd_Chr(Row, Column_Start, Value)
          Value = 0
          Column_Start = Column_Start + 1
     wend
     end sub

main:
  ANSEL = 0                                   'mods by DDJ
  OPTION_REG = 2                              ' Assign prescaler to TMR0 (1:8)
  TRISC  = $00                                ' Designate PORTC as output
  PORTC  = $FF                                ' Initialize PORTC
  CMCON0 = 7
  TRISA  = $FF                                ' Designate PORTA as input (for signal)

  counter= $00                                ' Initialize the counter
  TMR0  = 5
  INTCON = $A0                                ' Enable TMRO interrupt

  msec = 0                                    ' Clear msec
  num_impulse = 0                             ' Clear num_impulse


  'ADCON1 = $FF                               'mod by DDJ  PORTB all digital
  'CMCON  = $06                               'mod by DDJ  Comparators off
  
  text3 = "E"
  text4 = "F"
  Lcd_Config(PORTC,3,2,1,0,PORTC,4,7,5)       ' Initialize LCD connected to PORTC
  LCD_BarGraph_Init()
  Lcd_Cmd(LCD_CLEAR)                          ' Send command to LCD "clear display"
  Lcd_Cmd(LCD_CURSOR_OFF)                     ' Send command "cursor off"

  while 1 = 1

  num_impulse = Pulse_In(PORTA, 2, 1, 2000)   ' Count HI pulses on PORTA.2, for 1000ms

  count1 = num_impulse

     WordToStr(count1, txt)                 ' Convert results to string for LCD output
     lcd_out(1,1,txt)

     LCD_BarGraph_Draw(2, 2, 7, 6)    'value scale = 1 to 30 for 0 to full bar

     Lcd_Out(2, 8, text4)
     Lcd_Out(2, 1, text3)



    wend
  
  
  

  'lcd_Out(1, 1, "Pulses")           ' Print txt to LCD
 ' Lcd_Out(1, 1, txt)                          ' Print number of pulses to LCD

  'wend                                        ' Wait forever (stop)
end.

Thanks a lot for your help

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Pulse-In function example

#12 Post by Dany » 27 Aug 2008 18:08

Hi Marko, what is the purpose of the "Counter" variable? It toggles continuously between 0 and 1 (it is always zero when entering the interrupt routine, subsequently incremented and again set to zero), and and is not used further.

Code: Select all

procedure interrupt;
begin
   inc(counter);                                // Increment value of counter on every interrupt
   if counter = 1 then                          // Has 1ms elapsed?
     begin
        counter := 0;                           // Clear the counter
        inc(msec);                              // Increment msec on every 1 ms
     end;
   TMR0 := 5;
   ClearBit(INTCON, T0IF);                      // Clear the TMR0IF flag
   SetBit(INTCON, T0IE);                        // Enable TMR0 interrupt
end;
Thanks in advance. :D

(I assume it is a leftover from the time that the measuretime always was 1 sec, and not parameterized...)
Last edited by Dany on 27 Aug 2008 18:31, edited 1 time in total.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Counter

#13 Post by Dany » 27 Aug 2008 18:24

DDJ wrote:

Code: Select all

  num_impulse = Pulse_In(PORTA, 2, 1, 2000)   ' Count HI pulses on PORTA.2, for 1000ms
Hi, something is wrong here: or the code is wrong, or the comment is wrong (I think): 2000 versus 1000 millisecs.
DDJ wrote:I'm trying to measure pulses from a cd4093 and write them to a lcd.
This is a little bit vague "to measure pulses". What the code does in measuring the number of pulses per time (in your case a time of 2 seconds). So, it is the "frequency" (in your case half the frequency, since you measure for 2 seconds) that is measured. I assume this is indeed what is wanted :?:
Last edited by Dany on 27 Aug 2008 18:42, edited 1 time in total.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Counter

#14 Post by Dany » 27 Aug 2008 18:35

DDJ wrote:I just don't know how to convert the pulse count to a value on the lcd.

Code: Select all

  
  'lcd_Out(1, 1, "Pulses")           ' Print txt to LCD
 ' Lcd_Out(1, 1, txt)                          ' Print number of pulses to LCD

  'wend                                        ' Wait forever (stop)
end.

Thanks a lot for your help
What about

Code: Select all

 
  lcd_Out(1, 1, "Pulses")           ' Print txt to LCD
  WordToStr(num_impulse, txt)
  Lcd_Out(1, 1, txt)                          ' Print number of pulses to  
LCD
:?:

erratum:
I now see that you had it already, does this not work?

Code: Select all

count1 = num_impulse

     WordToStr(count1, txt)                 ' Convert results to string for LCD output
     lcd_out(1,1,txt) 
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

#15 Post by Dany » 27 Aug 2008 18:45

Code: Select all

count1 = num_impulse
     WordToStr(count1, txt)                 ' Convert results to string for LCD output
     Lcd_out(1,1,txt)
     LCD_BarGraph_Draw(2, 2, 7, count1)    'value scale = 1 to 30 for 0 to full bar
Above would be at first glance adapted to show the pulsecount also on the bar graph. There is only one small problem: the last parameter of "LCD_BarGraph_Draw" is of a byte type in stead of a word type. :D
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Post Reply

Return to “mikroBasic General”