Subversion Repositories HomeAutomation

Rev

Rev 486 | Rev 498 | 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. #define THISRELAYID         NODE_ID     /* application software should not depend on the id of the physical node
  49.                                             but for now lets do it like this */
  50.  
  51. #define APP_TYPE    CAN_APPTYPES_RELAY
  52. #define APP_VERSION 0x0001
  53.  
  54. /*-------------------------------------------------------------------------
  55.  * Global variables
  56.  * -----------------------------------------------------------------------*/
  57. uint8_t relayStatus, failsafe_flag = 0;
  58. uint32_t boardTemperature = 0;
  59.  
  60. volatile Can_Message_t rxMsg; // Message storage
  61. volatile uint8_t rxMsgFull;   // Synchronization flag
  62.  
  63.  
  64. /*----------------------------------------------------------------------------
  65.  * Functions
  66.  * -------------------------------------------------------------------------*/
  67. uint8_t relayOff();
  68. uint8_t relayOn();
  69. void relayFailsafe();
  70. void sendStatus();
  71.  
  72. void can_receive(Can_Message_t *msg)
  73. { // CAN callback function
  74.     if (!rxMsgFull) {
  75.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  76.         rxMsgFull = 1;
  77.     }
  78. }
  79.  
  80. /*----------------------------------------------------------------------------
  81.  * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
  82.  * -------------------------------------------------------------------------*/
  83. #if TWO_BUTTON_MODE
  84. ISR( PCINT2_vect )
  85. {
  86.  
  87. }
  88. #endif
  89.  
  90. /*-----------------------------------------------------------------------------
  91.  * Main Program
  92.  *---------------------------------------------------------------------------*/
  93. int main(void) {
  94.  
  95.     uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
  96.  
  97.     adcTemperatureInit();
  98.  
  99.     // Set up callback for CAN messages
  100.     BIOS_CanCallback = &can_receive;
  101.  
  102.     sei();
  103.    
  104.     Timebase_Init();
  105.  
  106.     Can_Message_t txMsg;
  107.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  108.     txMsg.DataLength = 4;
  109.     txMsg.RemoteFlag = 0;
  110.     txMsg.ExtendedFlag = 1;
  111.     txMsg.Data.words[0] = APP_TYPE;
  112.     txMsg.Data.words[1] = APP_VERSION;
  113.     BIOS_CanSend(&txMsg);
  114.  
  115.     // Turn relay off
  116.     relayStatus = relayOff();
  117.  
  118.     // Main loop
  119.     while (1) {
  120.  
  121.         temp = Timebase_CurrentTime();
  122.         if( temp - timeStamp >= STATUS_SEND_PERIOD ){
  123.             timeStamp = temp;
  124.             // Send relay status to CAN
  125.             sendStatus();
  126.         }
  127.  
  128.         if (rxMsgFull) {
  129.             uint8_t acttype;
  130.             uint16_t relayid;
  131.        
  132.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
  133.                 // Actuator package
  134.                 acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  135.                 relayid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  136.                
  137.                 if ((acttype == ACT_TYPE_RELAY) && (relayid == THISRELAYID)) {
  138.                     // This is a message for this relay
  139.                     if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
  140.                         // Return to normal operation
  141.                         failsafe_flag = 0;
  142.                     }
  143.                    
  144.                     if (!failsafe_flag) {
  145.                         if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
  146.                             // Turn relay on
  147.                             relayStatus = relayOn();
  148.            
  149.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
  150.                             // Turn relay off
  151.                             relayStatus = relayOff();
  152.            
  153.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
  154.                                 // Toggle relay
  155.                                 if(relayStatus == RELAY_OFF){
  156.                                     relayStatus = relayOn();
  157.                                 }else{
  158.                                     relayStatus = relayOff();
  159.                                 }
  160.            
  161.                         }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
  162.                             // Send relay status to CAN
  163.                             sendStatus();
  164.                         }
  165.                     }
  166.                 }
  167.             }
  168.             rxMsgFull = 0; //  
  169.  
  170.         }
  171.        
  172.     }
  173.     return 0;
  174. }
  175.  
  176. uint8_t relayOff()
  177. {
  178.     // Turn off relay
  179.     PORTC &= ~(1<<PC1);
  180.     DDRC |= (1<<DDC1);
  181.  
  182.     return RELAY_OFF;
  183. }
  184.  
  185. uint8_t relayOn()
  186. {
  187.     // Turn on relay
  188.     DDRC &= ~(1<<DDC1);
  189.     PORTC |= (1<<PC1);
  190.  
  191.     return RELAY_ON;
  192. }
  193.  
  194. void relayFailsafe()
  195. {
  196.     uint32_t failsafe_timeStamp, temp;
  197.     relayStatus = relayOff();
  198.     failsafe_flag = 1;
  199.  
  200.     while(1){
  201.  
  202.         if( !failsafe_flag ){
  203.             // Return from failsafe mode
  204.             return;
  205.         }
  206. // TODO skicka med period
  207.         sendStatus( );
  208.     }
  209. }
  210.  
  211. void sendStatus()
  212. {
  213.     uint32_t temperature;
  214.     Can_Message_t statusMsg;
  215.     statusMsg.RemoteFlag = 0;
  216.     statusMsg.ExtendedFlag = 1;
  217.     statusMsg.DataLength = 4;
  218.     statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_TYPE_RELAY_STATUS<<CAN_SHIFT_ACT_TYPE )|( NODE_ID<<CAN_SHIFT_SNS_SID );
  219.    
  220.     temperature = getTC1047temperature();
  221.     if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
  222.         // Goto failsafe mode
  223.         relayFailsafe();
  224.     }else{
  225.         // Transmitt node status
  226.         statusMsg.Data.bytes[0] = temperature & 0x00FF;
  227.         statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
  228.         statusMsg.Data.bytes[2] = relayStatus;
  229.         statusMsg.Data.bytes[3] = failsafe_flag;
  230.  
  231.         BIOS_CanSend( &statusMsg );
  232.     }
  233. }
  234.