Subversion Repositories HomeAutomation

Rev

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

Rev 245 Rev 246
1
/**
1
/**
2
 * CanBlinds.
2
 * CanBlinds.
3
 * Takes incomming packages and adjusts PWM output.
3
 * Takes incomming packages and adjusts PWM output.
4
 * Input: -128 to +127
4
 * Input: -128 to +127
5
 * Position msg: <byte0 BLINDS_CMD> <byte1 position>
5
 * Position msg: <byte0 BLINDS_CMD> <byte1 position>
6
 * Turning msg: <byte0 START/STOP> <byte 1 direction>
6
 * Turning msg: <byte0 START/STOP> <byte 1 direction>
7
 *
7
 *
8
 * @date    2001-01-01
8
 * @date    2001-01-01
9
 * @author  Erik Larsson
9
 * @author  Erik Larsson
10
 */
10
 */
11
 
11
 
12
#define DEBUG           0 /* Prints debug messages to uart */
12
#define DEBUG           0 /* Prints debug messages to uart */
13
//#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
13
#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
14
 
14
 
15
/*-----------------------------------------------------------------------------
15
/*-----------------------------------------------------------------------------
16
 * Includes
16
 * Includes
17
 *---------------------------------------------------------------------------*/
17
 *---------------------------------------------------------------------------*/
18
/* system files */
18
/* system files */
19
#include <avr/io.h>
19
#include <avr/io.h>
20
#include <avr/interrupt.h>
20
#include <avr/interrupt.h>
21
#include <avr/wdt.h>
21
#include <avr/wdt.h>
22
#include <stdio.h>
22
#include <stdio.h>
23
/* lib files */
23
/* lib files */
24
#include <can.h>
24
#include <can.h>
25
#if DEBUG
25
#if DEBUG
26
#include <serial.h>
26
#include <serial.h>
27
#endif
27
#endif
28
#include <timebase.h>
28
#include <timebase.h>
29
 
29
 
30
#include "tc1047.h"
30
#include <tc1047.h>
31
#include <rc_servo.h>
31
#include <rc_servo.h>
32
 
32
 
33
/* defines */
33
/* defines */
34
#define FAILSAFE_MODE       0x0F
34
#define FAILSAFE_MODE       0x0F
35
#define FAILSAFE_TRESHOLD   60  /* Degrees celcius when nodeBlinds goes into failsafe mode */
35
#define FAILSAFE_TRESHOLD   60  /* Degrees celcius when nodeBlinds goes into failsafe mode */
36
 
36
 
37
#define BLINDS_CMD_GET      0x1300
37
#define BLINDS_CMD_GET      0x1300
38
#define BLINDS_CMD_SEND     0x1301
38
#define BLINDS_CMD_SEND     0x1301
39
 
39
 
40
#define BLINDS_CMD_ABS      0x01 /* Absolute position */
40
#define BLINDS_CMD_ABS      0x01 /* Absolute position */
41
#define BLINDS_CMD_REL      0x02 /* Relative position */
41
#define BLINDS_CMD_REL      0x02 /* Relative position */
42
#define BLINDS_CMD_START    0x03 /* Start turning RC-servo */
42
#define BLINDS_CMD_START    0x03 /* Start turning RC-servo */
43
#define BLINDS_CMD_STOP     0x04 /* Stop turning RC-servo */
43
#define BLINDS_CMD_STOP     0x04 /* Stop turning RC-servo */
44
#define BLINDS_CMD_RESET    0x05
44
#define BLINDS_CMD_RESET    0x05
45
#define BLINDS_CMD_STATUS   0x06
45
#define BLINDS_CMD_STATUS   0x06
46
 
46
 
47
#define BLINDS_TURN_STOP    0x00
47
#define BLINDS_TURN_STOP    0x00
48
#define BLINDS_TURN_LEFT    0x01
48
#define BLINDS_TURN_LEFT    0x01
49
#define BLINDS_TURN_RIGHT   0x02
49
#define BLINDS_TURN_RIGHT   0x02
50
 
50
 
51
#define STEPS_PER_TURN_PERIOD 10 /* number of steps for each adjustment */
51
#define STEPS_PER_TURN_PERIOD 10 /* number of steps for each adjustment */
52
#define TURN_PERIOD         100 /* milliseconds */
52
#define TURN_PERIOD         100 /* milliseconds */
53
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
53
#define STATUS_SEND_PERIOD  10000 /* milliseconds */
54
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
54
#define FAILSAFE_SEND_PERIOD    10000 /* milliseconds */
55
#define BOUNCE_TIME         10 /* milliseconds */
55
#define BOUNCE_TIME         10 /* milliseconds */
56
#define BUTTON_ID           0x1202
56
#define BUTTON_ID           0x1202
57
#define BUTTON1             1
57
#define BUTTON1             1
58
#define BUTTON2             2
58
#define BUTTON2             2
59
 
