Linking single channel encoder to a TIMER1/COUNTER

Hello Guys, I am a newbie. so don’t get angry if my question looks stupid.

what i was trying to do: I wanted to read number of ticks/ pulses generated on a incremental optical encoder using a timer1/counter which is configured as counter.

my connections and my code: The circuit is simple, I have a arduino UNO and an optical encoder

  1. connected VCC to 5v of UNO
  2. connected GND to GND of UNO
  3. connected pulse generating pin of PD5 of arduino UNO (pin 11 from pin-mapping)

my code:

unsigned long total_count;
volatile unsigned long overflow_count;
unsigned long timer1_current_value;

void total_counter_setup()
{
  total_count = 0;
  overflow_count = 0;

  // Initial reset
  TCCR1A = 0;
  TCCR1B = 0;

  // Interrupt when overflow
  TIMSK1 = bit (TOIE1);

  // Initially set value to zero and connect encoder channel to PD5 (pin 11 on arduino UNO)
  TCNT1 = 0;
  TCCR1B =  bit (CS10) | bit (CS11) | bit (CS12);
}

ISR (TIMER1_OVF_vect)
{
  ++overflow_count;
}

void setup ()
{
  total_counter_setup();
  Serial.begin(57600);
}

void loop ()
{
  
  timer1_current_value = TCNT1;
  Serial.println(TCNT1);
  if ((TIFR1 & bit (TOV1)) && timer1_current_value < 256)
  {
    overflow_count++;
  }
  total_count = (overflow_count << 16) + timer1_current_value;
//  Serial.println(total_count);
}

result:
I checked both total_count and TCNT1 in the serial monitor and i always read the reading is zero.

other test:
I checked the same encoder using interrupts INT0 and I found continous reading at lower speed but skipping values at higher rates.
My motivation to use counter is because from my understanding counter continuously counts the pulses in the background, so that my board will not be disturbed everytime a interrupt is generated and i only have to read the counter value when required.

This is my understanding and correct me if i am wrong.

Thanks in advance and any kind of help is highly appreciated.

I wanted to read number of ticks/ pulses generated on a incremental optical encoder using a timer1/counter which is configured as counter.

Sorry. That does not make sense. An encoder can be connected to an external interrupt pin, and generate interrupts when a change occurs. That way, you know about EVERY change - not just the ones that happen when you happen to be looking, because the timer fired.

PaulS: An encoder can be connected to an external interrupt pin, and generate interrupts when a change occurs.

Yes i have tried this by using mode rising. But what I want is to count the rising pulses without using interrupts.

PaulS: not just the ones that happen when you happen to be looking, because the timer fired. [\quote]

PaulS can you eloborate this. I am lost here.

Dark_LorD: Yes i have tried this by using mode rising. But what I want is to count the rising pulses without using interrupts.

Why?

Using an interrupt is easy and is the usual way?

I guess you might be able to use your encoder as the external clock source for a Timer - but you will need to read the Atmel datasheet a few times to figure out if that can be made to work.

...R

Robin2: Why?

Using an interrupt is easy and is the usual way?

Here I am also using an IMU mpu-6050 in I2C mode which also required an interrupt pin. Here, however I am having a TIMER free, so i wanted to use it (and also if i do on interrupts my both encoders take 2 interrupts and i will not be having one for IMU) and also I wanted to try this in counter since i am not using my 16bit timer.

I have read the Atmel datasheet and that is what I cam up with :/

Any advice is appreciated.

But what I want is to count the rising pulses without using interrupts.

So, why are you then trying to generate timer interrupts? Why do you think that that will be better? It won't, but I'm interested in your rationale.

PaulS can you eloborate this. I am lost here.

If the purpose of generating the timer interrupt is to read the encoder state in the interrupt handler, you'll either need to generate a boatload of interrupts, so you can be looking at the encoder often enough to not miss a single change, or you'll risk missing changes. If you go with the boatloads of interrupts, you'll have little time to do anything else. If you don't, you'll risk missing changes that happen when you aren't looking.

Think about it like this. You know that an encoder change is happening sometime today. That's like expecting a package to be delivered. You can install a doorbell, for the delivery person to ring when the package arrives. (That would be the external interrupt for the encoder to trigger). Or, you can run down the hall, down the stairs, and open the door, to see if the delivery person has arrived (that's what you are doing with the timer interrupt). If you don't happen to be looking out the door when the delivery person arrives, they will take your package and leave. Now, how often will you need to run out and check? That depends, to some extent, on how long the delivery person will wait, looking for the doorbell. A patient delivery person will mean that you can check say once every 30 seconds. An impatient delivery person will require you to check more often (perhaps even way more often).

Now, how are you going to make me cookies, and not burn them, when every 30 or 15 or 10 or 1 second, you have to keep running out to see if your package has arrived?

I really think the doorbell is a better idea. I do not like burnt cookies.

Here I am also using an IMU mpu-6050 in I2C mode which also required an interrupt pin.

So, NOW you mention this? You don’t think this was important up front?

Get a Mega, with more external interrupts.

Dark_LorD: I have read the Atmel datasheet and that is what I cam up with :/

Have you tried using a simpler input to the Timer pin (T1). For example connect a resistor between T1 and GND and then use a piece of wire to briefly connect T1 to +5v - just to make sure there is a good strong pulse.

...R

using a timer1/counter which is configured as counter.3. connected pulse generating pin of PD5 of arduino UNO (pin 11 from pin-mapping)

It’s not clear to me that you have your external pulse input going to digital pin 5 (D5) which is the external clock source input pin(T1) for Timer 1.

@Robin2 suggests

Have you tried using a simpler input to the Timer pin (T1). For example connect a resistor between T1 and GND and then use a piece of wire to briefly connect T1 to +5v - just to make sure there is a good strong pulse.

