Subversion Repositories HomeAutomation

Rev

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

Rev 352 Rev 354
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
 *   ADC=Vin*1024/Vref
8
 *   ADC=Vin*1024/Vref
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
10
 *
10
 *
11
 *  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>
12
 *
12
 *
13
 *
13
 *
14
 */
14
 */
15
 
15
 
16
#define TWO_BUTTON_MODE 0 /* 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 */
17
 
17
 
18
/*-----------------------------------------------------------------------------
18
/*-----------------------------------------------------------------------------
19
 * Includes
19
 * Includes
20
 *---------------------------------------------------------------------------*/
20
 *---------------------------------------------------------------------------*/
21
/* system files */
21
/* system files */
22
#include <avr/io.h>
22
#include <avr/io.h>
23
#include <avr/interrupt.h>
23
#include <avr/interrupt.h>
24
#include <stdio.h>
24
#include <stdio.h>
25
#include <avr/wdt.h>
25
#include <avr/wdt.h>
26
/* lib files */
26
/* lib files */
27
#include <bios.h>
27
#include <bios.h>
28
#include <tc1047.h>
28
#include <tc1047.h>
29
#include <funcdefs.h>
29
#include <funcdefs.h>
30
 
30
 
31
/* defines */
31
/* defines */
32
#define GROUP_ID        0x01UL
32
#define GROUP_ID        0x01UL
33
 
33
 
34
#define RELAY_OFF           0x01UL
34
#define RELAY_OFF           0x01UL
35
#define RELAY_ON            0x02UL
35
#define RELAY_ON            0x02UL
36
#define FAILSAFE_MODE       0x0FUL
36
#define FAILSAFE_MODE       0x0FUL
37
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
37
#define FAILSAFE_TRESHOLD   60  /* Degrees when nodeRelay goes into failsafe mode */
38
 
38
 
39
#define RELAY_CMD_ON        0x01UL
39
#define RELAY_CMD_ON        0x01UL
40
#define RELAY_CMD_OFF       0x02UL
40
#define RELAY_CMD_OFF       0x02UL
41
#define RELAY_CMD_TOGGLE    0x03UL
41
#define RELAY_CMD_TOGGLE    0x03UL
42
#define RELAY_CMD_STATUS    0x04UL
42
#define RELAY_CMD_STATUS    0x04UL
43
#define RELAY_CMD_RESET     0x05UL
43
#define RELAY_CMD_RESET     0x05UL
44
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
44
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
45
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
45
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
46
#define BOUNCE_TIME         10 /* milliseconds */
46
#define BOUNCE_TIME         10 /* milliseconds */
47
#define BUTTON1             1
47
#define BUTTON1             1
48
#define BUTTON2             2
48
#define BUTTON2             2
49
 
49
 
50
/*-------------------------------------------------------------------------
50
/*-------------------------------------------------------------------------
51
 * Global variables
51
 * Global variables
52
 * -----------------------------------------------------------------------*/
52
 * -----------------------------------------------------------------------*/
53
#if TWO_BUTTON_MODE
53
#if TWO_BUTTON_MODE
54
Can_Message_t txMsg_Button;
54
Can_Message_t txMsg_Button;
55
#endif
55
#endif
-
 
56
 
56
 
57
 
57
uint8_t relayStatus, failsafe_flag = 0;
58
uint8_t relayStatus, failsafe_flag = 0;
58
uint32_t boardTemperature = 0;
59
uint32_t boardTemperature = 0;
59
Can_Message_t txMsg;
60
Can_Message_t txMsg;
60
 
61
 
61
/*----------------------------------------------------------------------------
62
/*----------------------------------------------------------------------------
62
 * Functions
63
 * Functions
63
 * -------------------------------------------------------------------------*/
64
 * -------------------------------------------------------------------------*/
64
uint8_t relayOff();
65
uint8_t relayOff();
65
uint8_t relayOn();
66
uint8_t relayOn();
66
void relayFailsafe();
67
void relayFailsafe();
67
 
68
 
