/**
* CAN Relay.
*
*
* @date 2006-12-17
* @author Erik Larsson
*
* Observera! Applikationen är endast testad på labplatta med m88, pot och lysdiod
*
* ADC=Vin*1024/Vref
* Vout=( 10 mV/C )( Temperature C ) + 500 mV
*
* Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status>
*
* TODO fixa så status/temp ligger i en funktion
* temperaturomvandlingen fungerar fint
* fixa så adcn inte pollas hela tiden, det tar för mycket tid
* kunna använda Vref = 1.1
*
*/
/*
* For testing with ATmega88 PDIP enable this fetaure
* Since PDIP doesn't have ADC7 it will use the ADC0 instead
*/
#define PDIP 1
#define DEBUG 0 /* Prints debug messages to uart */
/*-----------------------------------------------------------------------------
* Includes
*---------------------------------------------------------------------------*/
/* system files */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>
/* lib files */
#include <can.h>
#include <serial.h>
#include <timebase.h>
/* defines */
#define OFF 0x00
#define ON 0x01
#define Vref 5 /* For Aref use 5, internal ref 1.1 */
/*-----------------------------------------------------------------------------
* Main Program
*---------------------------------------------------------------------------*/
int main(void) {
uint8_t relayStatus;
uint32_t boardTemperature;
Timebase_Init();
#if DEBUG
Serial_Init();
#endif
sei();
/* Turn relay off */
PORTC &= ~(1<<PC1);
DDRC |= (1<<DDC1);
relayStatus = OFF;
/* Initiate ADC for reading temperature sensor */
/* Wake up ADC */
PRR &= ~(1<<PRADC);
#if PDIP
/* Enable AREF and ADC0 (For PDIP package) */
ADMUX = 0x00; // TODO 0x00 för aref, 0xc0 för internal 1,1
#else
/* Enable AREF and ADC7 (For TQFP package) */
ADMUX = 0x07;
#endif
ADCSRA |= (1<<ADEN);
#if DEBUG
printf("\n------------------------------------------------------------\n");
printf( "------------------------------------------------------------\n");
if (Can_Init() != CAN_OK) {
}else{
}
#else
Can_Init();
#endif
uint32_t timeStamp = 0;
Can_Message_t txMsg;
Can_Message_t rxMsg;
txMsg.Id = 0;
txMsg.RemoteFlag = 0;
txMsg.ExtendedFlag = 1;
/* main loop */
while (1) {
/* service the CAN routines */
Can_Service();
/* check if any messages have been received */
while (Can_Receive(&rxMsg) == CAN_OK) {
/* This relay is adressed*/
if( rxMsg.Id == 0x1200 ){
if( rxMsg.Data.bytes[0] == 0x01 ){
/* Turn relay on */
/* Set as input and enable pull-up */
DDRC &= ~(1<<DDC1);
PORTC |= (1<<PC1);
relayStatus = ON;
#if DEBUG
#endif
}else if(rxMsg.Data.bytes[0] == 0x02){
/* Turn relay off */
PORTC &= ~(1<<PC1);
DDRC |= (1<<DDC1);
relayStatus = OFF;
#if DEBUG
#endif
}else if(rxMsg.Data.bytes[0] == 0x03){
/* Toggle relay */
if(relayStatus == ON){
PORTC &= ~(1<<PC1);
DDRC |= (1<<DDC1);
#if DEBUG
#endif
relayStatus = OFF;
}else{
DDRC &= ~(1<<DDC1);
PORTC |= (1<<PC1);
#if DEBUG
#endif
relayStatus = ON;
}
}else if(rxMsg.Data.bytes[0] == 0x04){
/* Get relay status (ON/OFF?, temperature) */
ADCSRA |= (1<<ADSC);
/* Wait for conversion to complete */
while( ADCSRA & (1<<ADSC) ){}
txMsg.Id = 0x1201; // temporary ID
txMsg.Data.bytes[2] = relayStatus;
/* Convert voltage to temperature */
boardTemperature = ADCW;
boardTemperature = boardTemperature*Vref;
boardTemperature = (boardTemperature*100/1024)-50;
/* Save and send */
txMsg.Data.bytes[0]= boardTemperature & 0x00FF;
txMsg.Data.bytes[1]= (boardTemperature & 0xFF00)>>8;
txMsg.DataLength = 3;
Can_Send( &txMsg );
}
}
}
// TODO
// ska status på relä och temperatur skickas periodiskt?
// tätare intervall om temperaturen kommer över en viss gräns?
if( Timebase_PassedTimeMillis(timeStamp) >=10000){
timeStamp = Timebase_CurrentTime();
/* Get relay status (ON/OFF?, temperature) and send */
ADCSRA |= (1<<ADSC);
/* Wait for conversion to complete */
while( ADCSRA & (1<<ADSC) ){}
txMsg.Id = 0x1201; // temporary ID
txMsg.Data.bytes[2] = relayStatus;
/* Convert voltage to temperature */
boardTemperature = ADCW;
boardTemperature = boardTemperature*Vref;
boardTemperature = (boardTemperature*100/1024)-50;
/* Save and send */
txMsg.Data.bytes[0]= boardTemperature & 0x00FF;
txMsg.Data.bytes[1]= (boardTemperature & 0xFF00)>>8;
txMsg.DataLength = 3;
Can_Send( &txMsg );
#if DEBUG
printf("Temperature: %d\nRelay status: %x, %u\n", boardTemperature
, relayStatus
, relayStatus
);
#endif
}
}
return 0;
}