Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CAN Relay.
  3.  *
  4.  *
  5.  * @date    2006-12-17
  6.  * @author  Erik Larsson
  7.  *
  8.  *   Observera! Applikationen är endast testad på labplatta med m88, pot och lysdiod
  9.  *
  10.  *   ADC=Vin*1024/Vref
  11.  *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
  12.  *
  13.  *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
  14.  *
  15.  *
  16.  */
  17.  
  18. #define DEBUG           1 /* Prints debug messages to uart */
  19. #define TWO_BUTTON_MODE 1 /* If using two (or just one but nothing more) auxiliary buttons */
  20.  
  21. /*-----------------------------------------------------------------------------
  22.  * Includes
  23.  *---------------------------------------------------------------------------*/
  24. /* system files */
  25. #include <avr/io.h>
  26. #include <avr/interrupt.h>
  27. #include <avr/wdt.h>
  28. #include <stdio.h>
  29. /* lib files */
  30. #include <can.h>
  31. #include <serial.h>
  32. #include <timebase.h>
  33.  
  34. #include <tc1047.h>
  35.  
  36. /* defines */
  37. #define RELAY_OFF           0x01
  38. #define RELAY_ON            0x02
  39. #define FAILSAFE_MODE       0x0F
  40. #define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
  41.  
  42. #define RELAY_CMD_GET       0x1200
  43. #define RELAY_CMD_SEND      0x1201
  44. #define RELAY_CMD_ON        0x01
  45. #define RELAY_CMD_OFF       0x02
  46. #define RELAY_CMD_TOGGLE    0x03
  47. #define RELAY_CMD_STATUS    0x04
  48. #define RELAY_CMD_RESET     0x05
  49. #define STATUS_SEND_PERIOD  10000 /* milliseconds */
  50. #define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
  51. #define BOUNCE_TIME         10 /* milliseconds */
  52. #define BUTTON_ID           0x1202
  53. #define BUTTON1             1
  54. #define BUTTON2             2
  55.  
  56. /*-------------------------------------------------------------------------
  57.  * Global variables
  58.  * -----------------------------------------------------------------------*/
  59. #if TWO_BUTTON_MODE
  60. Can_Message_t txMsg_Button;
  61. #endif
  62.  
  63. /*----------------------------------------------------------------------------
  64.  * Functions
  65.  * -------------------------------------------------------------------------*/
  66. uint8_t relayOff();
  67. uint8_t relayOn();
  68. void relayFailsafe();
  69.  
  70. /*----------------------------------------------------------------------------
  71.  * Interrupt routines
  72.  * -------------------------------------------------------------------------*/
  73. #if TWO_BUTTON_MODE
  74. ISR( PCINT2_vect )
  75. {
  76.     /*
  77.      * Auxiliary button pressed and released
  78.      * Check time between press and release to eliminate bounces
  79.      */
  80.     static uint32_t buttonTime[2];
  81.  
  82.     txMsg_Button.RemoteFlag = 0;
  83.     txMsg_Button.ExtendedFlag = 1;
  84.  
  85.     if( (PIND & (1<<PD6)) == 0){
  86.         /* Button pressed */
  87.         buttonTime[0] = Timebase_CurrentTime();
  88. #if DEBUG
  89.         printf("Button 1 pressed\n");
  90. #endif
  91.     }else if( (PIND & (1<<PD6)) == 1){
  92.         if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
  93.             /* No bounce, send message */
  94.             txMsg_Button.Id = BUTTON_ID;
  95.             txMsg_Button.DataLength = 1;
  96.             txMsg_Button.Data.bytes[0] = BUTTON1;
  97. #if DEBUG
  98.             printf("Button 1 pressed: message sent\n");
  99. #endif
  100.             return;
  101.         }else{
  102.             /* Just bounces, ignore it */
  103. #if DEBUG
  104.             printf("Button 1 just bounced\n");
  105. #endif
  106.             return;
  107.         }
  108.     }
  109.     if( (PIND & (1<<PD7)) == 0){
  110.         /* Button pressed */
  111.         buttonTime[1] = Timebase_CurrentTime();
  112. #if DEBUG
  113.         printf("Button 2 pressed\n");
  114. #endif
  115.     }else if( (PIND & (1<<PD7)) == 1){
  116.         if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
  117.             /* No bounce, send message */
  118.             txMsg_Button.Id = BUTTON_ID;
  119.             txMsg_Button.DataLength = 1;
  120.             txMsg_Button.Data.bytes[0] = BUTTON2;
  121. #if DEBUG
  122.             printf("Button 2 pressed: message sent\n");
  123. #endif
  124.             return;
  125.         }else{
  126.             /* Just bounces, ignore it */
  127. #if DEBUG
  128.             printf("Button 2 just bounced\n");
  129. #endif
  130.             return;
  131.         }
  132.     }
  133. }
  134. #endif
  135.  
  136. //ISR( ADC_vect )
  137. //{
  138.     /*
  139.      * ADC conversion completed
  140.      */
  141.     // TODO använd denna rutin för att läsa värde när omvandlingen är klar
  142.  
  143. //}
  144.  
  145. /*-----------------------------------------------------------------------------
  146.  * Main Program
  147.  *---------------------------------------------------------------------------*/
  148. int main(void) {
  149.  
  150.     uint8_t relayStatus;
  151.     uint32_t boardTemperature = 0;
  152.  
  153.     adcTemperatureInit();
  154.  
  155.     Timebase_Init();
  156. #if DEBUG
  157.     Serial_Init();
  158. #endif
  159.  
  160. #if TWO_BUTTON_MODE
  161.     /*
  162.      * Initialize buttons
  163.      * It is possible to use ie. sensors instead
  164.      * but then change this
  165.      */
  166.     /* Set as input and enable pull-up */
  167.     DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
  168.     PORTD |= (1<<PD6)|(1<<PD7);
  169.  
  170.     /* Enable IO-pin interrupt */
  171.     PCICR |= (1<<PCIE1);
  172.     /* Unmask PD6 and PD7 */
  173.     PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
  174. #endif
  175.     sei();
  176.  
  177.     /* Turn relay off */
  178.     relayStatus = relayOff();
  179.  
  180. #if DEBUG
  181.     printf("\n------------------------------------------------------------\n");
  182.     printf(  "   CAN: Relay\n");
  183.     printf(  "------------------------------------------------------------\n");
  184.  
  185.  
  186.     printf("CanInit...");
  187.     if (Can_Init() != CAN_OK) {
  188.         printf("FAILED!\n");
  189.     }else{
  190.         printf("OK!\n");
  191.     }
  192. #else
  193.     Can_Init();
  194. #endif
  195.     uint32_t timeStamp = 0;
  196.  
  197.     Can_Message_t txMsg;
  198.     Can_Message_t rxMsg;
  199.     txMsg.Id = RELAY_CMD_SEND;
  200.     txMsg.RemoteFlag = 0;
  201.     txMsg.ExtendedFlag = 1;
  202.     txMsg.DataLength = 3;
  203.  
  204.     /* main loop */
  205.     while (1) {
  206.         /* service the CAN routines */
  207.         Can_Service();
  208.  
  209.         /* check if any messages have been received */
  210.         while (Can_Receive(&rxMsg) == CAN_OK) {
  211.             /* This relay is adressed*/
  212.             if( rxMsg.Id == RELAY_CMD_GET ){
  213.  
  214.                 if( rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
  215.                     /* Turn relay on */
  216.                     relayStatus = relayOn();
  217.  
  218.                 }else if(rxMsg.Data.bytes[0] == RELAY_CMD_OFF){
  219.                     /* Turn relay off */
  220.                     relayStatus = relayOff();
  221.  
  222.                 }else if(rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
  223.                     /* Toggle relay */
  224.  
  225.                     if(relayStatus == RELAY_OFF){
  226.                         relayStatus = relayOn();
  227.                     }else{
  228.                         relayStatus = relayOff();
  229.                     }
  230.  
  231.                 }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS){
  232.                     /* Send relay status to CAN */
  233.  
  234.                     boardTemperature = getTC1047temperature();
  235.  
  236.                     if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
  237.                         relayFailsafe();
  238.                     }else{
  239.                         txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  240.                         txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  241.                         txMsg.Data.bytes[2] = relayStatus;
  242.  
  243.                         Can_Send( &txMsg );
  244.                     }
  245.                 }
  246.             }
  247.         }
  248.  
  249.         if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
  250.             timeStamp = Timebase_CurrentTime();
  251.             /* Send relay status to CAN */
  252.  
  253.             boardTemperature = getTC1047temperature();
  254.  
  255.             if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
  256.                 relayFailsafe();
  257.             }else{
  258.                 txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  259.                 txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  260.                 txMsg.Data.bytes[2] = relayStatus;
  261.  
  262.                 Can_Send( &txMsg );
  263. #if DEBUG
  264.                 printf("Periodic message sent...\n");
  265.                 printf("Temperature: %d\nRelay status: %u\n", boardTemperature, relayStatus);
  266. #endif
  267.             }
  268.         }
  269.     }
  270.     return 0;
  271. }
  272.  
  273. uint8_t relayOff()
  274. {
  275.     /* Set as output and sink */
  276.     PORTC &= ~(1<<PC1);
  277.     DDRC |= (1<<DDC1);
  278.  
  279. #if DEBUG
  280.     printf("relay turned off\n");
  281. #endif
  282.  
  283.     return RELAY_OFF;
  284. }
  285.  
  286. uint8_t relayOn()
  287. {
  288.     /* Set as input and enable pull-up */
  289.     DDRC &= ~(1<<DDC1);
  290.     PORTC |= (1<<PC1);
  291.  
  292. #if DEBUG
  293.     printf("relay turned on\n");
  294. #endif
  295.  
  296.     return RELAY_ON;
  297. }
  298.  
  299. void relayFailsafe()
  300. {
  301.     uint8_t relayStatus;
  302.     uint32_t boardTemperature = 0, timeStamp = 0;
  303.  
  304.     Can_Message_t txMsg;
  305.     Can_Message_t rxMsg;
  306.     txMsg.Id = RELAY_CMD_SEND;
  307.     txMsg.RemoteFlag = 0;
  308.     txMsg.ExtendedFlag = 1;
  309.     txMsg.DataLength = 4;
  310.  
  311.     relayStatus = relayOff();
  312.  
  313.     while(1){
  314.         /* service the CAN routines */
  315.         Can_Service();
  316.  
  317.         /* check if any messages have been received */
  318.         while (Can_Receive(&rxMsg) == CAN_OK) {
  319.             /* This relay is adressed*/
  320.             if( rxMsg.Id == RELAY_CMD_GET ){
  321.                 if( rxMsg.Data.bytes[0] == RELAY_CMD_RESET ){
  322.                     /* Return from failsafe mode */
  323.                     return;
  324.                 }
  325.             }
  326.         }
  327.  
  328.         if( Timebase_PassedTimeMillis(timeStamp) >= FAILSAFE_SEND_PERIOD ){
  329.             timeStamp = Timebase_CurrentTime();
  330.             /* Send relay status to CAN */
  331. #if DEBUG
  332.             printf("Failsafe mode!\n");
  333. #endif
  334.             boardTemperature = getTC1047temperature();
  335.  
  336.             txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  337.             txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  338.             txMsg.Data.bytes[2] = relayStatus;
  339.             txMsg.Data.bytes[3] = FAILSAFE_MODE;
  340.  
  341.             Can_Send( &txMsg );
  342.         }
  343.     }
  344. }
  345.  
  346.