Details | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 285 | noddan | 1 | /** |
| 286 | noddan | 2 | * CAN RGB LED. This application is used to control a RGB LED. |
| 3 | * It uses the HSL colorspace. Still under heavy development. |
||
| 4 | * Still untested with a real RGB-LED, HSV Colorspace might be better suited. We'll see... |
||
| 5 | |||
| 6 | * TODO: Use pointers in the HSL_2_RGB functions etc. It's currently a waste of memory. |
||
| 285 | noddan | 7 | * |
| 286 | noddan | 8 | * @date 2007-02-04 |
| 9 | * @author Martin Nordén |
||
| 285 | noddan | 10 | * |
| 11 | */ |
||
| 12 | |||
| 13 | /*----------------------------------------------------------------------------- |
||
| 14 | * Includes |
||
| 15 | *---------------------------------------------------------------------------*/ |
||
| 16 | /* system files */ |
||
| 17 | #include <avr/io.h> |
||
| 18 | #include <avr/interrupt.h> |
||
| 19 | #include <avr/wdt.h> |
||
| 20 | #include <stdio.h> |
||
| 21 | /* lib files */ |
||
| 22 | #include <can.h> |
||
| 23 | #include <serial.h> |
||
| 24 | #include <timebase.h> |
||
| 25 | #include <math.h> |
||
| 26 | |||
| 27 | /*----------------------------------------------------------------------------- |
||
| 28 | * Variables |
||
| 29 | *---------------------------------------------------------------------------*/ |
||
| 286 | noddan | 30 | uint32_t timeStamp; |
| 285 | noddan | 31 | |
| 286 | noddan | 32 | uint8_t R; //Current Red PWM dutycycle |
| 33 | uint8_t G; //Current Green PWM dutycycle |
||
| 34 | uint8_t B; //Current Blue PWM dutycycle |
||
| 285 | noddan | 35 | |
| 286 | noddan | 36 | double currH; //HSL går mellan 0 och 1 |
| 37 | double currS; |
||
| 38 | double currL; |
||
| 285 | noddan | 39 | |
| 286 | noddan | 40 | double destH; |
| 41 | double destS; |
||
| 42 | double destL; |
||
| 43 | |||
| 285 | noddan | 44 | uint16_t fadeSpeed; //Fadingspeed. 16bit for reaaaally slow fading |
| 45 | uint8_t program; //This variable keeps track of what program is currently running. 0 means no program. |
||
| 46 | uint8_t programstate; //This variable keeps track of where in a program we currently are. |
||
| 47 | |||
| 48 | /*---------------------------------------------------------------------------- |
||
| 49 | * Functions |
||
| 50 | * -------------------------------------------------------------------------*/ |
||
| 51 | void updateLED(); |
||
| 286 | noddan | 52 | uint8_t Hue_2_RGB(double v1, double v2, double v3); |
| 285 | noddan | 53 | |
| 54 | |||
| 55 | /*----------------------------------------------------------------------------- |
||
| 56 | * Main Program |
||
| 57 | *---------------------------------------------------------------------------*/ |
||
| 58 | int main(void) { |
||
| 59 | Timebase_Init(); |
||
| 60 | Serial_Init(); |
||
| 286 | noddan | 61 | Can_Init(); |
| 285 | noddan | 62 | |
| 63 | //Setting up OC1A, 16 bit counter used as 8 bit. |
||
| 64 | /* Use OC1A */ |
||
| 65 | TCCR1A |= (1<<COM1A1) | (1<<WGM11); /* Set OC1A at TOP, mode 14 */ |
||
| 66 | TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS11); /* Timer uses main system clock with 1/8 prescale */ |
||
| 67 | ICR1 = 256; //8 bit precision to match the other two counters. |
||
| 68 | OCR1A = 128; //50% as standard |
||
| 69 | DDRB |= (1<<PB1); /* Enable pin as output */ |
||
| 70 | |||
| 71 | //Initialize variables |
||
| 286 | noddan | 72 | fadeSpeed = 20; |
| 73 | timeStamp = 0; |
||
| 285 | noddan | 74 | |
| 75 | Can_Message_t rxMsg; |
||
| 286 | noddan | 76 | |
| 77 | //Init HSL |
||
| 78 | currH = 0; |
||
| 79 | currS = 1; |
||
| 80 | currL = 0.5; |
||
| 285 | noddan | 81 | |
| 82 | sei(); |
||
| 83 | |||
| 84 | /* main loop */ |
||
| 85 | while (1) { |
||
| 86 | /* service the CAN routines */ |
||
| 87 | Can_Service(); |
||
| 286 | noddan | 88 | |
| 285 | noddan | 89 | /* Time to see if we want to update our values */ |
| 90 | if (Timebase_PassedTimeMillis(timeStamp) >= fadeSpeed) { |
||
| 91 | timeStamp = Timebase_CurrentTime(); |
||
| 286 | noddan | 92 | currH = currH + 0.01; |
| 93 | if (currH > 1) currH = 0; |
||
| 285 | noddan | 94 | updateLED(); |
| 95 | } |
||
| 96 | |||
| 97 | |||
| 98 | /* check if any messages have been received */ |
||
| 99 | /* A lot of remote control crap going on here now for testing */ |
||
| 100 | while (Can_Receive(&rxMsg) == CAN_OK) { |
||
| 101 | if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x20)){ |
||
| 102 | program = 1; |
||
| 103 | fadeSpeed = 0; |
||
| 104 | } |
||
| 105 | |||
| 106 | if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x21)){ |
||
| 107 | program = 2; |
||
| 108 | fadeSpeed = 0; |
||
| 109 | } |
||
| 286 | noddan | 110 | } |
| 285 | noddan | 111 | |
| 112 | |||
| 286 | noddan | 113 | } |
| 114 | |||
| 115 | return 0; |
||
| 116 | } |
||
| 285 | noddan | 117 | |
| 118 | |||
| 119 | |||
| 120 | |||
| 121 | |||
| 286 | noddan | 122 | void updateLED(){ |
| 285 | noddan | 123 | |
| 124 | |||
| 286 | noddan | 125 | if ( currS == 0 ) //HSL values = 0 ÷ 1 |
| 126 | { |
||
| 127 | R = currL * 255; //RGB results = 0 ÷ 255 |
||
| 128 | G = currL * 255; |
||
| 129 | B = currL * 255; |
||
| 130 | } |
||
| 131 | else |
||
| 132 | { |
||
| 133 | double var_1; |
||
| 134 | double var_2; |
||
| 135 | if ( currL < 0.5 ) var_2 = currL * ( 1 + currS ); |
||
| 136 | else var_2 = ( currL + currS ) - ( currS * currL ); |
||
| 285 | noddan | 137 | |
| 286 | noddan | 138 | var_1 = 2 * currL - var_2; |
| 285 | noddan | 139 | |
| 286 | noddan | 140 | R = Hue_2_RGB( var_1, var_2, currH + ( 1 / 3 ) ); |
| 141 | G = Hue_2_RGB( var_1, var_2, currH ); |
||
| 142 | B = Hue_2_RGB( var_1, var_2, currH - ( 1 / 3 ) ); |
||
| 143 | } |
||
| 285 | noddan | 144 | |
| 145 | |||
| 146 | |||
| 286 | noddan | 147 | OCR1A = R; |
| 285 | noddan | 148 | |
| 149 | //Red |
||
| 150 | //Green |
||
| 151 | //Blue |
||
| 152 | } |
||
| 153 | |||
| 286 | noddan | 154 | |
| 155 | uint8_t Hue_2_RGB(double v1, double v2, double vH ) //Function Hue_2_RGB |
||
| 156 | { |
||
| 157 | if ( vH < 0 ) vH += 1; |
||
| 158 | if ( vH > 1 ) vH -= 1; |
||
| 159 | if ( ( 6 * vH ) < 1 ) return 255*( v1 + ( v2 - v1 ) * 6 * vH ); |
||
| 160 | if ( ( 2 * vH ) < 1 ) return 255*( v2 ); |
||
| 161 | if ( ( 3 * vH ) < 2 ) return 255*( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 ); |
||
| 162 | return 255*( v1 ); |
||
| 163 | } |