Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
171 eqlazer 1
/**
177 eqlazer 2
 * CAN Relay.
3
 *
4
 *
5
 * @date    2006-12-17
6
 * @author  Erik Larsson
7
 *
185 eqlazer 8
 *   Observera! Applikationen är endast testad på labplatta med m88, pot och lysdiod
177 eqlazer 9
 *
175 eqlazer 10
 *   ADC=Vin*1024/Vref
176 eqlazer 11
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
175 eqlazer 12
 *
190 eqlazer 13
 *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
176 eqlazer 14
 *
184 eqlazer 15
 *
171 eqlazer 16
 */
17
 
192 eqlazer 18
#define DEBUG           1 /* Prints debug messages to uart */
19
#define TWO_BUTTON_MODE 1 /* If using two (or just one but nothing more) auxiliary buttons */
177 eqlazer 20
 
171 eqlazer 21
/*-----------------------------------------------------------------------------
22
 * Includes
23
 *---------------------------------------------------------------------------*/
24
/* system files */
25
#include <avr/io.h>
26
#include <avr/interrupt.h>
27
#include <avr/wdt.h>
28
#include <stdio.h>
29
/* lib files */
30
#include <can.h>
31
#include <serial.h>
32
#include <timebase.h>
187 eqlazer 33
 
34
#include <tc1047.h>
35
 
177 eqlazer 36
/* defines */
187 eqlazer 37
#define RELAY_OFF           0x01
38
#define RELAY_ON            0x02
39
#define FAILSAFE_MODE       0x0F
40
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
171 eqlazer 41
 
187 eqlazer 42
#define RELAY_CMD_GET       0x1200
43
#define RELAY_CMD_SEND      0x1201
44
#define RELAY_CMD_ON        0x01
45
#define RELAY_CMD_OFF       0x02
46
#define RELAY_CMD_TOGGLE    0x03
47
#define RELAY_CMD_STATUS    0x04
48
#define RELAY_CMD_RESET     0x05
49
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
192 eqlazer 50
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
51
#define BOUNCE_TIME         10 /* milliseconds */
52
#define BUTTON_ID           0x1202
53
#define BUTTON1             1
54
#define BUTTON2             2
187 eqlazer 55
 
192 eqlazer 56
/*-------------------------------------------------------------------------
57
 * Global variables
58
 * -----------------------------------------------------------------------*/
59
#if TWO_BUTTON_MODE
60
Can_Message_t txMsg_Button;
61
#endif
62
 
187 eqlazer 63
/*----------------------------------------------------------------------------
64
 * Functions
65
 * -------------------------------------------------------------------------*/
66
uint8_t relayOff();
67
uint8_t relayOn();
68
void relayFailsafe();
69
 
192 eqlazer 70
/*----------------------------------------------------------------------------
71
 * Interrupt routines
72
 * -------------------------------------------------------------------------*/
73
#if TWO_BUTTON_MODE
74
ISR( PCINT2_vect )
75
{
76
    /*
77
     * Auxiliary button pressed and released
78
     * Check time between press and release to eliminate bounces
79
     */
80
    static uint32_t buttonTime[2];
81
 
82
    txMsg_Button.RemoteFlag = 0;
83
    txMsg_Button.ExtendedFlag = 1;
84
 
85
    if( (PIND & (1<<PD6)) == 0){
86
        /* Button pressed */
87
        buttonTime[0] = Timebase_CurrentTime();
88
#if DEBUG
89
        printf("Button 1 pressed\n");
90
#endif
91
    }else if( (PIND & (1<<PD6)) == 1){
92
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
93
            /* No bounce, send message */
94
            txMsg_Button.Id = BUTTON_ID;
95
            txMsg_Button.DataLength = 1;
96
            txMsg_Button.Data.bytes[0] = BUTTON1;
97
#if DEBUG
98
            printf("Button 1 pressed: message sent\n");
99
#endif
100
            return;
101
        }else{
102
            /* Just bounces, ignore it */
103
#if DEBUG
104
            printf("Button 1 just bounced\n");
105
#endif
106
            return;
107
        }
108
    }
