mdUJ
Newbie level 6
Hello,
years ago I made a program to control an inverted pendulum. To increase the system resolution for better control, I doubled the encoder resolution by software. Here is the code. It is written for ATmega88 - may be someone can use it.
years ago I made a program to control an inverted pendulum. To increase the system resolution for better control, I doubled the encoder resolution by software. Here is the code. It is written for ATmega88 - may be someone can use it.
Code:
// Port and Pin definitions for Rotary Encoder
#define RE_SIGNAL_90_DDR (DDRD)
#define RE_SIGNAL_90_PRT (PORTD)
#define RE_SIGNAL_90_PIN (PIND)
#define RE_SIGNAL_90_BIT (PD3)
#define RE_GET_SIGNAL_90() (RE_SIGNAL_90_PIN & RE_SIGNAL_90_BIT)
//-----------------------------------------------------------------------------
S32 volatile re_count; // Signed 32-bit variable
//-----------------------------------------------------------------------------
void re_init(void)
{
// Set INT0 as input and enable pullup
DDRD &= ~PD2;
PORTD |= PD2;
// Set second Rotary Encoder signal as input and enable pullup
RE_SIGNAL_90_DDR &= RE_SIGNAL_90_BIT;
RE_SIGNAL_90_PRT |= RE_SIGNAL_90_BIT;
// Falling edge of INT0 generates an interrupt
EICRA |= ISC01;
// Clear INT0 interrupt flag
EIFR |= INTF0;
// Enable INT0 interrupt
EIMSK |= INT0;
}
//-----------------------------------------------------------------------------
interrupt[EXT_INT0] void int0_isr(void)
{
// Interrupt triggered by rising edge
if (PIND & PD2)
{
if (RE_GET_SIGNAL_90()) // If second signal is high
{
re_count++;
}
else // If second signal is low
{
re_count--;
}
// Set falling edge to trigger INT0 interrupt
EICRA &= ~ISC00;
}
else // Interrupt triggered by falling edge
{
if (RE_GET_SIGNAL_90()) // If second signal is high
{
re_count--;
}
else // If second signal is low
{
re_count++;
}
// Set rising edge to trigger INT0 interrupt
EICRA |= ISC00;
}
}
Last edited: