Subversion Repositories HomeAutomation

Rev

Rev 176 | Rev 184 | 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.  *   Observera! Applikationen är helt otestad!
  9.  *
  10.  *   ADC=Vin*1024/Vref
  11.  *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
  12.  *
  13.  *  Transmitts: DATA: <temperature high byte> <temperature low byte> <relay status>
  14.  *
  15.  */
  16.  
  17. /*
  18.  * For testing with ATmega88 PDIP enable this fetaure
  19.  * Since PDIP doesn't have ADC7 it will use the ADC0 instead
  20.  */
  21. #define PDIP    0
  22.  
  23. /*-----------------------------------------------------------------------------
  24.  * Includes
  25.  *---------------------------------------------------------------------------*/
  26. /* system files */
  27. #include <avr/io.h>
  28. #include <avr/interrupt.h>
  29. #include <avr/wdt.h>
  30. #include <stdio.h>
  31. /* lib files */
  32. #include <can.h>
  33. #include <serial.h>
  34. #include <timebase.h>
  35. /* defines */
  36. #define OFF     0x00
  37. #define ON      0x01
  38. #define Vref    5
  39.  
  40. /*------------------------------------------------------------------------------
  41.  * Read and send relay state (OPEN/CLOSED) and temperature
  42.  * ---------------------------------------------------------------------------*/
  43. void sendRelayStatus( Can_Message_t* msg, uint8_t state )
  44. {
  45.     int16_t temp;
  46.  
  47.     /* Start measureing */
  48.     ADCSRA |= (1<<ADSC);
  49.  
  50.     /* Wait for conversion to complete */
  51.     while( ADCSRA & (1<<ADSC) ){}
  52.  
  53.     msg->Id = 0x1201; // temporary ID
  54.  
  55.     msg->Data.bytes[0] = state;
  56.  
  57.     /* Convert voltage to temperature */
  58.     temp = (ADCL & (ADCH<<8));
  59.     temp = temp*Vref/1024;
  60.     temp = (temp - 0.5)/(0.01);
  61.  
  62.     msg->Data.bytes[1]= temp;
  63.     msg->Data.bytes[2]= (temp>>8);
  64.     msg->DataLength = 3;
  65.  
  66.     Can_Send( &msg );
  67. }
  68.  
  69. /*-----------------------------------------------------------------------------
  70.  * Main Program
  71.  *---------------------------------------------------------------------------*/
  72. int main(void) {
  73.  
  74.     uint8_t relayStatus;
  75.  
  76.     Timebase_Init();
  77.     Serial_Init();
  78.     sei();
  79.  
  80.     /* Turn relay off */
  81.     PORTC &= ~(1<<PC1);
  82.     DDRC |= (1<<DDC1);
  83.  
  84.     relayStatus = OFF;
  85.  
  86.     /* Initiate ADC for reading temperature sensor */
  87.  
  88.     /* Wake up ADC */
  89.     PRR &= ~(1<<PRADC);
  90. #if PDIP
  91.     /* Enable AREF and ADC0 (For PDIP package) */
  92.     ADMUX = 0x00;
  93. #else
  94.     /* Enable AREF and ADC7 (For TQFP package) */
  95.     ADMUX = 0x07;
  96. #endif
  97.  
  98.     ADCSRA |= (1<<ADEN);
  99.  
  100.     printf("\n------------------------------------------------------------\n");
  101.     printf(  "   CAN: Relay\n");
  102.     printf(  "------------------------------------------------------------\n");
  103.  
  104.  
  105.     printf("CanInit...");
  106.     if (Can_Init() != CAN_OK) {
  107.         printf("FAILED!\n");
  108.     }else{
  109.         printf("OK!\n");
  110.     }
  111.  
  112.     uint32_t timeStamp = 0;
  113.  
  114.     Can_Message_t txMsg;
  115.     Can_Message_t rxMsg;
  116.     txMsg.Id = 0;
  117.     txMsg.RemoteFlag = 0;
  118.     txMsg.ExtendedFlag = 1;
  119.  
  120.  
  121.     /* main loop */
  122.     while (1) {
  123.         /* service the CAN routines */
  124.         Can_Service();
  125.  
  126.         /* check if any messages have been received */
  127.         while (Can_Receive(&rxMsg) == CAN_OK) {
  128.             /* This relay is adressed*/
  129.             if( rxMsg.Id == 0x1200 ){
  130.  
  131.                 if( rxMsg.Data.bytes[0] == 0x01 ){
  132.                     /* Turn relay on */
  133.  
  134.                     /* Set as input and enable pull-up */
  135.                     DDRC &= ~(1<<DDC1);
  136.                     PORTC |= (1<<PC1);
  137.  
  138.                     relayStatus = ON;
  139.  
  140.                 }else if(rxMsg.Data.bytes[0] == 0x02){
  141.                     /* Turn relay off */
  142.  
  143.                     PORTC &= ~(1<<PC1);
  144.                     DDRC |= (1<<DDC1);
  145.  
  146.                     relayStatus = OFF;
  147.  
  148.                 }else if(rxMsg.Data.bytes[0] == 0x03){
  149.                     /* Toggle relay */
  150.  
  151.                     if(relayStatus == ON){
  152.                         PORTC &= ~(1<<PC1);
  153.                         DDRC |= (1<<DDC1);
  154.  
  155.                         relayStatus = OFF;
  156.  
  157.                     }else{
  158.                         DDRC &= ~(1<<DDC1);
  159.                         PORTC |= (1<<PC1);
  160.  
  161.                         relayStatus = ON;
  162.                     }
  163.  
  164.                 }else if(rxMsg.Data.bytes[0] == 0x04){
  165.                     /* Get relay status (ON/OFF?, temperature) */
  166.                     sendRelayStatus( &txMsg, relayStatus );
  167.                 }
  168.             }
  169.         }
  170.  
  171.         // TODO
  172.         // ska status på relä och temperatur skickas periodiskt?
  173.         // tätare intervall om temperaturen kommer över en viss gräns?
  174.  
  175.         if( Timebase_PassedTimeMillis(timeStamp) >=5000){
  176.             timeStamp = Timebase_CurrentTime();
  177.             /* Get relay status (ON/OFF?, temperature) and send */
  178.  
  179.              sendRelayStatus( &txMsg, relayStatus );
  180.         }
  181.     }
  182.     return 0;
  183. }
  184.  
  185.