Subversion Repositories HomeAutomation

Rev

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
}