68
void can_receive(Can_Message_t *msg){
69
void can_receive(Can_Message_t *msg){
69
    uint32_t act;
70
    uint32_t act;
70
    uint32_t m, act_type, group, node;
71
    uint32_t m, act_type, group, node;
71
 
72
 
72
    if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
73
    if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
73
 
74
 
74
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
75
        act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
75
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
76
        act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
76
        group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
77
        group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
77
        node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
78
        node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
78
 
79
 
79
        if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
80
        if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
80
            if(msg->Data.bytes[0] == RELAY_CMD_ON && !failsafe_flag){
81
            if(msg->Data.bytes[0] == RELAY_CMD_ON && !failsafe_flag){
81
                // Turn relay on
82
                // Turn relay on
82
                relayStatus = relayOn();
83
                relayStatus = relayOn();
83
 
84
 
84
            }else if(msg->Data.bytes[0] == RELAY_CMD_OFF && !failsafe_flag){
85
            }else if(msg->Data.bytes[0] == RELAY_CMD_OFF && !failsafe_flag){
85
                // Turn relay off
86
                // Turn relay off
86
                relayStatus = relayOff();
87
                relayStatus = relayOff();
87
                txMsg.Id = 0x8000111UL; // FIXME
88
                txMsg.Id = 0x8000111UL; // FIXME
88
                bios->can_send(&txMsg);
89
                bios->can_send(&txMsg);
89
 
90
 
90
            }else if(msg->Data.bytes[0] == RELAY_CMD_TOGGLE && !failsafe_flag){
91
            }else if(msg->Data.bytes[0] == RELAY_CMD_TOGGLE && !failsafe_flag){
91
                    // Toggle relay
92
                    // Toggle relay
92
                    if(relayStatus == RELAY_OFF){
93
                    if(relayStatus == RELAY_OFF){
93
                        relayStatus = relayOn();
94
                        relayStatus = relayOn();
94
                    }else{
95
                    }else{
95
                        relayStatus = relayOff();
96
                        relayStatus = relayOff();
96
                        txMsg.Id = 0x8000113UL; // FIXME
97
                        txMsg.Id = 0x8000113UL; // FIXME
97
                        bios->can_send(&txMsg);
98
                        bios->can_send(&txMsg);
98
                    }
99
                    }
99
 
100
 
100
            }else if(msg->Data.bytes[0] == RELAY_CMD_STATUS && !failsafe_flag){
101
            }else if(msg->Data.bytes[0] == RELAY_CMD_STATUS && !failsafe_flag){
101
                // Send relay status to CAN
102
                // Send relay status to CAN
102
                boardTemperature = getTC1047temperature();
103
                boardTemperature = getTC1047temperature();
103
 
104
 
104
                if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
105
                if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
105
                    // Goto failsafe mode
106
                    // Goto failsafe mode
106
                    relayFailsafe();
107
                    relayFailsafe();
107
                }else{
108
                }else{
108
                    // Transmitt node status
109
                    // Transmitt node status
109
                    txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
110
                    txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
110
                    txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
111
                    txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
111
                    txMsg.Data.bytes[2] = relayStatus;
112
                    txMsg.Data.bytes[2] = relayStatus;
112
                    txMsg.Data.bytes[3] = 0;
113
                    txMsg.Data.bytes[3] = 0;
113
                    txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
114
                    txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
114
                    bios->can_send( &txMsg );
115
                    bios->can_send( &txMsg );
115
                }
116
                }
116
            }else if(msg->Data.bytes[0] == RELAY_CMD_RESET){
117
            }else if(msg->Data.bytes[0] == RELAY_CMD_RESET){
117
                // Return to normal operation
118
                // Return to normal operation
118
                failsafe_flag = 0;
119
                failsafe_flag = 0;
119
            }
120
            }
120
        }
121
        }
121
    }
122
    }
122
}
123
}
123
 
124
 
124
/*----------------------------------------------------------------------------
125
/*----------------------------------------------------------------------------
125
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
126
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
126
 * -------------------------------------------------------------------------*/
127
 * -------------------------------------------------------------------------*/
