Subversion Repositories HomeAutomation

Rev

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

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