59
 
60
/*-------------------------------------------------------------------------
60
/*-------------------------------------------------------------------------
61
 * Global variables
61
 * Global variables
62
 * -----------------------------------------------------------------------*/
62
 * -----------------------------------------------------------------------*/
63
#if TWO_BUTTON_MODE
63
#if TWO_BUTTON_MODE
64
Can_Message_t txMsg_Button;
64
Can_Message_t txMsg_Button;
65
#endif
65
#endif
66
 
66
 
67
/*----------------------------------------------------------------------------
67
/*----------------------------------------------------------------------------
68
 * Functions
68
 * Functions
69
 * -------------------------------------------------------------------------*/
69
 * -------------------------------------------------------------------------*/
70
void blindsFailsafe();
70
void blindsFailsafe();
71
 
71
 
72
/*----------------------------------------------------------------------------
72
/*----------------------------------------------------------------------------
73
 * Interrupt routines
73
 * Interrupt routines
74
 * -------------------------------------------------------------------------*/
74
 * -------------------------------------------------------------------------*/
75
#if TWO_BUTTON_MODE
75
#if TWO_BUTTON_MODE
76
ISR( PCINT2_vect )
76
ISR( PCINT2_vect )
77
{
77
{
78
    /*
78
    /*
79
     * Auxiliary button pressed and released
79
     * Auxiliary button pressed and released
80
     * Check time between press and release to eliminate bounces
80
     * Check time between press and release to eliminate bounces
81
     */
81
     */
82
    static uint32_t buttonTime[2];
82
    static uint32_t buttonTime[2];
83
 
83
 
84
    txMsg_Button.RemoteFlag = 0;
84
    txMsg_Button.RemoteFlag = 0;
85
    txMsg_Button.ExtendedFlag = 1;
85
    txMsg_Button.ExtendedFlag = 1;
86
 
86
 
87
    if( (PIND & (1<<PD6)) == 0){
87
    if( (PIND & (1<<PD6)) == 0){
88
        /* Button pressed */
88
        /* Button pressed */
89
        buttonTime[0] = Timebase_CurrentTime();
89
        buttonTime[0] = Timebase_CurrentTime();
90
#if DEBUG
90
#if DEBUG
91
        printf("Button 1 pressed\n");
91
        printf("Button 1 pressed\n");
92
#endif
92
#endif
93
    }else if( (PIND & (1<<PD6)) == 1){
93
    }else if( (PIND & (1<<PD6)) == 1){
94
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
94
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
95
            /* No bounce, send message */
95
            /* No bounce, send message */
96
            txMsg_Button.Id = BUTTON_ID;
96
            txMsg_Button.Id = BUTTON_ID;
97
            txMsg_Button.DataLength = 1;
97
            txMsg_Button.DataLength = 1;
98
            txMsg_Button.Data.bytes[0] = BUTTON1;
98
            txMsg_Button.Data.bytes[0] = BUTTON1;
99
#if DEBUG
99
#if DEBUG
100
            printf("Button 1 pressed: message sent\n");
100
            printf("Button 1 pressed: message sent\n");
101
#endif
101
#endif
102
            return;
102
            return;
103
        }else{
103
        }else{
104
            /* Just bounces, ignore it */
104
            /* Just bounces, ignore it */
105
#if DEBUG
105
#if DEBUG
106
            printf("Button 1 just bounced\n");
106
            printf("Button 1 just bounced\n");
107
#endif
107
#endif
108
            return;
108
            return;
109
        }
109
        }
110
    }
110
    }
