
Roary encoder display V1.0 - Build Instructions
1.0.0 - 8 September, 2015 477.07 KBSooner or later there will be a project wich uses rotary encoders and LEDs.
I created these two units to test out the possibilities. These are great circuits to be used on breadboard or as a building block in an enclosure.
Here are some demo videos of the working units: (It is up to your software how many steps are needed to switch to the next LED. This demo uses 256 steps for 100%)
Digital Parts
$ 4.80
Digital Parts
$ 4.20
// PIC Testboard - Rotary Encoder // Version 0.2 // 12.12.2013 // (c) 2013 Thomas Hofmann // TH custom effects // // PROCESSOR : PIC16F1827 // CLOCK : INTERNAL 34Mhz #include <xc.h> #pragma config FCMEN = OFF // Fail Save Clock Monitor #pragma config IESO = OFF // Internal/External Switchover mode #pragma config WDTE = OFF // Watchdog Timer Enable #pragma config MCLRE = OFF // Reset Enable (see LVP) #pragma config BOREN = OFF // Brownn Out Ebable #pragma config PWRTE = OFF // Power up Timer enable #pragma config LVP = OFF // Low Voltage Programming #pragma config CLKOUTEN=OFF // Clock Output Enable #pragma config FOSC = INTOSC // Internal Oscillator #pragma config CP = ON // Program Memory Code Protection #pragma config CPD = OFF // Data Memory Code Protection #pragma config STVREN= OFF // Stack Overflow Reset #define bit_set(var,bitno) ((var) |= 1 << (bitno)) #define bit_clr(var,bitno) ((var) &= ~(1 << (bitno))) #define testbit_on(data,bitno) ((data>>bitno)&0x01) unsigned int e_max = 256; // max encoder value unsigned char e_last = 0; // encoder old value unsigned char e_new = 0; // encoder new value signed char e_delta = 0; // diff signed char e_temp = 0; // encoder temp unsigned char e_count = 0; // encoder counter unsigned char b_temp = 0; // button temp unsigned char b_pres = 0; // debouncing unsigned char B_FLAG = 0; // Button toggle flag unsigned char wait = 0; const static signed char table[16] = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0}; void interrupt isr(void) { if (TMR4IF) // timer4 interrupt (1ms interval) { // decode encoder e_new = PORTA & 0b00011000; e_last = (e_last << 2) & 0x0F; if (testbit_on(e_new,3)) e_last |=2; if (testbit_on(e_new,4)) e_last |=1; e_delta += table[e_last]; // check for button pressed b_temp=PORTB & 0x01; // Read B0 if ((b_temp==0x01) && (b_pres==0x01)) { // Toggle Button Flag b_pres=0; B_FLAG^=0x01; } if (b_temp==0x00){b_pres=0x01;} // indicate key pressed TMR4IF=0; } } signed char encoder_read( void ) // Encoder auslesen { signed char val; PEIE=0; val = e_delta; e_delta = 0; PEIE=1; return val; } //Just simple delay void Delay(unsigned long cntr) { while (--cntr != 0); } // sending data word to controller 1x16 void out_LEDx16(unsigned int data){ for (unsigned char l=0; l<=15; l++){ // output bit by bit if testbit_on(data,15-l) bit_set(LATB,1); else bit_clr(LATB,1); // Set data on RB1 LATB^=0x04; // Pulse SCK on RB2 LATB^=0x04; } LATA^=0x04; // Pulse LE on RA2 LATA^=0x04; } // sending data word to controller 2x16 void out_LEDx32(unsigned int data, unsigned int data2){ for (unsigned char l=0; l<=15; l++){ // output bit by bit if testbit_on(data2,15-l) bit_set(LATB,1); else bit_clr(LATB,1); // Set data on RB1 LATB^=0x04; // Pulse SCK on RB2 LATB^=0x04; } for (unsigned char l=0; l<=15; l++){ // output bit by bit if testbit_on(data,15-l) bit_set(LATB,1); else bit_clr(LATB,1); // Set data on RB1 LATB^=0x04; // Pulse SCK on RB2 LATB^=0x04; } LATA^=0x04; // Pulse LE on RA2 LATA^=0x04; } // converting char 0-16 to point/bar indicator unsigned int value_to_graph(unsigned char data, unsigned char nvl_enable, unsigned char point_bar){ unsigned int buff = 0; unsigned char ctr = 0; if ((data>0) || (nvl_enable>0)){ buff=1; for (ctr=0; ctr<data; ctr++){ // shift left x times buff=buff<<1; if (point_bar>0){buff++;} } } return buff; } unsigned char calc_div(unsigned char val){ unsigned char adjust = 0; adjust = e_max/16; return val/adjust; } // main function void main(void) { OSCCON = 0b11110000; // 8Mhz x PLL=4 = 32Mhz // General OPTION_REG = 0x00; // GPIO pull-ups are enabled INTCON = 0x00; // Disable all Interrups TRISA = 0b00111010; // PORTA 6,7 OUT - LED Bicolor, 2-OUT-LE, 3,4 - IN- Encoder, 0 - SDO2 TRISB = 0b00001001; // PORTB 4-6 OUT - LED RGB; 0- IN-Pushbutton; 1,4 = I2C ANSELA = 0x00; // Disable Analog Port A ANSELB = 0x00; // Disable Analog Port B LATA = 0x00; // Set PORTA to defined State LATB = 0x00; // Set PORTB to defined State TMR4 = 0x00; // reset counter 4 // Encoder TIMER T4CON = 0b00001010; // 1:2 postscaler, 1:16x prescaler PR4 = 250; // interrupt is called 1/1000s TMR4IF = 0; // Clear Timer4 IF TMR4IE = 1; // Allow Timer4 Interrupts TMR4ON = 1; // Start Timer4 PEIE = 1; // Enable Low Priority Interrupts // INTERRUPS GIE = 1; // Enable global interrupts LATA = 0b01000000; // light bicolor LED to indicate RED unsigned int show = 1; unsigned char i = 0; unsigned char ack = 0; while(1) { e_temp=encoder_read(); // read encoder changres since last read if ((e_count==0) && (e_temp==-1) || (e_count==e_max-1) && (e_temp==1)) {} else { // update new value only if no under/overrun will occour e_count+=e_temp; //out_LED(value_to_graph(calc_div(e_count),1,B_FLAG)); // output value with nulval_enabled and point out_LEDx32(value_to_graph(calc_div(e_count),1,B_FLAG),value_to_graph(calc_div(255-e_count),1,B_FLAG)); // output value with nulval_enabled and point } } }
Pingback: Ine bygger High End Amplifiers - Side 140