Subversion Repositories HomeAutomation

Rev

Rev 196 | Rev 352 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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