111
    if( (PIND & (1<<PD7)) == 0){
111
    if( (PIND & (1<<PD7)) == 0){
112
        /* Button pressed */
112
        /* Button pressed */
113
        buttonTime[1] = Timebase_CurrentTime();
113
        buttonTime[1] = Timebase_CurrentTime();
114
#if DEBUG
114
#if DEBUG
115
        printf("Button 2 pressed\n");
115
        printf("Button 2 pressed\n");
116
#endif
116
#endif
117
    }else if( (PIND & (1<<PD7)) == 1){
117
    }else if( (PIND & (1<<PD7)) == 1){
118
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
118
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
119
            /* No bounce, send message */
119
            /* No bounce, send message */
120
            txMsg_Button.Id = BUTTON_ID;
120
            txMsg_Button.Id = BUTTON_ID;
121
            txMsg_Button.DataLength = 1;
121
            txMsg_Button.DataLength = 1;
122
            txMsg_Button.Data.bytes[0] = BUTTON2;
122
            txMsg_Button.Data.bytes[0] = BUTTON2;
123
#if DEBUG
123
#if DEBUG
124
            printf("Button 2 pressed: message sent\n");
124
            printf("Button 2 pressed: message sent\n");
125
#endif
125
#endif
126
            return;
126
            return;
127
        }else{
127
        }else{
128
            /* Just bounces, ignore it */
128
            /* Just bounces, ignore it */
129
#if DEBUG
129
#if DEBUG
130
            printf("Button 2 just bounced\n");
130
            printf("Button 2 just bounced\n");
131
#endif
131
#endif
132
            return;
132
            return;
133
        }
133
        }
134
    }
134
    }
135
}
135
}
136
#endif
136
#endif
137
 
137
 
138
/*-----------------------------------------------------------------------------
138
/*-----------------------------------------------------------------------------
139
 * Main Program
139
 * Main Program
140
 *---------------------------------------------------------------------------*/
140
 *---------------------------------------------------------------------------*/
