Subversion Repositories HomeAutomation

Rev

Rev 405 | Rev 486 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * CAN Relay.
  3.  *
  4.  *
  5.  * @date    2006-12-17
  6.  * @author  Erik Larsson
  7.  *
  8.  *   ADC=Vin*1024/Vref
  9.  *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
  10.  *
  11.  *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
  12.  *
  13.  *
  14.  */
  15.  
  16. #define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
  17.  
  18. /*-----------------------------------------------------------------------------
  19.  * Includes
  20.  *---------------------------------------------------------------------------*/
  21. /* system files */
  22. #include <avr/io.h>
  23. #include <avr/interrupt.h>
  24. #include <stdio.h>
  25. /* lib files */
  26. #include <config.h>
  27. #include <bios.h>
  28. #include <drivers/timer/timebase.h>
  29. //#include <funcdefs.h>
  30.  
  31. /* defines */
  32. #define RELAY_OFF           0x01
  33. #define RELAY_ON            0x02
  34. #define FAILSAFE_MODE       0x0F
  35. #define FAILSAFE_TRESHOLD   0xFF  /* Degrees when nodeRelay goes into failsafe mode */
  36.  
  37. #define RELAY_CMD_ON        0x01
  38. #define RELAY_CMD_OFF       0x02
  39. #define RELAY_CMD_TOGGLE    0x03
  40. #define RELAY_CMD_STATUS    0x04
  41. #define RELAY_CMD_RESET     0x05
  42. #define STATUS_SEND_PERIOD  10000UL /* milliseconds */
  43. #define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
  44. #define BOUNCE_TIME         10 /* milliseconds */
  45. #define BUTTON1             1
  46. #define BUTTON2             2
  47.  
  48. /*-------------------------------------------------------------------------
  49.  * Global variables
  50.  * -----------------------------------------------------------------------*/
  51. uint8_t relayStatus, failsafe_flag = 0;
  52. uint32_t boardTemperature = 0;
  53.  
  54. volatile Can_Message_t rxMsg; // Message storage
  55. volatile uint8_t rxMsgFull;   // Synchronization flag
  56.  
  57.  
  58. /*----------------------------------------------------------------------------
  59.  * Functions
  60.  * -------------------------------------------------------------------------*/
  61. uint8_t relayOff();
  62. uint8_t relayOn();
  63. void relayFailsafe();
  64. void sendStatus();
  65.  
  66. void can_receive(Can_Message_t *msg)
  67. { // CAN callback function
  68.     if (!rxMsgFull) {
  69.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  70.         rxMsgFull = 1;
  71.     }
  72. }
  73.  
  74. /*----------------------------------------------------------------------------
  75.  * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
  76.  * -------------------------------------------------------------------------*/
  77. #if TWO_BUTTON_MODE
  78. ISR( PCINT2_vect )
  79. {
  80.  
  81. }
  82. #endif
  83.  
  84. /*-----------------------------------------------------------------------------
  85.  * Main Program
  86.  *---------------------------------------------------------------------------*/
  87. int main(void) {
  88.  
  89.     uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
  90.  
  91.     adcTemperatureInit();
  92.  
  93.     // Set up callback for CAN messages
  94.     BIOS_CanCallback = &can_receive;
  95.  
  96.     sei();
  97.    
  98.     Timebase_Init();
  99.  
  100.     // Turn relay off
  101.     relayStatus = relayOff();
  102.  
  103.     // Main loop
  104.     while (1) {
  105.  
  106.         temp = Timebase_CurrentTime();
  107.         if( temp - timeStamp >= STATUS_SEND_PERIOD ){
  108.             timeStamp = temp;
  109.             // Send relay status to CAN
  110.             sendStatus();
  111.         }
  112.  
  113.         if (rxMsgFull) {
  114.             uint8_t acttype;
  115.             uint16_t servoid;
  116.        
  117.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
  118.                 // Actuator package
  119.                 acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_FUNCC) >> CAN_SHIFT_ACT_FUNCC);
  120.                 servoid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_NID) >> CAN_SHIFT_ACT_NID);
  121.                
  122.                 if ((acttype == ACT_FUNCC_RELAY) && (servoid == NODE_ID)) {
  123.                     // This is a message for this relay
  124.                     if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
  125.                         // Return to normal operation
  126.                         failsafe_flag = 0;
  127.                     }
  128.                    
  129.                     if (!failsafe_flag) {
  130.                         if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
  131.                             // Turn relay on
  132.                             relayStatus = relayOn();
  133.            
  134.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
  135.                             // Turn relay off
  136.                             relayStatus = relayOff();
  137.            
  138.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
  139.                                 // Toggle relay
  140.                                 if(relayStatus == RELAY_OFF){
  141.                                     relayStatus = relayOn();
  142.                                 }else{
  143.                                     relayStatus = relayOff();
  144.                                 }
  145.            
  146.                         }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
  147.                             // Send relay status to CAN
  148.                             sendStatus();
  149.                         }
  150.                     }
  151.                 }
  152.             }
  153.             rxMsgFull = 0; //  
  154.  
  155.         }
  156.        
  157.     }
  158.     return 0;
  159. }
  160.  
  161. uint8_t relayOff()
  162. {
  163.     // Turn off relay
  164.     PORTC &= ~(1<<PC1);
  165.     DDRC |= (1<<DDC1);
  166.  
  167.     return RELAY_OFF;
  168. }
  169.  
  170. uint8_t relayOn()
  171. {
  172.     // Turn on relay
  173.     DDRC &= ~(1<<DDC1);
  174.     PORTC |= (1<<PC1);
  175.  
  176.     return RELAY_ON;
  177. }
  178.  
  179. void relayFailsafe()
  180. {
  181.     uint32_t failsafe_timeStamp, temp;
  182.     relayStatus = relayOff();
  183.     failsafe_flag = 1;
  184.  
  185.     while(1){
  186.  
  187.         if( !failsafe_flag ){
  188.             // Return from failsafe mode
  189.             return;
  190.         }
  191. // TODO skicka med period
  192.         sendStatus( );
  193.     }
  194. }
  195.  
  196. void sendStatus()
  197. {
  198.     uint32_t temperature;
  199.     Can_Message_t statusMsg;
  200.     statusMsg.RemoteFlag = 0;
  201.     statusMsg.ExtendedFlag = 1;
  202.     statusMsg.DataLength = 4;
  203.     statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_FUNCC_RELAY_STATUS<<CAN_SHIFT_ACT_FUNCC )|( NODE_ID<<CAN_SHIFT_SNS_SID );
  204.    
  205.     temperature = getTC1047temperature();
  206.     if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
  207.         // Goto failsafe mode
  208.         relayFailsafe();
  209.     }else{
  210.         // Transmitt node status
  211.         statusMsg.Data.bytes[0] = temperature & 0x00FF;
  212.         statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
  213.         statusMsg.Data.bytes[2] = relayStatus;
  214.         statusMsg.Data.bytes[3] = failsafe_flag;
  215.  
  216.         BIOS_CanSend( &statusMsg );
  217.     }
  218. }
  219.