desk-light with brightness and color temperature (remote) control
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

66 lines
1.4 KiB

#include <avr/io.h>
#include <avr/interrupt.h>
#include "encoder.h"
/*
* Code based on version from Peter Dannegger, see
* https://www.mikrocontroller.net/articles/Drehgeber#Signalauswertung
*/
volatile int delta = 0;
static int last;
static int btn;
void encoder_init( void )
{
int new;
// enable internal pull-up resistors
ENC_PORT |= (1 << ENC_PIN_A) | (1 << ENC_PIN_B);
ENC_PORT_BTN |= (1 << ENC_PIN_BTN);
new = 0;
if( INPUT_B ) new = 3;
if( INPUT_A ) new ^= 1;
last = new;
TCCR2 = (1 << WGM21) | (1 << WGM20) | (1<<CS22);
// setup compare register to trigger after 1ms
// OCR2 = (uint)(F_CPU / 64.0 * 1e-3 - 0.5);
// enable timer compare interrupt
TIMSK |= 1<<OCIE2;
}
ISR( TIMER2_COMP_vect ) // 1ms for manual movement
{
int new, diff;
new = 0;
if( INPUT_B ) new = 3;
if( INPUT_A ) new ^= 1; // convert gray to binary
diff = last - new; // difference last - new
if( diff & 1 ) { // bit 0 = value (1)
last = new; // store new as next last
delta += (diff & 2) - 1; // bit 1 = direction (+/-)
}
// button pressed is signal low, need to invert
btn = INPUT_BTN ^ 1;
}
int encoder_read( void ) // read four step encoders
{
int val;
cli();
val = delta;
delta = val & 3;
sei();
return val >> 2; // counts since last call
}
int encoder_read_btn( void ) // read button state
{
return btn;
}