Frequency of a pulse signal

Hi, i have a project in Uni where i have to count the number of pulses received from an encoder, so i can have the frequency. This frequency should be read every second, and printed in the serial monitor (just to take note)
I ve seen some codes already, but my professor said i have to use an interrupt cycle.
I m pretty new to arduino, so im havind some trouble finding a solution.
Can anybody send a similar code or a solution for this?

So we are to do your homework for you? Will we get credit?

frequency measurement.

Is that because (s)he believes it's the only/best solution, or because (s)he requires it as part of your learning process?

What is the anticipated frequency of this signal? Are we talking a few Hz, ar a couple hundred Hz, or faster? What is the anticipated pulse duration / duty cycle of the signal?

He believes its the best solution. The encoder is associated to a eletric motor of maximum speed 4000 rpm, and the encoder has 53 stripes, so at full speed (in this machine we normally go for lower speeds) the pulse signal has 12,72 MHz. I dont know the duty cycle

i've found that an interrupt is needed to properly read an encoder even when spun with fingers

do you actually read the frequency from the encoder?

wouldn't the interrupt simply update a count?

how often would there be an output? what determines when to update the output?

what are the values needed to update the output?

Ok, forget about trying to read ~12MHz signals with an UNO for frequency determination. You'll need a way faster microcontroller to do that.

The enconder will give an pulse signal, if i count the number of pulses in a determined time i can have the frequency in that part of time.
It would be perfet if i could get an output every 0.5s to 1s.
I dont really know if the interrupt is needed i made one code, from some codes ive seen in here, that doesnt use interrupt.

Hi,

?????
4000 rpm = 4000 / 60 = 6.66 revs per second.
53 stripes per revolution.
6.66 x 53 = 3,533 Hz.
Where do you get 12,720,000 Hz ?
(4000 x 60 x 53 = 12,720, 000 Hz )

Can you post a link to data/specs of the encoder please?
Even if it is a quadrature encoder, for a speed/frequency reading you only need one channel.

Can you please post the task sheet as it was given to you please?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Is your pulse signal produced by the stripes or by the empty space between the stripes? The normal, industrial devices send the pulse when then the IR light passes through the open space. Then you have 52 open spaces.

how often are you outputting a frequency?
when do you need to calculate the frequency?
what do you need to do after each update to keep track of things?

4000 * 53 is 212000 pulses per MINUTE. That is under 3,6 kHz. Nowhere near 12 MHz.

const byte EncoderPin = 2;  // Must be external interrupt pin

const unsigned PulsesPerRevolution = 53;
const unsigned long PrintInterval = 1000;

volatile unsigned long EncoderCount = 0;

void EncoderISR()
{
  EncoderCount++;
}

void setup()
{
  Serial.begin(115200);
  delay(200);
  
  pinMode(EncoderPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(EncoderPin), EncoderISR, FALLING);
}

void loop()
{
  unsigned long currentMillis = millis();
  static unsigned long lastPrintTime = 0;

  if (currentMillis - lastPrintTime >= PrintInterval)
  {
    lastPrintTime = currentMillis;

    // Disable interrupts while reading/writing volatiles
    noInterrupts();
    unsigned long encoderCountInLastSecond = EncoderCount;
    EncoderCount = 0;
    interrupts();

    Serial.print(encoderCountInLastSecond * 60 / PulsesPerRevolution);
    Serial.println(" RPM");
  }
}

1. Connect your Encoder's output with DPin-2 of UNO as per Fig-1.

intzrxEncoder
Figure-1:

2. The output of the encoder is a series of pulses. Every pulse has the following four characteristics (Fig-2).
pulseCharac
Figure-2:

(1) Low (active low = AL)
(2) Rising Edge (RE)
(3) High (active high = AH)
(4) Falling Edge (FE)

3. Let us allow the Falling Edge (known as Trigger Level) of the encoder signal to interrupt the MCU.

4. In an interrupt process/cycle, the MCU usually remains busy in doing something what is called "Main Line Program (MLP)". The MLP for the MCU could the job of continuously checking if 1-sec time is over or not. This 1-sec time is the period over which, the MCU will be counting the encoder pulses.

5. When an interrupt occurs by the falling edge of the encoder pulse, the MLP is suspended. The MCU goes to a side job (called ISR for Interrupt Sub Routine), increments a "Pulse Counter" and then returns to the MLP.

6. At the end of 1-sec period, the MCU reads the Pulse Counter and shows the value on the Serial Monitor.

7. The relation among DPin-2 (the interrupt pin), ISR (myISR), and Trigger Level (FALLING) are established/declared by the following command/function:

attachInterrupt(digitalPinToInterrupt(2), myISR, FALLING);

8. You can upload the following test sketch in UNO; where, the interrupting signals (2 kHz) are automatically coming from DPin-9 of UNO. So, at the moment do not use the encoder and short DPin-9 to DPin-2.

int pulseCounter = 0;
unsigned long prMillis = millis();

void setup()
{
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  { //-- to simulate 2 kHz interrupting signal----
    bitClear(TCCR1B, WGM13);
    bitSet(TCCR1B, WGM12);
    bitClear(TCCR1A, WGM11);
    bitClear(TCCR1A, WGM10);

    bitClear(TCCR1A, COM1A1);
    bitSet(TCCR1A, COM1A0);
    pinMode(9, OUTPUT);

    OCR1A = 3999;  // for 2 kHz
    TCNT1 = 0x0000;

    bitClear(TCCR1B, CS12);
    bitClear(TCCR1B, CS11);
    bitSet(TCCR1B, CS10);
  }
  attachInterrupt(digitalPinToInterrupt(2), myISR, FALLING);
}

void loop()
{
  if (millis() - prMillis >= 1000)
  {
    prMillis = millis();
    Serial.print("Pulses counted in 1-sec time is: ");
    Serial.println(pulseCounter);
    pulseCounter = 0;
  }
}

void myISR()
{
  pulseCounter++;
}

9. Output:

Pulses counted in 1-sec time is: 1999
Pulses counted in 1-sec time is: 2000
Pulses counted in 1-sec time is: 1998

10. Read post #11 to see that there are good reasons for declaring the pulseCounter to be volatile and the interrupt logic should be disabled before reading the pulseCounter. For the shake of simplicity, I have not included these features in the sketch of Step-8.

you are right, I m sorry for the math.
Thanks!
It wasnt given a task sheet. I have a project wich i have to do an aquisition system of a machine. I m almost done, but the part envolving the arduino was really bugging me, cause i never had this type o programming language. But the task is what i said. i will have a pulse signal leaving the encoder and have to count the pulses in a second (or less) every second. This is so i can get the distance of the platform, of the machine.

I understood it, thanks so much for your time!

You are totally right, another mistake i didnt see
Thanks!

You are my savior John!
I understand it all!
Thank you so much