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.
287 noddan 3
 * Still under heavy development
285 noddan 4
 *
286 noddan 5
 * @date    2007-02-04
6
 * @author  Martin Nordén
285 noddan 7
 *  
301 noddan 8
 * TODO: A lot, including. Using my new precious struct Color for currColor, destColor and some basic programfunctionality
285 noddan 9
 */
10
 
11
/*-----------------------------------------------------------------------------
12
 * Includes
13
 *---------------------------------------------------------------------------*/
14
/* system files */
15
#include <avr/io.h>
16
#include <avr/interrupt.h>
17
#include <avr/wdt.h>
18
#include <stdio.h>
19
/* lib files */
20
#include <can.h>
21
#include <serial.h>
22
#include <timebase.h>
23
#include <math.h>
24
 
301 noddan 25
 
26
/*----------------------------------------------------------------------------
27
 * Ehm, struct?
28
 * -------------------------------------------------------------------------*/
29
struct Color
30
{
31
    uint8_t R;
32
    uint8_t G;
33
    uint8_t B;
34
    uint8_t Intens;
35
};
36
 
285 noddan 37
/*-----------------------------------------------------------------------------
38
 * Variables
39
 *---------------------------------------------------------------------------*/
289 noddan 40
uint32_t timeStamp; //TimeStamp to keep track of time
41
uint32_t dimStamp;  //Timestamp to keep track of dimmer changes
285 noddan 42
 
298 noddan 43
uint32_t tempStamp; //Timestamp to keep track of temp things during development
44
uint8_t temp;
45
 
301 noddan 46
struct Color currColor;  //Current color
47
struct Color destColor;  //Destination color
285 noddan 48
 
289 noddan 49
uint16_t fadeSpeed; //Fadingspeed. 16bit for reaaaally slow fading. Sets the speed of colorchange.
50
uint8_t dimSpeed;       //Dimmer speed. Sets the speed of intensitychange.
285 noddan 51
 
289 noddan 52
uint8_t program;        //This variable keeps track of what program is currently running. 
53
uint8_t programstate;   //This variable keeps track of where in a program we currently are. Will probably be removed later on.
54
 
285 noddan 55
/*----------------------------------------------------------------------------
56
 * Functions
57
 * -------------------------------------------------------------------------*/
58
void updateLED();
301 noddan 59
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright);
298 noddan 60
void changeColor(int8_t amount, uint8_t* color);
289 noddan 61
uint8_t fade(uint8_t current, uint8_t destination);
285 noddan 62
 
63
/*-----------------------------------------------------------------------------
64
 * Main Program
65
 *---------------------------------------------------------------------------*/
66
int main(void) {
67
    Timebase_Init();
68
    Serial_Init();
286 noddan 69
    Can_Init();
285 noddan 70
 
71
//Setting up OC1A, 16 bit counter used as 8 bit.
72
    TCCR1A |= (1<<COM1A1) | (1<<WGM11); /* Set OC1A at TOP, mode 14 */
301 noddan 73
    TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS12); /* Timer uses main system clock with ? prescale */
285 noddan 74
    ICR1 = 256; //8 bit precision to match the other two counters.
298 noddan 75
    OCR1A = 0;  //0% as standard
285 noddan 76
    DDRB |= (1<<PB1); /* Enable pin as output */
77
 
298 noddan 78
//Setting up OC0A
291 noddan 79
    TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00); /* Set OC0A at TOP, Mode 7 */
301 noddan 80
    TCCR0B |= (1<<CS02); /* Prescaler updating now */
298 noddan 81
    OCR0A = 0;  //0% standard
291 noddan 82
    DDRD |= (1<<PD6);
83
 
298 noddan 84
//Setting up OC0B
291 noddan 85
    TCCR0A |= (1<<COM0B1);
298 noddan 86
    OCR0B = 0;
291 noddan 87
    DDRD |= (1<<PD5);
88
 
298 noddan 89
 
285 noddan 90
//Initialize variables
298 noddan 91
    fadeSpeed = 10;
289 noddan 92
    dimSpeed = 255;
286 noddan 93
    timeStamp = 0;
289 noddan 94
    dimStamp = 0;
301 noddan 95
    Can_Message_t rxMsg;   
285 noddan 96
 
301 noddan 97
    reformatRGB(0x00,0xff,0x00,1);
98
    destColor.Intens = 100;
99
    currColor = destColor;
285 noddan 100
 
301 noddan 101
//Just temporary for now, they keep track of some kind of demo-program.
102
    program = 1;
103
    temp = 1;
287 noddan 104
 
289 noddan 105
 
301 noddan 106
    sei();
298 noddan 107
 
285 noddan 108
    /* main loop */
