Subversion Repositories HomeAutomation

Rev

Rev 184 | Rev 187 | 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 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>
  14.  *
  15.  *  TODO fixa så status/temp ligger i en funktion
  16.  *  temperaturomvandlingen fungerar fint
  17.  *  fixa så adcn inte pollas hela tiden, det tar för mycket tid
  18.  *  kunna använda Vref = 1.1
  19.  *
  20.  */
  21.  
  22. /*
  23.  * For testing with ATmega88 PDIP enable this fetaure
  24.  * Since PDIP doesn't have ADC7 it will use the ADC0 instead
  25.  */
  26. #define PDIP    1
  27. #define DEBUG   0 /* Prints debug messages to uart */
  28.  
  29. /*-----------------------------------------------------------------------------
  30.  * Includes
  31.  *---------------------------------------------------------------------------*/
  32. /* system files */
  33. #include <avr/io.h>
  34. #include <avr/interrupt.h>
  35. #include <avr/wdt.h>
  36. #include <stdio.h>
  37. /* lib files */
  38. #include <can.h>
  39. #include <serial.h>
  40. #include <timebase.h>
  41. /* defines */
  42. #define OFF     0x00
  43. #define ON      0x01
  44. #define Vref    5 /* For Aref use 5, internal ref 1.1 */
  45.  
  46. /*-----------------------------------------------------------------------------
  47.  * Main Program
  48.  *---------------------------------------------------------------------------*/
  49. int main(void) {
  50.  
  51.     uint8_t relayStatus;
  52.     uint32_t boardTemperature;
  53.  
  54.     Timebase_Init();
  55. #if DEBUG
  56.     Serial_Init();
  57. #endif
  58.     sei();
  59.  
  60.     /* Turn relay off */
  61.     PORTC &= ~(1<<PC1);
  62.     DDRC |= (1<<DDC1);
  63.  
  64.     relayStatus = OFF;
  65.  
  66.     /* Initiate ADC for reading temperature sensor */
  67.  
  68.     /* Wake up ADC */
  69.     PRR &= ~(1<<PRADC);
  70. #if PDIP
  71.     /* Enable AREF and ADC0 (For PDIP package) */
  72.     ADMUX = 0x00; // TODO 0x00 för aref, 0xc0 för internal 1,1
  73. #else
  74.     /* Enable AREF and ADC7 (For TQFP package) */
  75.     ADMUX = 0x07;
  76. #endif
  77.     ADCSRA |= (1<<ADEN);
  78.  
  79. #if DEBUG
  80.     printf("\n------------------------------------------------------------\n");
  81.     printf(  "   CAN: Relay\n");
  82.     printf(  "------------------------------------------------------------\n");
  83.  
  84.  
  85.     printf("CanInit...");
  86.     if (Can_Init() != CAN_OK) {
  87.         printf("FAILED!\n");
  88.     }else{
  89.         printf("OK!\n");
  90.     }
  91. #else
  92.     Can_Init();
  93. #endif
  94.     uint32_t timeStamp = 0;
  95.  
  96.     Can_Message_t txMsg;
  97.     Can_Message_t rxMsg;
  98.     txMsg.Id = 0;
  99.     txMsg.RemoteFlag = 0;
  100.     txMsg.ExtendedFlag = 1;
  101.  
  102.     /* main loop */
  103.     while (1) {
  104.         /* service the CAN routines */
  105.         Can_Service();
  106.  
  107.         /* check if any messages have been received */
  108.         while (Can_Receive(&rxMsg) == CAN_OK) {
  109.             /* This relay is adressed*/
  110.             if( rxMsg.Id == 0x1200 ){
  111.  
  112.                 if( rxMsg.Data.bytes[0] == 0x01 ){
  113.                     /* Turn relay on */
  114.  
  115.                     /* Set as input and enable pull-up */
  116.                     DDRC &= ~(1<<DDC1);
  117.                     PORTC |= (1<<PC1);
  118.  
  119.                     relayStatus = ON;
  120. #if DEBUG
  121.                     printf("turn on\n");
  122. #endif
  123.  
  124.                 }else if(rxMsg.Data.bytes[0] == 0x02){
  125.                     /* Turn relay off */
  126.  
  127.                     PORTC &= ~(1<<PC1);
  128.                     DDRC |= (1<<DDC1);
  129.  
  130.                     relayStatus = OFF;
  131. #if DEBUG
  132.                     printf("turn off\n");
  133. #endif
  134.  
  135.                 }else if(rxMsg.Data.bytes[0] == 0x03){
  136.                     /* Toggle relay */
  137.  
  138.                     if(relayStatus == ON){
  139.                         PORTC &= ~(1<<PC1);
  140.                         DDRC |= (1<<DDC1);
  141. #if DEBUG
  142.                         printf("toggle: turn off\n");
  143. #endif
  144.  
  145.                         relayStatus = OFF;
  146.  
  147.                     }else{
  148.                         DDRC &= ~(1<<DDC1);
  149.                         PORTC |= (1<<PC1);
  150. #if DEBUG
  151.                         printf("toggle: turn on\n");
  152. #endif
  153.  
  154.                         relayStatus = ON;
  155.                     }
  156.  
  157.                 }else if(rxMsg.Data.bytes[0] == 0x04){
  158.                     /* Get relay status (ON/OFF?, temperature) */
  159.                     ADCSRA |= (1<<ADSC);
  160.  
  161.                     /* Wait for conversion to complete */
  162.                     while( ADCSRA & (1<<ADSC) ){}
  163.  
  164.                     txMsg.Id = 0x1201; // temporary ID
  165.  
  166.                     txMsg.Data.bytes[2] = relayStatus;
  167.  
  168.                     /* Convert voltage to temperature */
  169.  
  170.                     boardTemperature = ADCW;
  171.  
  172.                     boardTemperature = boardTemperature*Vref;
  173.                     boardTemperature = (boardTemperature*100/1024)-50;
  174.  
  175.                     /* Save and send */
  176.                     txMsg.Data.bytes[0]= boardTemperature & 0x00FF;
  177.                     txMsg.Data.bytes[1]= (boardTemperature & 0xFF00)>>8;
  178.  
  179.                     txMsg.DataLength = 3;
  180.  
  181.                     Can_Send( &txMsg );
  182.                 }
  183.             }
  184.         }
  185.  
  186.         // TODO
  187.         // ska status på relä och temperatur skickas periodiskt?
  188.         // tätare intervall om temperaturen kommer över en viss gräns?
  189.  
  190.         if( Timebase_PassedTimeMillis(timeStamp) >=10000){
  191.             timeStamp = Timebase_CurrentTime();
  192.             /* Get relay status (ON/OFF?, temperature) and send */
  193.  
  194.             ADCSRA |= (1<<ADSC);
  195.  
  196.             /* Wait for conversion to complete */
  197.             while( ADCSRA & (1<<ADSC) ){}
  198.  
  199.             txMsg.Id = 0x1201; // temporary ID
  200.  
  201.             txMsg.Data.bytes[2] = relayStatus;
  202.  
  203.             /* Convert voltage to temperature */
  204.  
  205.             boardTemperature = ADCW;
  206.  
  207.             boardTemperature = boardTemperature*Vref;
  208.             boardTemperature = (boardTemperature*100/1024)-50;
  209.  
  210.             /* Save and send */
  211.             txMsg.Data.bytes[0]= boardTemperature & 0x00FF;
  212.             txMsg.Data.bytes[1]= (boardTemperature & 0xFF00)>>8;
  213.  
  214.             txMsg.DataLength = 3;
  215.             Can_Send( &txMsg );
  216. #if DEBUG
  217.             printf("Message sent...\n");
  218.             printf("Temperature: %d\nRelay status: %x, %u\n", boardTemperature, relayStatus, relayStatus);
  219. #endif
  220.  
  221.         }
  222.     }
  223.     return 0;
  224. }
  225.  
  226.