Subversion Repositories HomeAutomation

Rev

Rev 192 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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