109
    if( (PIND & (1<<PD7)) == 0){
110
        /* Button pressed */
111
        buttonTime[1] = Timebase_CurrentTime();
112
#if DEBUG
113
        printf("Button 2 pressed\n");
114
#endif
115
    }else if( (PIND & (1<<PD7)) == 1){
116
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
117
            /* No bounce, send message */
118
            txMsg_Button.Id = BUTTON_ID;
119
            txMsg_Button.DataLength = 1;
120
            txMsg_Button.Data.bytes[0] = BUTTON2;
121
#if DEBUG
122
            printf("Button 2 pressed: message sent\n");
123
#endif
124
            return;
125
        }else{
126
            /* Just bounces, ignore it */
127
#if DEBUG
128
            printf("Button 2 just bounced\n");
129
#endif
130
            return;
131
        }
132
    }
133
}
134
#endif
135
 
136
//ISR( ADC_vect )
137
//{
138
    /*
139
     * ADC conversion completed
140
     */
141
    // TODO använd denna rutin för att läsa värde när omvandlingen är klar
142
 
143
//}
144
 
171 eqlazer 145
/*-----------------------------------------------------------------------------
146
 * Main Program
147
 *---------------------------------------------------------------------------*/
148
int main(void) {
149
 
150
    uint8_t relayStatus;
187 eqlazer 151
    uint32_t boardTemperature = 0;
171 eqlazer 152
 
187 eqlazer 153
    adcTemperatureInit();
154
 
176 eqlazer 155
    Timebase_Init();
185 eqlazer 156
#if DEBUG
176 eqlazer 157
    Serial_Init();
185 eqlazer 158
#endif
192 eqlazer 159
 
160
#if TWO_BUTTON_MODE
161
    /*
162
     * Initialize buttons
163
     * It is possible to use ie. sensors instead
164
     * but then change this
165
     */
166
    /* Set as input and enable pull-up */
167
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
168
    PORTD |= (1<<PD6)|(1<<PD7);
169
 
170
    /* Enable IO-pin interrupt */
171
    PCICR |= (1<<PCIE1);
172
    /* Unmask PD6 and PD7 */
173
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
174
        /* Button pressed */
175
#endif
176
 
177
 
176 eqlazer 178
    sei();
171 eqlazer 179
 
176 eqlazer 180
    /* Turn relay off */
187 eqlazer 181
    relayStatus = relayOff();
175 eqlazer 182
 
184 eqlazer 183
#if DEBUG
176 eqlazer 184
    printf("\n------------------------------------------------------------\n");
185
    printf(  "   CAN: Relay\n");
186
    printf(  "------------------------------------------------------------\n");
171 eqlazer 187
 
188
 
176 eqlazer 189
    printf("CanInit...");
190
    if (Can_Init() != CAN_OK) {
191
        printf("FAILED!\n");
175 eqlazer 192
    }else{
193
        printf("OK!\n");
194
    }
185 eqlazer 195
#else
196
    Can_Init();
184 eqlazer 197
#endif
175 eqlazer 198
    uint32_t timeStamp = 0;
171 eqlazer 199
 
175 eqlazer 200
    Can_Message_t txMsg;
201
    Can_Message_t rxMsg;
187 eqlazer 202
    txMsg.Id = RELAY_CMD_SEND;
175 eqlazer 203
    txMsg.RemoteFlag = 0;
204
    txMsg.ExtendedFlag = 1;
187 eqlazer 205
    txMsg.DataLength = 3;
175 eqlazer 206
 
207
    /* main loop */
208
    while (1) {
209
        /* service the CAN routines */
210
        Can_Service();
211
 
212
        /* check if any messages have been received */
213
        while (Can_Receive(&rxMsg) == CAN_OK) {
171 eqlazer 214
            /* This relay is adressed*/
187 eqlazer 215
            if( rxMsg.Id == RELAY_CMD_GET ){
171 eqlazer 216
 
187 eqlazer 217
                if( rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
171 eqlazer 218
                    /* Turn relay on */
187 eqlazer 219
                    relayStatus = relayOn();
171 eqlazer 220
 
187 eqlazer 221
                }else if(rxMsg.Data.bytes[0] == RELAY_CMD_OFF){
222
                    /* Turn relay off */
223
                    relayStatus = relayOff();
175 eqlazer 224
 
187 eqlazer 225
                }else if(rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
226
                    /* Toggle relay */
171 eqlazer 227
 
187 eqlazer 228
                    if(relayStatus == RELAY_OFF){
229
                        relayStatus = relayOn();
230
                    }else{
231
                        relayStatus = relayOff();
232
                    }
171 eqlazer 233
 
187 eqlazer 234
                }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS){
235
                    /* Send relay status to CAN */
175 eqlazer 236
 
187 eqlazer 237
                    boardTemperature = getTC1047temperature();
171 eqlazer 238
 
190 eqlazer 239
                    if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
187 eqlazer 240
                        relayFailsafe();
241
                    }else{
242
                        txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
243
                        txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
244
                        txMsg.Data.bytes[2] = relayStatus;
171 eqlazer 245
 
187 eqlazer 246
                        Can_Send( &txMsg );
247
                    }
248
                }
249
            }
250
        }
