Go Down

Topic: How to program a pulse counter that is reset by another pulse (Read 622 times) previous topic - next topic

seth_ia

I'm new to the world of Arduino programming and programming in general, but am trying to learn as much as I can.  What I want an Arduino to do is count the number of pulse (square wave @ .5Hz to 2Hz max) received and display it on an LCD.  I want this total to be reset when another pulse(square wave @ .2Hz to .01Hz) is received on a second input.  The process then needs to then start over when the reset pulse is received.  I'll be using an Arduino Mega.  Is it possible to keep a serial port available to connect to a computer?  I evenually want the value shown on the LCD to also be sent to my desktop computer.

Can someone point me to any example code that might be close to what I'm trying todo? 

Any and all help is greatly appreciated as I'm new to this!

TIA!!!!!!!

PeterH

At those frequencies you don't need anything fancy - just poll the inputs looking for edges, maintain a global counter that is incremented when the first input goes active and resets to zero when the second input goes active. This would not preclude using the USB serial connection and/or connecting an LCD. Look for examples that do switch input detection and you will see how easy it is to do.
I only provide help via the forum - please do not contact me for private consultancy.

TanHadron

Counting pulses is something that interrupts were invented for.  Here's an example that I had.  You'll have to modify it to use LCD instead of Serial.

Code: [Select]


volatile int PulseCount = 0;

void Interrupt0Handler()
{
  ++PulseCount;
}

void Interrupt1Handler()
{
  PulseCount = 0;
}

void setup()
{
  pinMode(2, INPUT);  // Interrupt 0  on the Uno
  pinMode(3, INPUT);  // Interrupt 1 on the Uno
  attachInterrupt(0, Interrupt0Handler, RISING);   // Digital Pin 2 on the Uno
  attachInterrupt(1, Interrupt1Handler, RISING);   // Digital Pin 3 on the Uno
  Serial.begin(9600);
}

void loop()
{
  static int LastPulseCount = 0;

  if (LastPulseCount != PulseCount)
  {
    LastPulseCount = PulseCount;
    Serial.print("PulseCount = ");
    Serial.println(LastPulseCount);
  }
}


robtillaart

Perfect solution from TanHadron!

depending on the number of interrupts you might need to change :

volatile int PulseCount = 0;   ==>  volatile unsigned long PulseCount = 0;

LastPulseCount should change too ;)

But beware there is a chance you update the counter while it is compared

Code: [Select]

void loop()
{
  static int LastPulseCount = 0;

  noInterrupts();
  if (LastPulseCount != PulseCount)
  {
    LastPulseCount = PulseCount;
    interrupts();
    Serial.print("PulseCount = ");
    Serial.println(LastPulseCount);
  }
  interrupts();
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

TanHadron

Rob,

In this case, I don't think we really care if the interrupt happens after the compare and before setting LastPulseCount.  The result would be exactly the same as if the interrupt happened before the if statement.  That isn't a particularly critical section.  Disabling interrupts solves a problem that really isn't a problem.

robtillaart

Quote
That isn't a particularly critical section.

Except when the vars in question are 32 bit (long), as they cannot be assigned in one atomic machine instruction.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

PeterH

In my opinion, interrupts introduce sufficient complexity that they should only be used when necessary. A problem dealing with a pair of inputs carrying signals at around 1Hz is not IMO one that needs interrupts to solve, and the polling based solution is IMO considerably simpler because it eliminates concurrent execution. The polling implementation would be a trivial extension to the switch input / edge detection example to enable it to handle two inputs, with a single counter that can be any size you want, and you can update the display however and whenever you want using plain straight forward single threaded code.
I only provide help via the forum - please do not contact me for private consultancy.

TanHadron

@Rob: Good point.  I hadn't thought of that.

@PeterH: I have found interrupts on the Arduino to be incredibly easy.  However, it might be easier to poll it.  Let me see...

Code: [Select]

const byte PulsePin = 2;  // Or whatever
const byte ResetPin = 3;

void setup()
{
  pinMode(PulsePin, INPUT);
  pinMode(ResetPin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  static int PulseCount = 0;
  static byte PulseState = LOW, ResetPulseState = LOW;

  if (digitalRead(PulsePin) != PulseState)
  {
    if (PulseState == LOW)
    {
      PulseState = HIGH);
      ++PulseCount;
      Serial.print("PulseCount = ");
      Serial.println(PulseCount);
    }
    else
      PulseState = LOW;
  }

  if (digitalRead(ResetPin) != ResetPulseState)
  {
    if (ResetPulseState == LOW)
    {
      ResetPulseState = HIGH);
      PulseCount = 0;
      Serial.println("PulseCount = 0");
    }
    else
      ResetPulseState = LOW;
  }
}


You're probably right.  That does seem a little bit simpler to understand.  The only real advantage I can see of using interrupts in this case would be if the high time of the count pulse were very short.  It's not likely to be an issue.

seth_ia

Thank you for the examples! They are exactly what I was needing! They helped me a lot to unstand how the Arduino works.  Now I'll see if I can make it work on my own. 

Thanks!!!!!

PeterH


The only real advantage I can see of using interrupts in this case would be if the high time of the count pulse were very short.


I agree, if that was the case it would be a compelling reason to use interrupts.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up