141
int main(void) {
141
int main(void) {
142
 
142
 
143
    uint8_t blindsStatus, /* Position (-128 to 127) */
143
    uint8_t blindsStatus, /* Position (-128 to 127) */
144
            turnDirection = BLINDS_TURN_STOP; /* Specifies direction to turn or stopped */
144
            turnDirection = BLINDS_TURN_STOP; /* Specifies direction to turn or stopped */
145
    uint32_t boardTemperature = 0;
145
    uint32_t boardTemperature = 0;
146
    uint32_t timeStamp = 0, timeStampTurn = 0;
146
    uint32_t timeStamp = 0, timeStampTurn = 0;
147
 
147
 
148
    adcTemperatureInit();
148
    adcTemperatureInit();
149
    Timebase_Init();
149
    Timebase_Init();
150
    rcServoInit();
150
    rcServoInit();
151
#if DEBUG
151
#if DEBUG
152
    Serial_Init();
152
    Serial_Init();
153
#endif
153
#endif
154
 
154
 
155
#if TWO_BUTTON_MODE
155
#if TWO_BUTTON_MODE
156
    /*
156
    /*
157
     * Initialize buttons
157
     * Initialize buttons
158
     * It is possible to use ie. sensors instead
158
     * It is possible to use ie. sensors instead
159
     * but then change this
159
     * but then change this
160
     */
160
     */
161
    /* Set as input and enable pull-up */
161
    /* Set as input and enable pull-up */
162
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
162
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
163
    PORTD |= (1<<PD6)|(1<<PD7);
163
    PORTD |= (1<<PD6)|(1<<PD7);
164
 
164
 
165
    /* Enable IO-pin interrupt */
165
    /* Enable IO-pin interrupt */
166
    PCICR |= (1<<PCIE1);
166
    PCICR |= (1<<PCIE1);
167
    /* Unmask PD6 and PD7 */
167
    /* Unmask PD6 and PD7 */
168
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
168
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
169
#endif
169
#endif
170
    sei();
170
    sei();
171
#if DEBUG
171
#if DEBUG
172
    printf("\n------------------------------------------------------------\n");
172
    printf("\n------------------------------------------------------------\n");
173
    printf(  "   CAN: Blinds\n");
173
    printf(  "   CAN: Blinds\n");
174
    printf(  "------------------------------------------------------------\n");
174
    printf(  "------------------------------------------------------------\n");
175
 
175
 
176
    printf("CanInit...");
176
    printf("CanInit...");
177
    if (Can_Init() != CAN_OK) {
177
    if (Can_Init() != CAN_OK) {
178
        printf("FAILED!\n");
178
        printf("FAILED!\n");
179
    }else{
179
    }else{
180
        printf("OK!\n");
180
        printf("OK!\n");
181
    }
181
    }
182
#else
182
#else
183
    Can_Init();
183
    Can_Init();
184
#endif
184
#endif
185
 
185
 
186
    Can_Message_t txMsg;
186
    Can_Message_t txMsg;
187
    Can_Message_t rxMsg;
187
    Can_Message_t rxMsg;
188
    txMsg.Id = BLINDS_CMD_SEND;
188
    txMsg.Id = BLINDS_CMD_SEND;
189
    txMsg.RemoteFlag = 0;
189
    txMsg.RemoteFlag = 0;
190
    txMsg.ExtendedFlag = 1;
190
    txMsg.ExtendedFlag = 1;
191
    txMsg.DataLength = 3;
191
    txMsg.DataLength = 3;
192
 
192
 
193
    /* main loop */
193
    /* main loop */
194
    while (1) {
194
    while (1) {
195
        /* service the CAN routines */
195
        /* service the CAN routines */
196
        Can_Service();
196
        Can_Service();
197
 
197
 
198
        /* check if any messages have been received */
198
        /* check if any messages have been received */
199
        while (Can_Receive(&rxMsg) == CAN_OK) {
199
        while (Can_Receive(&rxMsg) == CAN_OK) {
200
            /* This node that control a servo is adressed */
200
            /* This node that control a servo is adressed */
201
            if( rxMsg.Id == BLINDS_CMD_GET ){
201
            if( rxMsg.Id == BLINDS_CMD_GET ){
202
 
202
 
203
                if( rxMsg.Data.bytes[0] == BLINDS_CMD_ABS ){
203
                if( rxMsg.Data.bytes[0] == BLINDS_CMD_ABS ){
204
                    /* Set absolute position to servo */
204
                    /* Set absolute position to servo */
205
                    setPosition( rxMsg.Data.bytes[1] );
205
                    setPosition( rxMsg.Data.bytes[1] );
206
 
206
 
207
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_REL){
207
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_REL){
208
                    /* Set relative position to servo */
208
                    /* Set relative position to servo */
209
                    alterPosition( rxMsg.Data.bytes[1] );
209
                    alterPosition( rxMsg.Data.bytes[1] );
210
 
210
 
211
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_START ){
211
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_START ){
212
                    /* Start turning the servo */
212
                    /* Start turning the servo */
213
                    turnDirection = rxMsg.Data.bytes[1];
213
                    turnDirection = rxMsg.Data.bytes[1];
214
 
214
 
215
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STOP ){
215
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STOP ){
216
                    /* Stop turning */
216
                    /* Stop turning */
217
                    turnDirection = BLINDS_TURN_STOP;
217
                    turnDirection = BLINDS_TURN_STOP;
218
 
218
 
219
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){
219
                }else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){
220
                    /* Send blinds status to CAN */
220
                    /* Send blinds status to CAN */
221
                    boardTemperature = getTC1047temperature();
221
                    boardTemperature = getTC1047temperature();
222
 
222
 
223
                    if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
223
                    if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
224
                        blindsFailsafe();
224
                        blindsFailsafe();
225
                    }else{
225
                    }else{
226
                        txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
226
                        txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
227
                        txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
227
                        txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
228
                        txMsg.Data.bytes[2] = getPosition();
228
                        txMsg.Data.bytes[2] = getPosition();
229
 
229
 
230
                        Can_Send( &txMsg );
230
                        Can_Send( &txMsg );
231
                    }
231
                    }
232
                }
232
                }
233
            }
233
            }
234
        }
234
        }
235
 
235
 
236
        if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
236
        if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
237
            timeStamp = Timebase_CurrentTime();
237
            timeStamp = Timebase_CurrentTime();
238
            /* Send blinds status to CAN */
238
            /* Send blinds status to CAN */
239
 
239
 
240
            boardTemperature = getTC1047temperature();
240
            boardTemperature = getTC1047temperature();
241
 
241
 
242
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
242
            if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
243
                blindsFailsafe();
243
                blindsFailsafe();
244
            }else{
244
            }else{
245
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
245
                txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
246
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
246
                txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
247
                txMsg.Data.bytes[2] = getPosition();
247
                txMsg.Data.bytes[2] = getPosition();
248
 
248
 
249
                Can_Send( &txMsg );
249
                Can_Send( &txMsg );
250
#if DEBUG
250
#if DEBUG
251
                printf("Periodic message sent...\n");
251
                printf("Periodic message sent...\n");
252
                printf("Temperature: %d\nBlinds status: %u\n", boardTemperature, getPosition());
252
                printf("Temperature: %d\nBlinds status: %u\n", boardTemperature, getPosition());
253
#endif
253
#endif
254
            }
254
            }
255
        }
255
        }
256
        /* If start turning servo */
256
        /* If start turning servo */
