Help counting pulses

Hello

I need some programming tips on how to do this:

I have a pulsing input (that will gradually build up and down between 0 and 4 Hz ) it will need to pulse an output at the same frequency until the input goes above a certain frequency (say 2 Hz )when I would like the output to remain constant at say 2 Hz. If the input then starts to drop below 2 Hz the LED will need to follow it.

This is low frequency, a mechanical wheel is going to flash an LED for an operator to watch. The actual frequency I will have to debug for accuracy, but the values here are near enough.

I understand inputs and outputs and the COUNT feature but I have no idea how to combine the counting and an output and then to hold that output until the input changes.

I hope this makes sense. The input device will be a Hall effect sensor with a magnet on the wheel.
 

hippy

Technical Support
Staff member
I haven't thought about the actual implementation but you are probably not going to be able to use blocking commands like COUNT or PULSIN on a single PICAXE.

I would guess an M2 and two tasks; one reading the input stream, determining its frequency, and another generating the output stream.

It might however be easier to use two PICAXE chips so the input can block and then update the outputting PICAXE using HSEROUT / HSERIN.
 
Thank you, that's a shame.

To use two Picaxe is above my pay grade.

So start0 would add the pulses to a variable and start1 could give an output I know how to do this, then clear the variable once it got to 2.

I was going to try this but if the frequency goes to 4 Hz the LED will give two pulses in the early part of the second and then a gap. I was trying to get even pulses.

Could I use a subroutine to give; even 2 Hz pulses while the variable is more than 2 and then drop out of the subroutine when it is 2 or less.

I was going to try this but thought the subroutine was not the best way, so I started on the COUNT path and got no where.

Thanks for the advice, I will try the two starts and see how it goes.
 

AllyCat

Senior Member
Hi,

2 Hz is quite "slow" even for a PICaxe, so it should be quite possible to do with a simple "polling" program loop. The main issues are how accurate the threshold time (i.e. 500 ms for 2 Hz) needs to be and how narrow is the "pulse" (i.e. its duty cycle). For a narrow pulse (perhaps less than 10 ms) you may need to use some form of "hardware assistance", but several possibilities are available even within the PICaxe chip.

A problem is that there is no readily available timing reference to "calibrate" the polling loop against the incoming frequency. A simple solution might be to put a (say) PAUSE 15 (15ms) in the loop. Then a short loop might repeat every ~20 ms, so a software count (incrementing once per polling loop) should reach about 25 with a period (between pulse edges) of 2 Hz.

For greater accuracy and/or a longer polling loop, you might "synchronise" the polling loop to "Timer 1" (using a PEEKSFR) which "rolls over" every 20 ms, or by reading a servo output pulse. Another factor to consider is how quickly the frequency of the pulses may change (e.g. the inertia of the wheel).

Cheers, Alan.
 
Last edited:

Buzby

Senior Member
I've not fully thought this through, but I think a single PICAXE could do this easily.

The task seems to be to copy the input signal to the output like-for-like, unless the input frequency is greater than 2Hz.
In that case the output should provide 2Hz regardless, until the input drops below 2Hz.

So a bit of code to measure the frequency could be used switch the output between either a fixed 2Hz clock, or the original input.

Sorry, I've not got time to try it just now.

Cheers,

Buzby
 

hippy

Technical Support
Staff member
Something like this may work but untested, not even tried simulation ...

Code:
#Picaxe 08M2

Symbol INPUT_PIN      = pinC.3
Symbol OUTPUT_PIN     = C.2

Symbol inputLoPeriod  = w0
Symbol inputHiPeriod  = w1

Symbol outputLoPeriod = w2
Symbol outputHiPeriod = w3

Symbol tmp            = w4

Start0:
  Do

    inputLoPeriod = 0
    Do While INPUT_PIN = 0
      inputLoPeriod = inputLoPeriod + 1
      Pause 20
    Loop
    outputLoPeriod = inputLoPeriod Min 6

    inputHiPeriod = 0
    Do While INPUT_PIN = 1
      inputHiPeriod = inputHiPeriod + 1
      Pause 20
    Loop
    outputHiPeriod = inputHiPeriod Min 6

  Loop

Start1:
  Do

    Low OUTPUT_PIN
    tmp = outputLoPeriod
    Do while tmp > 0
      tmp = tmp - 1
      Pause 20
    Loop

    High OUTPUT_PIN
    tmp = outputHiPeriod
    Do while tmp > 0
      tmp = tmp - 1
      Pause 20
    Loop

  Loop
One of the problems is that the M2's are locked at 16MHz when in multi-tasking mode and, AFAIR, PAUSE has to always be multiples of 20ms to be accurate, so the resolution is not high.

It might be possible to swap PAUSE for a low value PAUSEUS without significantly screwing up either input or output timing. As the output appears to be a LED it probably does not have to track too accurately.

It should be possible to generate a square wave output by combining the 'inputLoPeriod' and 'inputHiPeriod' to create a single high and low 'outputPeriod'.
 

hippy

Technical Support
Staff member
Here's a untested solution which avoids multi-tasking and doesn't use any blocking or PAUSE commands ...

Code:
#Picaxe 08M2

Symbol INPUT_PIN      = pinC.3
Symbol OUTPUT_PIN     = C.2

Symbol inputLoPeriod  = w0
Symbol inputHiPeriod  = w1

Symbol outputPeriod   = w2

Symbol tmp            = w3

Do

  inputLoPeriod = 0
  Do While INPUT_PIN = 0
    inputLoPeriod = inputLoPeriod + 1
    If tmp = 0 Then
      Toggle OUTPUT_PIN
      tmp = outputPeriod
    End If
    tmp = tmp - 1
  Loop
  outputPeriod = inputLoPeriod + inputHiPeriod / 2

  inputHiPeriod = 0
  Do While INPUT_PIN = 1
    inputHiPeriod = inputHiPeriod + 1
    If tmp = 0 Then
      Toggle OUTPUT_PIN
      tmp = outputPeriod
    End If
    tmp = tmp - 1
  Loop
  outputPeriod = inputLoPeriod + inputHiPeriod / 2

Loop
Those "outputPeriod = inputLoPeriod + inputHiPeriod / 2" lines may well need some adjustment to take into account different input and output rates and I have not included any limiting to 4Hz as that would depend on values read.

But it should be possible to run that up to any speed though it might need the counts to be capped along the way. Should be a reasonable starting point though.
 
Top