251
 
252
        if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
253
            timeStamp = Timebase_CurrentTime();
254
            /* Send relay status to CAN */
255
 
256
            boardTemperature = getTC1047temperature();
257
 
190 eqlazer 258
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
187 eqlazer 259
                relayFailsafe();
260
            }else{
261
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
262
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
263
                txMsg.Data.bytes[2] = relayStatus;
264
 
265
                Can_Send( &txMsg );
184 eqlazer 266
#if DEBUG
187 eqlazer 267
                printf("Periodic message sent...\n");
268
                printf("Temperature: %d\nRelay status: %u\n", boardTemperature, relayStatus);
184 eqlazer 269
#endif
187 eqlazer 270
            }
271
        }
272
    }
273
    return 0;
274
}
176 eqlazer 275
 
187 eqlazer 276
uint8_t relayOff()
277
{
278
    /* Set as output and sink */
279
    PORTC &= ~(1<<PC1);
280
    DDRC |= (1<<DDC1);
175 eqlazer 281
 
184 eqlazer 282
#if DEBUG
187 eqlazer 283
    printf("relay turned off\n");
184 eqlazer 284
#endif
176 eqlazer 285
 
187 eqlazer 286
    return RELAY_OFF;
287
}
171 eqlazer 288
 
187 eqlazer 289
uint8_t relayOn()
290
{
291
    /* Set as input and enable pull-up */
292
    DDRC &= ~(1<<DDC1);
293
    PORTC |= (1<<PC1);
184 eqlazer 294
 
187 eqlazer 295
#if DEBUG
296
    printf("relay turned on\n");
297
#endif
184 eqlazer 298
 
187 eqlazer 299
    return RELAY_ON;
300
}
184 eqlazer 301
 
187 eqlazer 302
void relayFailsafe()
303
{
304
    uint8_t relayStatus;
305
    uint32_t boardTemperature = 0, timeStamp = 0;
184 eqlazer 306
 
187 eqlazer 307
    Can_Message_t txMsg;
308
    Can_Message_t rxMsg;
309
    txMsg.Id = RELAY_CMD_SEND;
310
    txMsg.RemoteFlag = 0;
311
    txMsg.ExtendedFlag = 1;
312
    txMsg.DataLength = 4;
184 eqlazer 313
 
187 eqlazer 314
    relayStatus = relayOff();
184 eqlazer 315
 
187 eqlazer 316
    while(1){
317
        /* service the CAN routines */
318
        Can_Service();
184 eqlazer 319
 
187 eqlazer 320
        /* check if any messages have been received */
321
        while (Can_Receive(&rxMsg) == CAN_OK) {
322
            /* This relay is adressed*/
323
            if( rxMsg.Id == RELAY_CMD_GET ){
324
                if( rxMsg.Data.bytes[0] == RELAY_CMD_RESET ){
325
                    /* Return from failsafe mode */
192 eqlazer 326
                    return;
171 eqlazer 327
                }
328
            }
329
        }
330
 
187 eqlazer 331
        if( Timebase_PassedTimeMillis(timeStamp) >= FAILSAFE_SEND_PERIOD ){
171 eqlazer 332
            timeStamp = Timebase_CurrentTime();
187 eqlazer 333
            /* Send relay status to CAN */
190 eqlazer 334
#if DEBUG
335
            printf("Failsafe mode!\n");
336
#endif
187 eqlazer 337
            boardTemperature = getTC1047temperature();
184 eqlazer 338
 
187 eqlazer 339
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
340
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
185 eqlazer 341
            txMsg.Data.bytes[2] = relayStatus;
187 eqlazer 342
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
184 eqlazer 343
 
344
            Can_Send( &txMsg );
171 eqlazer 345
        }
177 eqlazer 346
    }
171 eqlazer 347
}
175 eqlazer 348