257
        if( turnDirection ){
257
        if( turnDirection ){
258
            if( Timebase_PassedTimeMillis( timeStampTurn ) >= TURN_PERIOD ){
258
            if( Timebase_PassedTimeMillis( timeStampTurn ) >= TURN_PERIOD ){
259
                timeStampTurn = Timebase_CurrentTime();
259
                timeStampTurn = Timebase_CurrentTime();
260
                /* Clockwise or counterclockwise? */
260
                /* Clockwise or counterclockwise? */
261
                if( turnDirection == BLINDS_TURN_LEFT ){
261
                if( turnDirection == BLINDS_TURN_LEFT ){
262
                    alterPosition( -STEPS_PER_TURN_PERIOD );
262
                    alterPosition( -STEPS_PER_TURN_PERIOD );
263
                }else if( turnDirection == BLINDS_TURN_RIGHT ){
263
                }else if( turnDirection == BLINDS_TURN_RIGHT ){
264
                    alterPosition( STEPS_PER_TURN_PERIOD );
264
                    alterPosition( STEPS_PER_TURN_PERIOD );
265
                }
265
                }
266
            }
266
            }
267
        }
267
        }
268
    }
268
    }
269
    return 0;
269
    return 0;
270
}
270
}
271
 
271
 
272
void blindsFailsafe() // TODO fixa failsafe, vad ska hända med PWM?
272
void blindsFailsafe() // TODO fixa failsafe, vad ska hända med PWM?
273
{
273
{
274
    uint8_t relayStatus;
274
    uint8_t relayStatus;
275
    uint32_t boardTemperature = 0, timeStamp = 0;
275
    uint32_t boardTemperature = 0, timeStamp = 0;
276
 
276
 
277
    Can_Message_t txMsg;
277
    Can_Message_t txMsg;
278
    Can_Message_t rxMsg;
278
    Can_Message_t rxMsg;
279
    txMsg.Id = BLINDS_CMD_SEND;
279
    txMsg.Id = BLINDS_CMD_SEND;
280
    txMsg.RemoteFlag = 0;
280
    txMsg.RemoteFlag = 0;
281
    txMsg.ExtendedFlag = 1;
281
    txMsg.ExtendedFlag = 1;
282
    txMsg.DataLength = 4;
282
    txMsg.DataLength = 4;
283
 
283
 
284
    while(1){
284
    while(1){
285
        /* service the CAN routines */
285
        /* service the CAN routines */
286
        Can_Service();
286
        Can_Service();
287
 
287
 
288
        /* check if any messages have been received */
288
        /* check if any messages have been received */
289
        while (Can_Receive(&rxMsg) == CAN_OK) {
289
        while (Can_Receive(&rxMsg) == CAN_OK) {
290
            /* This relay is adressed*/
290
            /* This relay is adressed*/
291
            if( rxMsg.Id == BLINDS_CMD_GET ){
291
            if( rxMsg.Id == BLINDS_CMD_GET ){
292
                if( rxMsg.Data.bytes[0] == BLINDS_CMD_RESET ){
292
                if( rxMsg.Data.bytes[0] == BLINDS_CMD_RESET ){
293
                    /* Return from failsafe mode */
293
                    /* Return from failsafe mode */
294
                    return;
294
                    return;
295
                }
295
                }
296
            }
296
            }
297
        }
297
        }
298
 
298
 
299
        if( Timebase_PassedTimeMillis(timeStamp) >= FAILSAFE_SEND_PERIOD ){
299
        if( Timebase_PassedTimeMillis(timeStamp) >= FAILSAFE_SEND_PERIOD ){
300
            timeStamp = Timebase_CurrentTime();
300
            timeStamp = Timebase_CurrentTime();
301
            /* Send relay status to CAN */
301
            /* Send relay status to CAN */
302
#if DEBUG
302
#if DEBUG
303
            printf("Failsafe mode!\n");
303
            printf("Failsafe mode!\n");
304
#endif
304
#endif
305
            boardTemperature = getTC1047temperature();
305
            boardTemperature = getTC1047temperature();
306
 
306
 
307
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
307
            txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
308
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
308
            txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
309
            txMsg.Data.bytes[2] = getPosition();
309
            txMsg.Data.bytes[2] = getPosition();
310
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
310
            txMsg.Data.bytes[3] = FAILSAFE_MODE;
311
 
311
 
312
            Can_Send( &txMsg );
312
            Can_Send( &txMsg );
313
        }
313
        }
314
    }
314
    }
315
}
315
}
316
 
316
 
317
 
317