I am newbie in Arduino , I had the code below designing for one of microcontroller types to read encoder position
now i want to convert it to Arduino sketch (i.e setup() , Loop()) so I could upload it on my Arduino uno but i don't know how to do that ?
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
//global variables: encoder position and direction of rotation
volatile unsigned int enc_pos; // use unsigned long for large distances
volatile unsigned char enc_dir;
/*
PORTC Pin change interrupt service routine. Decodes the encoder.
For algorithm, see Scott Edwards article from Nuts&Volts V1 Oct. 1995
(righthand bit of old A,B) xor (lefthand bit of new A,B) => dir.
Increment or decrement encoder position accordingly
*/
ISR (PCINT1_vect) {
static unsigned char enc_last=0,enc_now;
enc_now = (PINC & (3<<PC4))>>4; //read the port pins and shift result to bottom bits
enc_dir = ( enc_last & 1 )^( (enc_now & 2)>>1 ); //determine direction of rotation
if (enc_dir == 0) enc_pos++;
else enc_pos--; //update encoder position
enc_last = enc_now; //remember last state
}
int main(void)
{
enc_pos=0; //Initialize encoder position
DDRC &= ~(3<<PC4); //Port C pins 4 and 5 as input
PCMSK1 |= (3<<PCINT12); //enable interrupt on pin change, bits 4&5 PORTC
PCICR |= 1<<PCIE1; //enable interrupt on pin change, PORTC
sei(); //enable global interrupts
}
also I need to understand how to manipulate with direct port of Arduino , i read about it in the Arduino reference but it is still not completely clear to me .
for example
enc_now = (PINC & (3<<PC4))>>4; //read the port pins and shift result to bottom bits
this command to read the port pins and shift result to bottom bits , I need to understand how it works , what these numbers and signs "<<"
also for this
DDRC &= ~(3<<PC4); //Port C pins 4 and 5 as input
PCMSK1 |= (3<<PCINT12); //enable interrupt on pin change, bits 4&5 PORTC
PCICR |= 1<<PCIE1; //enable interrupt on pin change, PORTC
If you want to use setup() and loop(), just add them, move the contents of int main into setup and then delete the int main function. However the internal init() function may mess with your setup.
If you change PC3 to PINC3 and PC4 to DDC4 to match the names in the datasheet, it compiles without further changes.
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
//global variables: encoder position and direction of rotation
volatile unsigned int enc_pos; // use unsigned long for large distances
volatile unsigned char enc_dir;
/*
PORTC Pin change interrupt service routine. Decodes the encoder.
For algorithm, see Scott Edwards article from Nuts&Volts V1 Oct. 1995
(righthand bit of old A,B) xor (lefthand bit of new A,B) => dir.
Increment or decrement encoder position accordingly
*/
ISR (PCINT1_vect) {
static unsigned char enc_last=0,enc_now;
enc_now = (PINC & (3<<PINC4))>>4; //read the port pins and shift result to bottom bits
enc_dir = ( enc_last & 1 )^( (enc_now & 2)>>1 ); //determine direction of rotation
if (enc_dir == 0) enc_pos++;
else enc_pos--; //update encoder position
enc_last = enc_now; //remember last state
}
int main(void)
{
enc_pos=0; //Initialize encoder position
DDRC &= ~(3<<DDC4); //Port C pins 4 and 5 as input
PCMSK1 |= (3<<PCINT12); //enable interrupt on pin change, bits 4&5 PORTC
PCICR |= 1<<PCIE1; //enable interrupt on pin change, PORTC
sei(); //enable global interrupts
}
RoboTemad:
also I need to understand how to manipulate with direct port of Arduino , i read about it in the Arduino reference but it is still not completely clear to me .
The same as in the code you posted, once you get the spelling of the constants right.
I re-arranged the code as shown below with connecting the encoder wires to pins A4 and A5 of arduino but after running , the sketch just stucked on serial monitor .
volatile unsigned int enc_pos; // use unsigned long for large distances
volatile unsigned char enc_dir;
void setup()
{
Serial.begin(9600);
enc_pos=0; //Initialize encoder position
DDRC &= ~(3<<PC4); //Port C pins 4 and 5 as input
PCMSK1 |= (3<<PCINT12); //enable interrupt on pin change, bits 4&5 PORTC
PCICR |= 1<<PCIE1; //enable interrupt on pin change, PORTC
sei(); //enable global interrupts
}
void loop()
{
// put your main code here, to run repeatedly:
Serial.print(enc_pos);
}
ISR (PCINT1_vect)
{
static unsigned char enc_last=0,enc_now;
enc_now = (PINC & (3<<PC4))>>4; //read the port pins and shift result to bottom bits
enc_dir = ( enc_last & 1 )^( (enc_now & 2)>>1 ); //determine direction of rotation
if (enc_dir == 0) enc_pos++;
else enc_pos--; //update encoder position
enc_last = enc_now; //remember last state
}
I re-arranged the code as shown below with connecting the encoder wires to pins A4 and A5 of arduino but after running , the sketch just stucked on serial monitor .
volatile unsigned int enc_pos; // use unsigned long for large distances
volatile unsigned char enc_dir;
void setup()
{
Serial.begin(9600);
enc_pos=0; //Initialize encoder position
DDRC &= ~(3<<PC4); //Port C pins 4 and 5 as input
PCMSK1 |= (3<<PCINT12); //enable interrupt on pin change, bits 4&5 PORTC
PCICR |= 1<<PCIE1; //enable interrupt on pin change, PORTC
sei(); //enable global interrupts
}
void loop()
{
// put your main code here, to run repeatedly:
Serial.print(enc_pos);
}
ISR (PCINT1_vect)
{
static unsigned char enc_last=0,enc_now;
enc_now = (PINC & (3<<PC4))>>4; //read the port pins and shift result to bottom bits
enc_dir = ( enc_last & 1 )^( (enc_now & 2)>>1 ); //determine direction of rotation
if (enc_dir == 0) enc_pos++;
else enc_pos--; //update encoder position
enc_last = enc_now; //remember last state
}
I re-arranged the code as shown below with connecting the encoder wires to pins A4 and A5 of arduino but after running , the sketch just stucked on serial monitor .
Serial.print(enc_pos);
For me I find if you just print a very long string of characters without CR/LF to break it up the serial monitor & the Arduino IDE lock up.
Try using
I re-arranged the code as shown below with connecting the encoder wires to pins A4 and A5 of arduino but after running , the sketch just stucked on serial monitor .
Serial.print(enc_pos);
For me I find if you just print a very long string of characters without CR/LF to break it up the serial monitor & the Arduino IDE lock up.
Try using
Serial.println(enc_pos);
instead.
Thanks Riva , now it works good , but it just prints zeros even when I move the wheel by hand but the encoder doesn't count any thing .
pYro_65:
In 1.5.7, it compiles with no changes to the code. Are you saying the names are wrong (values), or not defined?
The Libc header files are generated from an XML document that Atmel maintains. Occasionally the XML file has a mistake. The short bit names are a mistake. The long bit names should always be correctly defined. If they are not please report the problem to Atmel.