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
 *  
302 noddan 8
 * TODO: A lot, currently trying to get some kind of ready-made programs to work.
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>
302 noddan 23
#include <math.h> //Not sure this is needed anymore..
24
#include <avr/pgmspace.h> //To allow read/write from flash
285 noddan 25
 
301 noddan 26
 
27
/*----------------------------------------------------------------------------
28
 * Ehm, struct?
29
 * -------------------------------------------------------------------------*/
302 noddan 30
typedef struct
301 noddan 31
{
32
    uint8_t R;
33
    uint8_t G;
34
    uint8_t B;
35
    uint8_t Intens;
302 noddan 36
} Color;
37
 
38
/*-----------------------------------------------------------------------------
39
 * Programs! This will most likely be improooved, but I have to start somewhere.
40
 *---------------------------------------------------------------------------*/
41
 
305 noddan 42
//Special combinations that means something special
43
//The combinations are useless for lighting anyway
44
//So we might as well use them!
45
//0x00, 0x00, 0x00, 0x00 means end of program, keep looping it
46
//0x00, 0x00, 0x00, 0x01 means end of program, halt 
304 noddan 47
 
48
Color pgm1[] PROGMEM = {
49
{0xff,0x00,0x00,0x00},
50
{0xff,0xff,0x00,0x00},
51
{0x00,0xff,0x00,0x00},
52
{0x00,0xff,0xff,0x00},
53
{0x00,0x00,0xff,0x00},
54
{0xff,0x00,0xff,0x00},
55
{0x00,0x00,0x00,0x00}
301 noddan 56
};
57
 
304 noddan 58
Color pgm2[] PROGMEM = {
302 noddan 59
{0x20,0x20,0x30,0x50},
60
{0x20,0x20,0x30,0x50},
61
{0x20,0x20,0x30,0x50}
62
};
63
 
304 noddan 64
Color* programs[] PROGMEM = {
65
(Color*)pgm1,
66
(Color*)pgm2
302 noddan 67
};
68
 
69
 
70
 
285 noddan 71
/*-----------------------------------------------------------------------------
72
 * Variables
73
 *---------------------------------------------------------------------------*/
289 noddan 74
uint32_t timeStamp; //TimeStamp to keep track of time
75
uint32_t dimStamp;  //Timestamp to keep track of dimmer changes
285 noddan 76
 
302 noddan 77
Color currColor;  //Current color
78
Color destColor;  //Destination color
285 noddan 79
 
289 noddan 80
uint16_t fadeSpeed; //Fadingspeed. 16bit for reaaaally slow fading. Sets the speed of colorchange.
81
uint8_t dimSpeed;       //Dimmer speed. Sets the speed of intensitychange.
285 noddan 82
 
305 noddan 83
uint8_t currProgram;        //This variable keeps track of what program is currently running. 
289 noddan 84
 
285 noddan 85
/*----------------------------------------------------------------------------
86
 * Functions
87
 * -------------------------------------------------------------------------*/
88
void updateLED();
301 noddan 89
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright);
298 noddan 90
void changeColor(int8_t amount, uint8_t* color);
302 noddan 91
void fade(uint8_t* current, uint8_t* destination);
285 noddan 92
 
93
/*-----------------------------------------------------------------------------
94
 * Main Program
95
 *---------------------------------------------------------------------------*/
96
int main(void) {
304 noddan 97
 
285 noddan 98
    Timebase_Init();
99
    Serial_Init();
286 noddan 100
    Can_Init();
285 noddan 101
 
102
//Setting up OC1A, 16 bit counter used as 8 bit.
103
    TCCR1A |= (1<<COM1A1) | (1<<WGM11); /* Set OC1A at TOP, mode 14 */
301 noddan 104
    TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS12); /* Timer uses main system clock with ? prescale */
285 noddan 105
    ICR1 = 256; //8 bit precision to match the other two counters.
298 noddan 106
    OCR1A = 0;  //0% as standard
285 noddan 107
    DDRB |= (1<<PB1); /* Enable pin as output */
108
 
298 noddan 109
//Setting up OC0A
302 noddan 110
    TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00); /* Set OC0A at TOP, Mode 7 */
