Menu

RPM measurement PIC16F628

Help
Capaction
2009-07-20
2013-05-30
  • Capaction

    Capaction - 2009-07-20

    My project is on a PIC16F628   4MHz  with a Hall sensor TLE4905 on Pin 6  ie  RB0/INT.
    I would like to measure the cycle time in microseconde for one cycle. As the engine does not give a very regular speed I would like to take an average on several revolutions.
    I do not see how to do this with Great Cow Basic.
    I would appreciate to get a coding sample or links on this matter.
    Thanks a lot,
    Jacques eMail:  capaction  at  free.fr

     
    • Hugh Considine

      Hugh Considine - 2009-07-20

      There are 2 ways I can see to go about this, unfortunately both will involve some slightly complex coding.

      The first option is to use some inline assembly code to measure the time between pulses. You can mix assembly code and GCBASIC code in the same program, but the bit of code for measuring time would have to be written in assembly - a downside to using a high level language is that it's hard to get exact timing. The code would have to keep checking the bit to see if it has changed, incrementing a counter if it hasn't.

      A better idea would be to use the Capture mode of the CCP module on the PIC. This would require moving the input to the CCP1 pin, which is on PORTB.3. Then, start timer 1 and set the CCP1CON register so that Capture mode is enabled. When something happens on CCP1, the current timer 1 value will be copied into the CCPR1H and CCPR1L registers, and the CCP interrupt will occur. Here is some sample code showing how to do this:

      'Set up timer
      InitTimer1 Osc, PS1_1/1
      ClearTimer 1
      StartTimer 1

      'Set up CCP
      On Interrupt CCP Call PulseReceived
      CCP1CON = b'00000101'
      Dim CapturedTime As Word Alias CCPR1H, CCPR1L

      Then a bit further down in your code, after the main routine:

      Sub PulseReceived
          'Clear and restart time
          ClearTimer 1
          StartTimer 1
         
          'Get time since last pulse
          Dim TimeDifference As Word
          TimeDifference = CapturedTime
         
          'Now do whatever you need to do with the time
          'On a 4 MHz chip, with a 1/1 prescaler, Timer 1 will increment every microsecond
          'So the value in TimeDifference is the time in microseconds since anything happened
          '
          ' ...
          '
      End Sub

       
    • Nobody/Anonymous

      let's do it in tricky and mathematic way... let's assmume that max 12 000 rpm. it is 200 revolutions per second. 200 Hz only. if you need to display data once per second, than it could be easy. just make timer routine who count pulses in one second and multiply by 60 and send to display. I recomend You to use different oscillator frequency. why? look on this greant tavle of common crystal oscillators frequenncies: http://en.wikipedia.org/wiki/Crystal_oscillator#Commonly_used_crystal_frequencies

      now info from datasheet: oscilator frequency is dividet by 4 to get clock frequency. from clock frequency is updatind timer and this is step for cpu instructions. if you are using 4 mhz oscillator than you can get 1 million instructions per second (1 MIPS). also internal timer frequency is 1 MHz. now little tricky part: timer is 8 bit counter. divide 1 MHZ to 256 to get how often timer will be overloaded: 3906.25 timer verload per second. this is bad because have decimal part. if you will use 4,096 MHZ clock than you will get exactly 4000 timer owerflows per second. all data if you are not using prescaler. now! write interrupt subrutine when timer is overloaded.

      some pseido code (geeks will write correct gcbasic code from this idea):

      #chip 16F628, 4 MHZ  'actualy we have 4.096 MHZ

      #config blablabla

      #define portb.0 sensor

      dim postscaler as word      'because we have 4000 per second
      dim sensordata as word     'just in case because we have 200 pulses per socons on max and we don't want to woverload this variable

      dim workdata as word        'should be same as sensordata
      dim displaydata as word   'this is display buffer

      on timer interrupt goto timeoverflow
      on portb.o interrupt goto countsensor

      setup:
      postscaler=0

      main:

      if postscaler>4000 then
      clear postscaler
      call prepare data
      call show data on display
      end if

      goto main
      END PROGRAM

      sub timer overflow
      postscaler ++
      end sub

      sub countsensor
      sensordata ++
      end sub

      sub prepare data
      disable sensor interrupt
      workdata=sensordata
      sensordata=0
      enable sensor interrupt
      displaydata=workdata * 60
      end sub

      sub displaydata
      send displaydata to LCD or whatever
      end sub

      this is my idea. this isnt the most precise algorythm, but any way. the error is following:
      1 revolution per seond=60 rpm.
      if you have 100 rps, tha it is 6000 rpm.
      if you miss 1 rps tha you will get 99 rps=5940 rpm
      this is algoryth error.
      if you want tu apdate data 10 times per second you will get more error.
      6000 rpm=10 revolutons per ten times second.
      if you miss now one pulse tha you will get 9 revolutons per ten times second.
      this is 5400 rpm. big difference if in true there 6000 rpm?

      is this idea good for you?

      another ide is to sount time betwenn two pulses.
      if we assume 12000 rmp that is 200 pulses/second, 5 milisecons between two pulses.
      clock owerload is 4000 times per secons, 4 khz, 200 microsecons per overload.
      now start timer when get pulse.
      on next pulse stop timer, calculate difference between two pulses and sotre somewhere.
      etc.
      i am thinking now on preido code for this...
      will post later.

      sorry for my mistakes in text. I am typing on my eeePC.

       
    • Nobody/Anonymous

      it is enough to display data 3-4 times per second. error will be +/- 180 or 240 rpm. I don't have a car or understand lot of real engine rpm, but i think that this error is OK for engine. make your calculations for your real situation! Also high refresh rate isn't readable on LCDs.

      Remember: interrupts must be as short as possible or you can miss pulses from sensor!

      Anyway this is how i get 19200 bit/s bit banging rs232 using 16f84a with 19,66 mhz clock.

       

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.