I'm still kinda new to all of this so bare with me. What I have is a motor that is only going one direction, so I only need the A channel of the encoder. When I try the example for a Rotary Encoder in the Playground it misses more than half of the steps.
The encoder has 624 counts per revolution. So what I heard you can do is connect it to a hardware Counter on the Arduino because that is very accurate.
I can't seem to find any examples of that or even the right pin to use. I heard Pin 5 somewhere but I'm still not sure. Any help would be greatly appreciated.
Ok so after looking around those sites I think I found what I needed but I'm not sure why it won't work.
When I run the code the counter just counts up infinitely without me ever turning the motor/encoder. My only guess is that your code was based off of the ATmega128 and I'm using the ATmega328. So maybe some of the registers are different.
Any Help would be greatly appreciated,
Cory
#define ENCODER_READ 5
unsigned int encoderPos;
void setup()
{
Serial.begin(19200);
counterStart();
}
void loop()
{
encoderPos = getCount();
Serial.println(encoderPos);
}
// call this to initialize the counter
void counterStart()
{
// hardware counter setup, see p. 107 for info on the 16-bit Timer1 Timer/Counter
TCCR1A=0; // reset timer/countern control register A
TCCR1B=0; // reset timer/countern control register B
TCNT1=0; // initialize the counter value to 0; this register holds the current count
// set timer/counter1 hardware as a counter; it counts events on pin Tn (Arduino pin 5)
// normal mode, wgm10 .. wgm13 = 0, see p. 131, table 13-4
TCCR1B = TCCR1B | 7; // Counter Clock source = pin Tn (Arduino pin 5) , start counting now
// 7 in binary is 0111; OR-ing will set CS10,11,12 to 1's
// External clock source on Tn pin. Clock on rising edge., see table 13-5, p. 132
}
// call this to get the current count
unsigned int getCount()
{
unsigned int count; // this variable returns the current encoder count from the counting register
TCCR1B = TCCR1B & ~7; // Gate Off / Counter Tn stopped, see table 13-5, p. 132; we need to disable counting just prior to our read
// this operation clears the bits (CS10,11,12)
count = TCNT1; // read the counting register
TCCR1B = TCCR1B | 7; // re-start counting by resetting the bits (CS10,11,12)
return count; // return the retreived count to the calling function
}
I've got something similar working, and the only difference that I can see is to include <avr/io.h> and to set pin 5 as in input in setup()
My problem at the moment is reading the value from TCNT1.
TCNT1 is a 16 bit counter, but when I print the values they count up to 255 and start decreasing again.
#include <avr/io.h>
#include <avr/interrupt.h>
// set pin numbers:
int encoderPin = 5;
int OVF_count = 0;
void setup() {
pinMode(encoderPin, INPUT);
Serial.begin(9600);
Serial.println("Initializing timerinterrupt");
//**************************************************
// TIMER 2 SETUP
// **************************************************
// 8 bit timer on 16MHz clock using 1024 precaler
// >> ~61 overflows per second
TCCR2A = 0;
// set the prescaler for timer0 to 1024
TCCR2B |= (1<<CS22)|(1<<CS21)|(1<<CS20);
// enable overflow intterupts for timer0
TIMSK2 |= (1<<TOIE2);
// initailize the counter
TCNT2 = 0;
//*****************************************************
//TIMER 1 SETUP
//*****************************************************
TCCR1B = 0b00000111; //Set T1 as input
TCNT1 = 0; // Initialize
}
//*************************************************************
// TIMER 2 INTERRUPT SERVICE ROUTINE
//*************************************************************
ISR(TIMER2_OVF_vect){
OVF_count++;
if (OVF_count == 30){// should print about twice per second
long Encoder_clicks = TCNT1;
OVF_count = 0;
Serial.println(Encoder_clicks);
}
}
//*************************************************************
// MAIN LOOP
//*************************************************************
void loop(){
while(1)
{
}
}
Hello I have problem with this code i'm using Arduino Mega 1280 and all what i get on serial is endless "0". Do you have any solution for me??
Thanks
edit:
i found this
Functions not available on Mega
PD 4 ICP1
PD 6 T1 (external counter) <-------HERE
PE 6 T3, Int 6
PE 7 Int 7, ICP3
PH 7 T4 (external counter)PJ 2 Pin Int 11
according to table which is placed in link above
arduino 168/328 pin5 PD 5 PWM T0B
Arduino mega pin5 is marked as something else but pin4 PG PWM T0B
so I plugged it into pin 4 and it still view only "0"
EDIT: So i found solution how to use Hardware Counter on Arduino Mega 1280
There is no T1 working But there is T0. You need to attach encoder to pin 38 and change T1 in code to T0 here is working example.
#include <avr/io.h>
#include <avr/interrupt.h>
// set pin numbers:
int encoderPin = 38;
int OVF_count = 0;
void setup() {
pinMode(encoderPin, INPUT);
Serial.begin(9600);
Serial.println("Initializing timerinterrupt");
//**************************************************
// TIMER 2 SETUP
// **************************************************
// 8 bit timer on 16MHz clock using 1024 precaler
// >> ~61 overflows per second
TCCR2A = 0;
// set the prescaler for timer0 to 1024
TCCR2B |= (1<<CS22)|(1<<CS21)|(1<<CS20);
// enable overflow intterupts for timer0
TIMSK2 |= (1<<TOIE2);
// initailize the counter
TCNT2 = 0;
//*****************************************************
//TIMER 1 SETUP
//*****************************************************
TCCR0B = 0b00000111; //Set T1 as input
TCNT0 = 0; // Initialize
}
//*************************************************************
// TIMER 2 INTERRUPT SERVICE ROUTINE
//*************************************************************
ISR(TIMER2_OVF_vect){
OVF_count++;
if (OVF_count == 30){// should print about twice per second
long Encoder_clicks = TCNT0;
OVF_count = 0;
Serial.println(Encoder_clicks);
}
}
//*************************************************************
// MAIN LOOP
//*************************************************************
void loop(){
while(1)
{
}
}