When I run your program with a square wave input I can see it counting.

Can you explain what you are trying to do with this line

if ((TIFR1 & bit (TOV1)) && timer1_current_value < 256)
[quote author=cattledog link=msg=3120751 date=1486485129]

if ((TIFR1 & bit (TOV1)) && timer1_current_value < 256)

[/quote]

There I was making sure that I didnot miss any overflow count.

Thanks cattledog Now i could got the reading my mistake was actually i connected that to pin 11 which is PD5 on atmega328 chip with your comment i just noticed it should be connected to digital pin 5. My bad! wasted lot of time

PaulS no offence but

Get a Mega, with more external interrupts.

is definitely not the solution for what i asked.

Dark_LorD: My bad! wasted lot of time

I also have that Tee Shirt :)

...R

PaulS no offence but ... is definitely not the solution for what i asked.

Perhaps now that the interrupt handler is being triggered by the timer, you'll explain what you intend to do in the interrupt handler with respect to getting data from the encoder.

How often are you triggering the interrupt? Does that leave time for doing other things? Or, do you spend so much time in the handler that you can't do anything else?

How often are you triggering the interrupt?

Every 65,535 counts.

Does that leave time for doing other things? Or, do you spend so much time in the handler that you can't do anything else?

Using of the Timer as a counter driven by an encoder pulse acting as the external clock source is much less processor intensive than counting in an ISR called by external, pinchange, or even input capture interrupt vectors.

How the OP is going to access the count and what he is going to do with it is unknown, but I believe he is counting in the way which has the least impact on other processes.

PaulS: Perhaps now that the interrupt handler is being triggered by the timer, you'll explain what you intend to do in the interrupt handler with respect to getting data from the encoder.

I think you have the wrong end of the stick.

The purpose of the ISR is (I believe) just to count the number of timer rolll-overs, Like counting how many times the hour-hand passes 12.

...R

Robin2: I think you have the wrong end of the stick.

The purpose of the ISR is (I believe) just to count the number of timer rolll-overs, Like counting how many times the hour-hand passes 12.

...R

Yes, My purpose of ISR is to count the number of over rolls so that, at any time by accesing the total_counts variable i can get the absolute value of ticks the encoder has passed

Using of the Timer as a counter driven by an encoder pulse acting as the external clock source is much less processor intensive than counting in an ISR called by external, pinchange, or even input capture interrupt vectors.

This is what I learned from my searching. So, i asked for help to use the timer as counter.

Perhaps now that the interrupt handler is being triggered by the timer, you'll explain what you intend to do in the interrupt handler with respect to getting data from the encoder.

My only aim was to get data from the encoder and i think I mentioned it enough clearly in my original post for your referral see below

My motivation to use counter is because from my understanding counter continuously counts the pulses in the background, so that my board will not be disturbed everytime a interrupt is generated and i only have to read the counter value when required.

How often are you triggering the interrupt? Does that leave time for doing other things? Or, do you spend so much time in the handler that you can't do anything else?

I am running motors at fair amount of speed and for every interrupt generated time difference will be atlest above 1ms. But I don't want to use get bigger boards for 1 external interrupt where nothing else is needed.

Finally, thanks Cattle dog this is what i wanted to say and what I am assuming is correct.

Using of the Timer as a counter driven by an encoder pulse acting as the external clock source is much less processor intensive than counting in an ISR called by external, pinchange, or even input capture interrupt vectors.

How the OP is going to access the count and he is counting in the way which has the least impact on other processes.

If I am wrong anywhere, please correct me.

Cheers.

Yes, My purpose of ISR is to count the number of over rolls so that, at any time by accesing the total_counts variable i can get the absolute value of ticks the encoder has passed

I guess I'm missing something. I see a relationship between total_counts and the number of times that the clock has ticked. I can not see a relationship between that and the number of times the encoder has generated a pulse.

My only aim was to get data from the encoder

I don't see where you are doing that. The timer ticking away has nothing to do with the encoder moving one way or the other, or not moving at all.

I'm happy that you got the timer issue squares away, but I am missing something that seems fairly obvious to everyone else.

I'd appreciate if someone could explain how knowing how many times the clock has ticked will tell you anything about the encoder position.

PaulS: I guess I'm missing something. I see a relationship between total_counts and the number of times that the clock has ticked. I can not see a relationship between that and the number of times the encoder has generated a pulse.

As I understand it, it is the pulses from the encoder that are causing the clock to tick. The HardwareTimer is just being used as a convenient counter. There is no time involved.

...R

Robin2: As I understand it, it is the pulses from the encoder that are causing the clock to tick. The HardwareTimer is just being used as a convenient counter. There is no time involved.

...R

Oh. I don't see how that will be useful for knowing which way the encoder is turning, but maybe that doesn't matter.

And, I don't see how that is substantially different from using an external interrupt. Perhaps that's because the pin being used in the timer way doesn't need to be an external interrupt pin.

Oh. I don't see how that will be useful for knowing which way the encoder is turning, but maybe that doesn't matter.

The thread title refers to a "single channel" encoder providing a pulse. There are no indications it is a a quadrature encoder which can indicate direction.

And, I don't see how that is substantially different from using an external interrupt. Perhaps that's because the pin being used in the timer way doesn't need to be an external interrupt pin.

It's also less processor intensive because all the counting(except for the rollover ISR) is in hardware, and there are no processor cycles spent entering and exiting the interrupt. The interrupt latency can be four to five microseconds with a 16MHz clock. http://gammon.com.au/interrupts

The thread title refers to a "single channel" encoder providing a pulse. There are no indications it is a a quadrature encoder which can indicate direction.

Good point.