127
#if TWO_BUTTON_MODE
128
#if TWO_BUTTON_MODE
128
ISR( PCINT2_vect )
129
ISR( PCINT2_vect )
129
{
130
{
130
    /*
131
    /*
131
     * Auxiliary button pressed and released
132
     * Auxiliary button pressed and released
132
     * Check time between press and release to eliminate bounces
133
     * Check time between press and release to eliminate bounces
133
     */
134
     */
134
    static uint32_t buttonTime[2];
135
    static uint32_t buttonTime[2];
135
 
136
 
136
    txMsg_Button.RemoteFlag = 0;
137
    txMsg_Button.RemoteFlag = 0;
137
    txMsg_Button.ExtendedFlag = 1;
138
    txMsg_Button.ExtendedFlag = 1;
138
 
139
 
139
    if( (PIND & (1<<PD6)) == 0){
140
    if( (PIND & (1<<PD6)) == 0){
140
        /* Button pressed */
141
        /* Button pressed */
141
        buttonTime[0] = Timebase_CurrentTime();
142
        buttonTime[0] = Timebase_CurrentTime();
142
    }else if( (PIND & (1<<PD6)) == 1){
143
    }else if( (PIND & (1<<PD6)) == 1){
143
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
144
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
144
            /* No bounce, send message */
145
            /* No bounce, send message */
145
            txMsg_Button.Id = BUTTON_ID;
146
            txMsg_Button.Id = BUTTON_ID;
146
            txMsg_Button.DataLength = 1;
147
            txMsg_Button.DataLength = 1;
147
            txMsg_Button.Data.bytes[0] = BUTTON1;
148
            txMsg_Button.Data.bytes[0] = BUTTON1;
148
            return;
149
            return;
149
        }else{
150
        }else{
150
            /* Just bounces, ignore it */
151
            /* Just bounces, ignore it */
151
            return;
152
            return;
152
        }
153
        }
153
    }
154
    }
154
    if( (PIND & (1<<PD7)) == 0){
155
    if( (PIND & (1<<PD7)) == 0){
155
        /* Button pressed */
156
        /* Button pressed */
156
        buttonTime[1] = Timebase_CurrentTime();
157
        buttonTime[1] = Timebase_CurrentTime();
157
    }else if( (PIND & (1<<PD7)) == 1){
158
    }else if( (PIND & (1<<PD7)) == 1){
158
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
159
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
159
            /* No bounce, send message */
160
            /* No bounce, send message */
160
            txMsg_Button.Id = BUTTON_ID;
161
            txMsg_Button.Id = BUTTON_ID;
161
            txMsg_Button.DataLength = 1;
162
            txMsg_Button.DataLength = 1;
162
            txMsg_Button.Data.bytes[0] = BUTTON2;
163
            txMsg_Button.Data.bytes[0] = BUTTON2;
163
            return;
164
            return;
164
        }else{
165
        }else{
165
            /* Just bounces, ignore it */
166
            /* Just bounces, ignore it */
166
            return;
167
            return;
167
        }
168
        }
168
    }
169
    }
169
}
170
}
170
#endif
171
#endif
171
 
172
 
172
/*-----------------------------------------------------------------------------
173
/*-----------------------------------------------------------------------------
173
 * Main Program
174
 * Main Program
174
 *---------------------------------------------------------------------------*/
175
 *---------------------------------------------------------------------------*/