111
    TCCR0B |= (1<<CS02); /* Prescaler updating now */
112
    OCR0A = 0;  //0% standard
113
    DDRD |= (1<<PD6);
291 noddan 114
 
298 noddan 115
//Setting up OC0B
302 noddan 116
    TCCR0A |= (1<<COM0B1);
117
    OCR0B = 0;
118
    DDRD |= (1<<PD5);
291 noddan 119
 
298 noddan 120
 
285 noddan 121
//Initialize variables
298 noddan 122
    fadeSpeed = 10;
289 noddan 123
    dimSpeed = 255;
286 noddan 124
    timeStamp = 0;
289 noddan 125
    dimStamp = 0;
301 noddan 126
    Can_Message_t rxMsg;   
285 noddan 127
 
301 noddan 128
    reformatRGB(0x00,0xff,0x00,1);
129
    destColor.Intens = 100;
130
    currColor = destColor;
285 noddan 131
 
301 noddan 132
//Just temporary for now, they keep track of some kind of demo-program.
305 noddan 133
    currProgram = 1;
134
    uint16_t temp_adress = pgm_read_word(&programs[currProgram-1]); //Get adress for program 0
287 noddan 135
 
289 noddan 136
 
301 noddan 137
    sei();
298 noddan 138
 
285 noddan 139
    /* main loop */
140
    while (1) {
141
        /* service the CAN routines */
142
        Can_Service();
286 noddan 143
 
289 noddan 144
        /* Time to fade color? */
301 noddan 145
        if (Timebase_PassedTimeMillis(timeStamp) >= fadeSpeed) {
302 noddan 146
            fade(&currColor.R, &destColor.R);          
147
            fade(&currColor.G, &destColor.G);
148
            fade(&currColor.B, &destColor.B);
298 noddan 149
 
285 noddan 150
            timeStamp = Timebase_CurrentTime();
151
            updateLED();
152
        }
153
 
154
 
289 noddan 155
        /* Time to fade intensity? */
156
        if (Timebase_PassedTimeMillis(dimStamp) >= dimSpeed) {
302 noddan 157
            fade(&currColor.Intens, &destColor.Intens);
289 noddan 158
            dimStamp = Timebase_CurrentTime();
159
            updateLED();
160
        }
161
 
162
 
302 noddan 163
        /* Program management */
305 noddan 164
        if (currProgram != 0){ //Check if a program is currently running
165
            if ((currColor.R == destColor.R)&(currColor.G == destColor.G)&(currColor.B == destColor.B)&(currColor.Intens == destColor.Intens)){//Is the current sequence finished?
166
                //Now we have to check if the program is finished and if we should loop
167
                if ((pgm_read_byte(temp_adress)==0)&(pgm_read_byte(temp_adress+1)==0)&(pgm_read_byte(temp_adress+2)==0)){
168
                    //The program has ended! Shall we loop it?
169
                    if (pgm_read_byte(temp_adress+3)==0){
170
                        //Yes, let's loop it
171
                        temp_adress = pgm_read_word(&programs[currProgram-1]);
172
                    } else {
173
                        //No, halt!
174
                        currProgram = 0;
175
                    }
176
                } else {
177
                    //The program has not ended, let's get the next RGB-triplet!
178
                    reformatRGB(pgm_read_byte(temp_adress),pgm_read_byte(temp_adress + 1),pgm_read_byte(temp_adress + 2),0);
179
                    temp_adress = temp_adress + 4;                 
180
                }
181
            }
302 noddan 182
        }
183
 
285 noddan 184
        /* check if any messages have been received */
185
        /* A lot of remote control crap going on here now for testing */
186
        while (Can_Receive(&rxMsg) == CAN_OK) {
187
            if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x20)){
305 noddan 188
                //program = 1;
189
                //fadeSpeed = 0;
285 noddan 190
            }
191
 
192
            if ((rxMsg.Data.bytes[0] == 0x0)&(rxMsg.Data.bytes[3] == 0x21)){
305 noddan 193
                //program = 2;
194
                //fadeSpeed = 0;
285 noddan 195
            }
