Subversion Repositories HomeAutomation

Rev

Rev 302 | Blame | Last modification | View Log | SVN | RSS feed

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