109
    while (1) {
110
        /* service the CAN routines */
111
        Can_Service();
286 noddan 112
 
289 noddan 113
        /* Time to fade color? */
301 noddan 114
        if (Timebase_PassedTimeMillis(timeStamp) >= fadeSpeed) {
115
            currColor.R = fade(currColor.R, destColor.R);          
116
            currColor.G = fade(currColor.G, destColor.G);
117
            currColor.B = fade(currColor.B, destColor.B);
298 noddan 118
 
285 noddan 119
            timeStamp = Timebase_CurrentTime();
120
            updateLED();
121
        }
122
 
123
 
289 noddan 124
        /* Time to fade intensity? */
125
        if (Timebase_PassedTimeMillis(dimStamp) >= dimSpeed) {
301 noddan 126
            currColor.Intens = fade(currColor.Intens, destColor.Intens);
289 noddan 127
            dimStamp = Timebase_CurrentTime();
128
            updateLED();
129
        }
130
 
131
 
298 noddan 132
        /* Just a nice fade-demo */
133
        if ((Timebase_PassedTimeMillis(tempStamp) >= 2500)&(program == 1)) {
134
            tempStamp = Timebase_CurrentTime();
135
 
136
            switch(temp){
137
            case 1:
301 noddan 138
                reformatRGB(0xff,0x00,0x00,0);
298 noddan 139
                break;
140
            case 2:
301 noddan 141
                reformatRGB(0xff,0xff,0x00,0);
298 noddan 142
                break;
143
            case 3:
301 noddan 144
                reformatRGB(0x00,0xff,0x00,0);
298 noddan 145
                break;
146
            case 4:
301 noddan 147
                reformatRGB(0x00,0xff,0xff,0);
298 noddan 148
                break;
149
            case 5:
301 noddan 150
                reformatRGB(0x00,0x00,0xff,0);
298 noddan 151
                break;
152
            case 6:
301 noddan 153
                reformatRGB(0xff,0x00,0xff,0);
298 noddan 154
                temp = 255;
155
                break;
156
            }
157
            temp++;
158
 
159
        }
289 noddan 160
 
298 noddan 161
 
285 noddan 162
        /* check if any messages have been received */
163
        /* A lot of remote control crap going on here now for testing */
164
        while (Can_Receive(&rxMsg) == CAN_OK) {
165
            if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x20)){
166
                program = 1;
167
                fadeSpeed = 0;
168
            }
169
 
170
            if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x21)){
171
                program = 2;
172
                fadeSpeed = 0;
173
            }
286 noddan 174
        }
285 noddan 175
 
176
 
286 noddan 177
    }
178
 
179
    return 0;
180
}
285 noddan 181
 
182
 
183
 
184
 
301 noddan 185
/************************************************************************************************
186
 *     updateLED updates the PWM counter values and thus changes the color of the RGBLED.       *
187
 *     It doesn't reculculate anything, except the values to write to the PWM registers.        *
188
 *     TODO: Get rid of the tempcontainer!                                  *
189
 ************************************************************************************************/
286 noddan 190
void updateLED(){
289 noddan 191
    //Bara för debugcrap
287 noddan 192
    Can_Message_t txMsg;
193
    txMsg.Id = 0x55;
194
    txMsg.RemoteFlag = 0;
195
    txMsg.ExtendedFlag = 1;
196
    txMsg.DataLength = 4;
301 noddan 197
 
198
 
199
    uint8_t tempcontainer;
200
 
201
    tempcontainer = currColor.R * currColor.Intens / 255;   //I really want to skip this, don't know how yet though.
202
    OCR1A = tempcontainer; 
203
      OCR0A = currColor.G * currColor.Intens / 255;
204
    OCR0B = currColor.B * currColor.Intens / 255;      
205
 
206
    txMsg.Data.bytes[0] = currColor.R * currColor.Intens / 255;
207
    txMsg.Data.bytes[1] = currColor.G * currColor.Intens / 255;
208
    txMsg.Data.bytes[2] = currColor.B * currColor.Intens / 255;
209
    txMsg.Data.bytes[3] = currColor.Intens;
287 noddan 210
    Can_Send(&txMsg);
298 noddan 211
}
285 noddan 212
 
213
 
214
 
301 noddan 215
/************************************************************************************************
216
 *     reformatRGB sets a new target RGB triplet to fade to. It reformats it so that            *
217
 *     the highest color always gets 0xff. Brightness is recalculated.                          *
218
 *     if setBright is set to 0, the brightness will not be updated.                    *
219
 *     TODO: Smarter 16-bit arithmetics would be nice. Also a pointer to struct to be updated.  *
220
 ************************************************************************************************/
221
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright){
298 noddan 222
    uint8_t maxvalue;
223
    uint16_t tempcontainer;
224
 
225
    if ((R>=G)&(R>=B)){
226
        maxvalue = R;
227
    } else if ((G>=R)&(G>=B)){
228
        maxvalue = G;
229
    } else {
230
        maxvalue = B;
231
    }
232
 
233
    tempcontainer = R * 255;
301 noddan 234
    destColor.R = tempcontainer/maxvalue;
298 noddan 235
    tempcontainer = G * 255;
301 noddan 236
    destColor.G = tempcontainer/maxvalue;
298 noddan 237
    tempcontainer = B * 255;
301 noddan 238
    destColor.B = tempcontainer/maxvalue;
298 noddan 239
 
301 noddan 240
    if (setBright){
241
        destColor.Intens = maxvalue;
242
    }
285 noddan 243
}
244
 
286 noddan 245
 
301 noddan 246
/************************************************************************************************
247
 *     fade tar in två värden, current och destination och för current ett steg                 *
248
 *     närmare destination.                                                               *
249
 *     Ev. TODO: skicka in två pekare och jämna ut dom istället.                        *
250
 ************************************************************************************************/
289 noddan 251
uint8_t fade(uint8_t current, uint8_t destination){
252
    if (current > destination){
253
        return(current - 1);
254
    } else if (current < destination){
255
        return(current + 1);
256
    }
257
    return(current);
287 noddan 258
}
298 noddan 259
 
301 noddan 260
 
261
/************************************************************************************************
262
 *     changeColor ändrar en färg mängden amount. -127>127.                                     *
263
 *     color kan vara dest eller curr R,G,B.                                                    *
264
 *     Ev. TODO: om t.ex. röd är på max och man vill öka röd ska de andra färgerna minskas. *
265
 ************************************************************************************************/
298 noddan 266
void changeColor(int8_t amount, uint8_t* color){
267
    if ( ((amount > 0)&(*color < 255)) || ((amount < 0)&(*color > 0)) ) //Se till att vi inte slår över *color
268
    *color = *color + amount;
269
}
301 noddan 270