Subversion Repositories HomeAutomation

Rev

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