[tpcode]#include <avr/interrupt.h> #include <avr/io.h> #include "LCD4Bit_mod.h" #define DEBOUNCE_MAX 17 // max value for debounce count #define DEBOUNCE_ON 12 // debounce pressed threshold 12x4ms = 48ms #define DEBOUNCE_OFF 2 // debounce released threshold 8ms //create object to control an LCD. //number of lines in display=1 LCD4Bit_mod lcd = LCD4Bit_mod(2); int potpin = A2; // POT connected to digital pin 2 - pos/neg are left and right connections on POT int rpin = 3; // Red int gpin = 10; // Green int bpin = 11; // Blue float h; // Hue range int h_int; // Hue color int r = 0, g = 0, b = 0; // Default RGB values int val = 0; // Set POT value to default 0 void h2rgb(float h, int& R, int& G, int& B); // Instantiate h2rgb and it's variables a.k.a Hue to RGB int adc_key_val[5] ={30, 150, 360, 535, 760 }; byte NUM_KEYS = 5; char key=-1; char oldkey=-1; // debounce counters byte button_count[5]; // button status - pressed/released byte button_status[5]; // button on flags byte button_flag[5]; // Timer2 interrupt routine - // 1/(160000000/256/(256-6)) = 4ms interval ISR(TIMER2_OVF_vect) { TCNT2 = 6; update_adc_key(); } // Convert ADC value to key number char get_key(unsigned int input) { char k; for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } } if (k >= NUM_KEYS) k = -1; // No valid key pressed return k; } void update_adc_key(){ int adc_key_in; char key_in; byte i; adc_key_in = analogRead(0); key_in = get_key(adc_key_in); for(i=0; i<NUM_KEYS; i++) { if(key_in==i) //one key is pressed { if(button_count[i]<DEBOUNCE_MAX) { button_count[i]++; if(button_count[i]>DEBOUNCE_ON) { if(button_status[i] == 0) { button_flag[i] = 1; // pressed state flag ON button_status[i] = 1; //button debounced to 'pressed' status } } } } else // no button pressed { if (button_count[i] >0) { button_count[i]--; if(button_count[i]<DEBOUNCE_OFF){ button_status[i]=0; //button debounced to 'released' status } } } // output button pressed state if(button_flag[i]==1) { button_flag[i]=0; // clear flag to avoid repeats Serial.print('A'+i,BYTE); // output MO button code } } } void setup() { pinMode(13, OUTPUT); //we'll use the debug LED to output a heartbeat digitalWrite(13,LOW); Serial.begin(19200); // reset button arrays for(byte i=0; i<5; i++){ button_count[i]=0; button_status[i]=0; button_flag[i]=0; } // Setup timer2 -- Prescaler/256 TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); TCCR2B &= ~(1<<WGM22); TCCR2B = (1<<CS22)|(1<<CS21); ASSR |=(0<<AS2); // Use normal mode TCCR2A =0; //Timer2 Overflow Interrupt Enable TIMSK2 |= (0<<OCIE2A); TCNT2=0x6; // counting starts from 6; TIMSK2 = (1<<TOIE2); SREG|=1<<SREG_I; lcd.init(); lcd.clear(); lcd.printIn("**LCD SMARTIE**"); lcd.cursorTo(2,3); lcd.printIn("on Arduino"); } byte serial_getch(){ int incoming; while (Serial.available()==0){} // read the incoming byte: incoming = Serial.read(); return (byte) (incoming &0xff); } void loop(){ val = analogRead(potpin); // Read the pin and display the value h = ((float)val)/1024; // Get the range. pot value / 1024 h_int = (int) 360*h; // Get the color hue by multiplying by 360 h2rgb(h,r,g,b); // Call the h2rgb function passing it the hue value Serial.print("POT value: "); Serial.print(val); // Pot value Serial.print(" = Hue of "); Serial.print(h_int); // Color Hue value Serial.print(" degrees. RGB values: "); Serial.print(r); // Red value Serial.print(" "); Serial.print(g); // Green value Serial.print(" "); Serial.println(b); // Blue value analogWrite(rpin, r); // Changes red led analogWrite(gpin, g); // Changes green led analogWrite(bpin, b); // Changes blue led byte rxbyte; byte temp; rxbyte = serial_getch(); if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands { switch (serial_getch()) { case 66: //backlight on (at previously set brightness) // not implemented break; case 70: //backlight off // not implemented break; case 71: //set cursor position temp = (serial_getch() - 1); //get column byte switch (serial_getch()) //get row byte { //line 1 is already set up case 2: temp += 0x40; break; case 3: temp += 0x14; break; case 4: temp += 0x54; break; default: break; } lcd.commandWrite(0b10000000 + temp); break; case 72: //cursor home (reset display position) lcd.commandWrite(2); break; case 74: //show underline cursor lcd.commandWrite(0b00001110); break; case 75: //underline cursor off case 84: //block cursor off lcd.commandWrite(0b00001100); break; case 76: //move cursor left lcd.commandWrite(16); break; case 77: //move cursor right lcd.commandWrite(20); break; case 78: //define custom char lcd.commandWrite(64 + (serial_getch() * 8)); //get+set char address for (temp = 7; temp != 0; temp--) { lcd.print(serial_getch()); //get each pattern byte } break; case 83: //show blinking block cursor lcd.commandWrite(0b00001111); break; case 86: //GPO OFF //implement later break; case 87: //GPO ON /*temp = serial_getch(); if (temp == 1) { GPO1 = GPO_ON; }*/ break; case 88: //clear display, cursor home lcd.commandWrite(1); break; case 152: //set and remember (doesn't save value, though) case 153: //set backlight brightness //not implemented break; //these commands ignored (no parameters) case 35: //read serial number case 36: //read version number case 55: //read module type case 59: //exit flow-control mode case 65: //auto transmit keypresses case 96: //auto-repeat mode off (keypad) case 67: //auto line-wrap on case 68: //auto line-wrap off case 81: //auto scroll on case 82: //auto scroll off case 104: //init horiz bar graph case 109: //init med size digits case 115: //init narrow vert bar graph case 118: //init wide vert bar graph break; default: //all other commands ignored and parameter byte discarded temp = serial_getch(); //dump the command code break; } return; } //END OF COMMAND HANDLER //change accented char to plain, detect and change descenders //NB descenders only work on 5x10 displays. This lookup table works // with my DEM-20845 (Display Elektronik GmbH) LCD using KS0066 chip. switch (rxbyte) { //chars that have direct equivalent in LCD charmap /* case 0x67: //g rxbyte = 0xE7; break; case 0x6A: //j rxbyte = 0xEA; break; case 0x70: //p rxbyte = 0xF0; break; case 0x71: //q rxbyte = 0xF1; break; case 0x79: //y rxbyte = 0xF9; break; */ case 0xE4: //ASCII "a" umlaut rxbyte = 0xE1; break; case 0xF1: //ASCII "n" tilde rxbyte = 0xEE; break; case 0xF6: //ASCII "o" umlaut rxbyte = 0xEF; //was wrong in v0.86 break; case 0xFC: //ASCII "u" umlaut rxbyte = 0xF5; break; //accented -> plain equivalent //and misc symbol translation case 0xA3: //sterling (pounds) rxbyte = 0xED; break; /* case 0xB0: //degrees symbol rxbyte = 0xDF; break; */ case 0xB5: //mu rxbyte = 0xE4; break; case 0xC0: //"A" variants case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: rxbyte = 0x41; break; case 0xC8: //"E" variants case 0xC9: case 0xCA: case 0xCB: rxbyte = 0x45; break; case 0xCC: //"I" variants case 0xCD: case 0xCE: case 0xCF: rxbyte = 0x49; break; case 0xD1: //"N" tilde -> plain "N" rxbyte = 0x43; break; case 0xD2: //"O" variants case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD8: rxbyte = 0x4F; break; case 0xD9: //"U" variants case 0xDA: case 0xDB: case 0xDC: rxbyte = 0x55; break; case 0xDD: //"Y" acute -> "Y" rxbyte = 0x59; break; /* case 0xDF: //beta //mucks up LCDSmartie's degree symbol?? rxbyte = 0xE2; break; */ case 0xE0: //"a" variants except umlaut case 0xE1: case 0xE2: case 0xE3: case 0xE5: rxbyte = 0x61; break; case 0xE7: //"c" cedilla -> "c" rxbyte = 0x63; break; case 0xE8: //"e" variants case 0xE9: case 0xEA: case 0xEB: rxbyte = 0x65; break; case 0xEC: //"i" variants case 0xED: case 0xEE: case 0xEF: rxbyte = 0x69; break; case 0xF2: //"o" variants except umlaut case 0xF3: case 0xF4: case 0xF5: case 0xF8: rxbyte = 0x6F; break; case 0xF7: //division symbol rxbyte = 0xFD; break; case 0xF9: //"u" variants except umlaut case 0xFA: case 0xFB: rxbyte = 0x75; break; default: break; } lcd.print(rxbyte); //otherwise a plain char so we print it to lcd return; } void h2rgb(float h, int& R, int& G, int& B) { // Used HSV --> RGB function // HSV - Hue, Saturation, Value // RGB - Red, Green, Blue - example (255,255,255) // Function below does a bunch of math to convert HSV values to RGB int var_i; float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b; if ( S == 0 ) //HSV values = 0 ÷ 1 { R = V * 255; G = V * 255; B = V * 255; } else { var_h = h * 6; if ( var_h == 6 ) var_h = 0; //H must be < 1 var_i = int( var_h ) ; //Or ... var_i = floor( var_h ) var_1 = V * ( 1 - S ); var_2 = V * ( 1 - S * ( var_h - var_i ) ); var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) ); if ( var_i == 0 ) { var_r = V ; var_g = var_3 ; var_b = var_1 ; } else if ( var_i == 1 ) { var_r = var_2 ; var_g = V ; var_b = var_1 ; } else if ( var_i == 2 ) { var_r = var_1 ; var_g = V ; var_b = var_3 ; } else if ( var_i == 3 ) { var_r = var_1 ; var_g = var_2 ; var_b = V ; } else if ( var_i == 4 ) { var_r = var_3 ; var_g = var_1 ; var_b = V ; } else { var_r = V ; var_g = var_1 ; var_b = var_2 ; } R = (1-var_r) * 255; //RGB results = 0 ÷ 255 G = (1-var_g) * 255; B = (1-var_b) * 255; } }[/tpcode]