Converting code to Arduino Sketch

hello everyone

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

I 'll be grateful for any answer .

Just remove the three includes at the top.

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.

You can see how int main is used by the Arduino code here:
http://arduino.land/FAQ/content/2/2/en/can-i-use-int-main-with-arduino.html

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.

thanks pYro_65 & Nick

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
}

In 1.5.7, it compiles with no changes to the code. Are you saying the names are wrong (values), or not defined?

Maybe it was added to AVR in a later release ( 1.0.5/1.5.6 and below ).

I was using 1.0.0 in my kitchen I must admit. I can't comment on how well it works on other versions.

... unless I leave the kitchen.

It appears they are new macros, it fails on 1.5.6r2.

I was just looking at the datasheet, always a good starting point.

RoboTemad:
thanks pYro_65 & Nick

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 think you missed my last post :wink:

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.

Riva:

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.