175
int main(void) {
176
int main(void) {
176
 
177
 
177
    adcTemperatureInit();
178
    adcTemperatureInit();
178
 
179
 
179
#if TWO_BUTTON_MODE
180
#if TWO_BUTTON_MODE
180
#error two button mode not yet tested
181
#error two button mode not yet tested
181
    /*
182
    /*
182
     * Initialize buttons
183
     * Initialize buttons
183
     * It is possible to use ie. sensors instead
184
     * It is possible to use ie. sensors instead
184
     * but then change this
185
     * but then change this
185
     */
186
     */
186
    // Set as input and enable pull-up
187
    // Set as input and enable pull-up
187
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
188
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
188
    PORTD |= (1<<PD6)|(1<<PD7);
189
    PORTD |= (1<<PD6)|(1<<PD7);
189
 
190
 
190
    // Enable IO-pin interrupt
191
    // Enable IO-pin interrupt
191
    PCICR |= (1<<PCIE1);
192
    PCICR |= (1<<PCIE1);
192
    // Unmask PD6 and PD7
193
    // Unmask PD6 and PD7
193
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
194
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
194
#endif
195
#endif
195
 
196
 
196
    // Control channel for relay
197
    // Control channel for relay
197
    DDRC |= (1<<DDC1);
198
    DDRC |= (1<<DDC1);
198
 
199
 
199
    // Set up callback for CAN messages
200
    // Set up callback for CAN messages
200
    bios->can_callback = &can_receive;
201
//  bios->can_callback = &can_receive;
201
 
202
 
202
    txMsg.RemoteFlag = 0;
203
    txMsg.RemoteFlag = 0;
203
    txMsg.ExtendedFlag = 1;
204
    txMsg.ExtendedFlag = 1;
204
    txMsg.DataLength = 4;
205
    txMsg.DataLength = 4;
205
 
206
 
206
    sei();
207
    sei();
207
 
208
 
208
    // Turn relay off
209
    // Turn relay off
209
    relayStatus = relayOff();
210
    relayStatus = relayOff();
210
    txMsg.Id = 0x8000110UL; // FIXME
211
    txMsg.Id = 0x8000110UL; // FIXME
211
    bios->can_send(&txMsg);
212
    bios->can_send(&txMsg);
212
 
213
 
213
    uint32_t timeStamp = 0;
214
    uint32_t timeStamp = bios->timebase_get(), temp;
214
 
215
 
215
 
216
 
216
    // Main loop
217
    // Main loop
217
    while (1) {
218
    while (1) {
218
 
219
 
-
 
220
        temp = bios->timebase_get();
219
        if( bios->timebase_get() - timeStamp >= STATUS_SEND_PERIOD ){
221
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
220
            timeStamp = bios->timebase_get();
222
            timeStamp = temp;
221
            // Send relay status to CAN
223
            // Send relay status to CAN
222
 
224
 
223
            boardTemperature = getTC1047temperature();
225
//          boardTemperature = getTC1047temperature();
224
 
226
 
225
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
227
//          if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
226
                relayFailsafe();
228
//              relayFailsafe();
227
            }else{
229
//          }else{
228
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
230
                txMsg.Data.bytes[0] = timeStamp & 0x000000FF; //boardTemperature & 0x00FF;
229
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
231
                txMsg.Data.bytes[1] = (timeStamp & 0x0000FF00)>>8; //(boardTemperature & 0xFF00)>>8;
230
                txMsg.Data.bytes[2] = relayStatus;
232
                txMsg.Data.bytes[2] = (timeStamp & 0x00FF0000)>>16; //relayStatus;
231
                txMsg.Data.bytes[3] = 0;
233
                txMsg.Data.bytes[3] = (timeStamp & 0xFF000000)>>24; //0;
232
                txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
234
                txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
233
                bios->can_send( &txMsg );
235
                bios->can_send( &txMsg );
234
            }
236
//          }
235
        }
237
        }
236
    }
238
    }
237
    return 0;
239
    return 0;
238
}
240
}
239
 
241
 
240
uint8_t relayOff()
242
uint8_t relayOff()
241
{
243
{
242
    // Turn off relay
244
    // Turn off relay
243
    PORTC &= ~(1<<PC1);
245
    PORTC &= ~(1<<PC1);
244
    DDRC |= (1<<DDC1); // FIXME
246
    DDRC |= (1<<DDC1); // FIXME
245
 
247
 
246
    return RELAY_OFF;
248
    return RELAY_OFF;
247
}
249
}
248
 
250
 
249
uint8_t relayOn()
251
uint8_t relayOn()
250
{
252
{
251
    // Turn on relay
253
    // Turn on relay
252
    DDRC &= ~(1<<DDC1); // FIXME
254
    DDRC &= ~(1<<DDC1); // FIXME
253
    PORTC |= (1<<PC1);
255
    PORTC |= (1<<PC1);
254
 
256
 
255
    return RELAY_ON;
257
    return RELAY_ON;
256
}
258
}
257
 
259
 
258
void relayFailsafe()
260
void relayFailsafe()
259
{
261
{
260
    uint32_t timeStamp = 0;
262
    uint32_t timeStamp = 0;
261
 
263
 
262
    relayStatus = relayOff();
264
    relayStatus = relayOff();
263
    failsafe_flag = 1;
265
    failsafe_flag = 1;
264
 
266
 
265
    while(1){
267
    while(1){
266
 
268
 
267
        if( !failsafe_flag ){
269
        if( !failsafe_flag ){
268
            // Return from failsafe mode
270
            // Return from failsafe mode
269
            return;
271
            return;
270
        }
272
        }
271
 
273
 
272
        if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
274
        if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
273
            timeStamp = bios->timebase_get();
275
            timeStamp = bios->timebase_get();
274
            // Send relay status to CAN
276
            // Send relay status to CAN
275
            boardTemperature = getTC1047temperature();
277
            boardTemperature = getTC1047temperature();
276
 
278
 
277
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
279
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
278
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
280
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
279
            txMsg.Data.bytes[2] = relayStatus;
281
            txMsg.Data.bytes[2] = relayStatus;
280
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
282
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
281
            txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
283
            txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
282
 
284
 
283
            bios->can_send( &txMsg );
285
            bios->can_send( &txMsg );
284
        }
286
        }
285
    }
287
    }
286
}
288
}
287
 
289
 
288
 
290