Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CanBlinds.
  3.  * Takes incomming packages and adjusts PWM output.
  4.  * Input: -128 to +127
  5.  *
  6. * @date    2001-01-01
  7.  * @author  Erik Larsson
  8.  */
  9.  
  10. #define DEBUG           1 /* Prints debug messages to uart */
  11.  
  12. /*-----------------------------------------------------------------------------
  13.  * Includes
  14.  *---------------------------------------------------------------------------*/
  15. /* system files */
  16. #include <avr/io.h>
  17. #include <avr/interrupt.h>
  18. #include <avr/wdt.h>
  19. #include <stdio.h>
  20. /* lib files */
  21. #include <can.h>
  22. #include <serial.h>
  23. #include <timebase.h>
  24.  
  25. #include <tc1047.h>
  26.  
  27. /* defines */
  28. //#define PWM_MAX_PULSE       500 /* milliseconds */
  29. //#define PWM_MIN_PULSE       1500
  30. #define FAILSAFE_MODE       0x0F
  31. #define FAILSAFE_TRESHOLD   60  /* Degrees when nodeBlinds goes into failsafe mode */
  32.  
  33. #define BLINDS_CMD_GET      0x1200
  34. #define BLINDS_CMD_SEND     0x1201
  35.  
  36. #define BLINDS_CMD_ABS      0x01 /* Absolute position */
  37. #define BLINDS_CMD_REL      0x02 /* Relative position */
  38. #define BLINDS_CMD_START    0x03 /* Start turning RC-servo */
  39. #define BLINDS_CMD_STOP     0x04 /* Stop turning RC-servo */
  40. #define BLINDS_CMD_RESET    0x05
  41.  
  42. #define BLINDS_TURN_LEFT    0x00
  43. #define BLINDS_TURN_RIGHT   0x01
  44.  
  45. #define STATUS_SEND_PERIOD  10000 /* milliseconds */
  46. #define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
  47. #define BOUNCE_TIME         10 /* milliseconds */
  48. #define BUTTON_ID           0x1202
  49. #define BUTTON1             1
  50. #define BUTTON2             2
  51.  
  52. /*-------------------------------------------------------------------------
  53.  * Global variables
  54.  * -----------------------------------------------------------------------*/
  55. #if TWO_BUTTON_MODE
  56. Can_Message_t txMsg_Button;
  57. #endif
  58.  
  59. /*----------------------------------------------------------------------------
  60.  * Functions
  61.  * -------------------------------------------------------------------------*/
  62. void blindsFailsafe();
  63.  
  64. /*----------------------------------------------------------------------------
  65.  * Interrupt routines
  66.  * -------------------------------------------------------------------------*/
  67. #if TWO_BUTTON_MODE
  68. ISR( PCINT2_vect )
  69. {
  70.     /*
  71.      * Auxiliary button pressed and released
  72.      * Check time between press and release to eliminate bounces
  73.      */
  74.     static uint32_t buttonTime[2];
  75.  
  76.     txMsg_Button.RemoteFlag = 0;
  77.     txMsg_Button.ExtendedFlag = 1;
  78.  
  79.     if( (PIND & (1<<PD6)) == 0){
  80.         /* Button pressed */
  81.         buttonTime[0] = Timebase_CurrentTime();
  82. #if DEBUG
  83.         printf("Button 1 pressed\n");
  84. #endif
  85.     }else if( (PIND & (1<<PD6)) == 1){
  86.         if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
  87.             /* No bounce, send message */
  88.             txMsg_Button.Id = BUTTON_ID;
  89.             txMsg_Button.DataLength = 1;
  90.             txMsg_Button.Data.bytes[0] = BUTTON1;
  91. #if DEBUG
  92.             printf("Button 1 pressed: message sent\n");
  93. #endif
  94.             return;
  95.         }else{
  96.             /* Just bounces, ignore it */
  97. #if DEBUG
  98.             printf("Button 1 just bounced\n");
  99. #endif
  100.             return;
  101.         }
  102.     }
  103.     if( (PIND & (1<<PD7)) == 0){
  104.         /* Button pressed */
  105.         buttonTime[1] = Timebase_CurrentTime();
  106. #if DEBUG
  107.         printf("Button 2 pressed\n");
  108. #endif
  109.     }else if( (PIND & (1<<PD7)) == 1){
  110.         if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
  111.             /* No bounce, send message */
  112.             txMsg_Button.Id = BUTTON_ID;
  113.             txMsg_Button.DataLength = 1;
  114.             txMsg_Button.Data.bytes[0] = BUTTON2;
  115. #if DEBUG
  116.             printf("Button 2 pressed: message sent\n");
  117. #endif
  118.             return;
  119.         }else{
  120.             /* Just bounces, ignore it */
  121. #if DEBUG
  122.             printf("Button 2 just bounced\n");
  123. #endif
  124.             return;
  125.         }
  126.     }
  127. }
  128. #endif
  129.  
  130. //ISR( ADC_vect )
  131. //{
  132.     /*
  133.      * ADC conversion completed
  134.      */
  135.     // TODO använd denna rutin för att läsa värde när omvandlingen är klar
  136.  
  137. //}
  138.  
  139. /*-----------------------------------------------------------------------------
  140.  * Main Program
  141.  *---------------------------------------------------------------------------*/
  142. int main(void) {
  143.  
  144.     uint8_t blindsStatus; /* Position */
  145.     uint32_t boardTemperature = 0;
  146.  
  147.     adcTemperatureInit();
  148.     Timebase_Init();
  149. #if DEBUG
  150.     Serial_Init();
  151. #endif
  152.  
  153. #if TWO_BUTTON_MODE
  154.     /*
  155.      * Initialize buttons
  156.      * It is possible to use ie. sensors instead
  157.      * but then change this
  158.      */
  159.     /* Set as input and enable pull-up */
  160.     DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
  161.     PORTD |= (1<<PD6)|(1<<PD7);
  162.  
  163.     /* Enable IO-pin interrupt */
  164.     PCICR |= (1<<PCIE1);
  165.     /* Unmask PD6 and PD7 */
  166.     PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
  167. #endif
  168.     sei();
  169. #if DEBUG
  170.     printf("\n------------------------------------------------------------\n");
  171.     printf(  "   CAN: Blinds\n");
  172.     printf(  "------------------------------------------------------------\n");
  173.  
  174.     printf("CanInit...");
  175.     if (Can_Init() != CAN_OK) {
  176.         printf("FAILED!\n");
  177.     }else{
  178.         printf("OK!\n");
  179.     }
  180. #else
  181.     Can_Init();
  182. #endif
  183.     uint32_t timeStamp = 0;
  184.  
  185.     Can_Message_t txMsg;
  186.     Can_Message_t rxMsg;
  187.     txMsg.Id = BLINDS_CMD_SEND;
  188.     txMsg.RemoteFlag = 0;
  189.     txMsg.ExtendedFlag = 1;
  190.     txMsg.DataLength = 3;
  191.  
  192.     /* main loop */
  193.     while (1) {
  194.         /* service the CAN routines */
  195.         Can_Service();
  196.  
  197.         /* check if any messages have been received */
  198.         while (Can_Receive(&rxMsg) == CAN_OK) {
  199.             /* This node that control a servo is adressed */
  200.             if( rxMsg.Id == BLINDS_CMD_GET ){
  201.  
  202.                 if( rxMsg.Data.bytes[0] == BLINDS_CMD_ABS ){
  203.                     /* Set absolute position to servo */
  204.  
  205.                 }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_REL){
  206.                     /* Set relative position to servo */
  207.  
  208.                 }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_START ){
  209.                     /* Start turning the servo */
  210.  
  211.                 }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STOP ){
  212.                     /* Stop turning */
  213.  
  214.                 }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){
  215.                     /* Send blinds status to CAN */
  216.  
  217.                     boardTemperature = getTC1047temperature();
  218.  
  219.                     if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
  220.                         blindsFailsafe();
  221.                     }else{
  222.                         txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  223.                         txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  224.                         txMsg.Data.bytes[2] = relayStatus;
  225.  
  226.                         Can_Send( &txMsg );
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.  
  232.         if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
  233.             timeStamp = Timebase_CurrentTime();
  234.             /* Send blinds status to CAN */
  235.  
  236.             boardTemperature = getTC1047temperature();
  237.  
  238.             if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
  239.                 blindsFailsafe();
  240.             }else{
  241.                 txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  242.                 txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  243.                 txMsg.Data.bytes[2] = relayStatus;
  244.  
  245.                 Can_Send( &txMsg );
  246. #if DEBUG
  247.                 printf("Periodic message sent...\n");
  248.                 printf("Temperature: %d\nRelay status: %u\n", boardTemperature, relayStatus);
  249. #endif
  250.             }
  251.         }
  252.     }
  253.     return 0;
  254. }
  255.  
  256. void blindsFailsafe() // TODO fixa failsafe
  257. {
  258.     uint8_t relayStatus;
  259.     uint32_t boardTemperature = 0, timeStamp = 0;
  260.  
  261.     Can_Message_t txMsg;
  262.     Can_Message_t rxMsg;
  263.     txMsg.Id = BLINDS_CMD_SEND;
  264.     txMsg.RemoteFlag = 0;
  265.     txMsg.ExtendedFlag = 1;
  266.     txMsg.DataLength = 4;
  267.  
  268.     relayStatus = relayOff();
  269.  
  270.     while(1){
  271.         /* service the CAN routines */
  272.         Can_Service();
  273.  
  274.         /* check if any messages have been received */
  275.         while (Can_Receive(&rxMsg) == CAN_OK) {
  276.             /* This relay is adressed*/
  277.             if( rxMsg.Id == BLINDS_CMD_GET ){
  278.                 if( rxMsg.Data.bytes[0] == BLINDS_CMD_RESET ){
  279.                     /* Return from failsafe mode */
  280.                     return;
  281.                 }
  282.             }
  283.         }
  284.  
  285.         if( Timebase_PassedTimeMillis(timeStamp) >= FAILSAFE_SEND_PERIOD ){
  286.             timeStamp = Timebase_CurrentTime();
  287.             /* Send relay status to CAN */
  288. #if DEBUG
  289.             printf("Failsafe mode!\n");
  290. #endif
  291.             boardTemperature = getTC1047temperature();
  292.  
  293.             txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
  294.             txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
  295.             txMsg.Data.bytes[2] = relayStatus;
  296.             txMsg.Data.bytes[3] = FAILSAFE_MODE;
  297.  
  298.             Can_Send( &txMsg );
  299.         }
  300.     }
  301. }
  302.  
  303.