286 noddan 196
        }
285 noddan 197
 
286 noddan 198
    }
199
 
200
    return 0;
201
}
285 noddan 202
 
203
 
204
 
205
 
301 noddan 206
/************************************************************************************************
207
 *     updateLED updates the PWM counter values and thus changes the color of the RGBLED.       *
208
 *     It doesn't reculculate anything, except the values to write to the PWM registers.        *
209
 *     TODO: Get rid of the tempcontainer!                                  *
210
 ************************************************************************************************/
286 noddan 211
void updateLED(){
301 noddan 212
    uint8_t tempcontainer;
213
 
214
    tempcontainer = currColor.R * currColor.Intens / 255;   //I really want to skip this, don't know how yet though.
215
    OCR1A = tempcontainer; 
216
      OCR0A = currColor.G * currColor.Intens / 255;
217
    OCR0B = currColor.B * currColor.Intens / 255;      
218
 
302 noddan 219
    //Bara för debugcrap
220
    Can_Message_t txMsg;
221
    txMsg.Id = 0x55;
222
    txMsg.RemoteFlag = 0;
223
    txMsg.ExtendedFlag = 1;
305 noddan 224
    txMsg.DataLength = 8;
225
    txMsg.Data.bytes[0] = currColor.R;
226
    txMsg.Data.bytes[1] = currColor.G;
227
    txMsg.Data.bytes[2] = currColor.B;
301 noddan 228
    txMsg.Data.bytes[3] = currColor.Intens;
305 noddan 229
 
287 noddan 230
    Can_Send(&txMsg);
298 noddan 231
}
285 noddan 232
 
233
 
234
 
301 noddan 235
/************************************************************************************************
236
 *     reformatRGB sets a new target RGB triplet to fade to. It reformats it so that            *
237
 *     the highest color always gets 0xff. Brightness is recalculated.                          *
238
 *     if setBright is set to 0, the brightness will not be updated.                    *
239
 *     TODO: Smarter 16-bit arithmetics would be nice. Also a pointer to struct to be updated.  *
240
 ************************************************************************************************/
241
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright){
298 noddan 242
    uint8_t maxvalue;
243
    uint16_t tempcontainer;
244
 
245
    if ((R>=G)&(R>=B)){
246
        maxvalue = R;
247
    } else if ((G>=R)&(G>=B)){
248
        maxvalue = G;
249
    } else {
250
        maxvalue = B;
251
    }
252
 
253
    tempcontainer = R * 255;
301 noddan 254
    destColor.R = tempcontainer/maxvalue;
298 noddan 255
    tempcontainer = G * 255;
301 noddan 256
    destColor.G = tempcontainer/maxvalue;
298 noddan 257
    tempcontainer = B * 255;
301 noddan 258
    destColor.B = tempcontainer/maxvalue;
298 noddan 259
 
301 noddan 260
    if (setBright){
261
        destColor.Intens = maxvalue;
262
    }
285 noddan 263
}
264
 
286 noddan 265
 
301 noddan 266
/************************************************************************************************
267
 *     fade tar in två värden, current och destination och för current ett steg                 *
268
 *     närmare destination.                                                               *
269
 ************************************************************************************************/
302 noddan 270
void fade(uint8_t* current, uint8_t* destination){
271
    if (*current > *destination){
272
        *current = *current - 1;
273
    } else if (*current < *destination){
274
        *current = *current + 1;
289 noddan 275
    }
287 noddan 276
}
298 noddan 277
 
301 noddan 278
 
279
/************************************************************************************************
280
 *     changeColor ändrar en färg mängden amount. -127>127.                                     *
281
 *     color kan vara dest eller curr R,G,B.                                                    *
282
 *     Ev. TODO: om t.ex. röd är på max och man vill öka röd ska de andra färgerna minskas. *
283
 ************************************************************************************************/
298 noddan 284
void changeColor(int8_t amount, uint8_t* color){
285
    if ( ((amount > 0)&(*color < 255)) || ((amount < 0)&(*color > 0)) ) //Se till att vi inte slår över *color
286
    *color = *color + amount;
287
}
301 noddan 288