3047 |
miho |
1 |
// ------------------------------------------------------------------ |
|
|
2 |
// |
|
|
3 |
// TRAIN TIMER |
|
|
4 |
// ----------- |
|
|
5 |
// |
|
|
6 |
// Firmware for TRAIN02A board. It changes state of relay outputs |
|
|
7 |
// as defined in configuration. Default configuration is in .h file |
|
|
8 |
// and definitions may be changed online via USB port and if needed |
|
|
9 |
// stored into EEPROM. |
|
|
10 |
// |
|
|
11 |
// Uses ATmega8 at 8MHz (internal RC or external XTAL) |
|
|
12 |
// |
|
|
13 |
// (c) miho WWW.MLAB.CZ/PermaLink/TRAIN |
|
|
14 |
// |
|
|
15 |
// ------------------------------------------------------------------ |
|
|
16 |
// |
|
|
17 |
// History |
|
|
18 |
// |
|
|
19 |
// 1.00 First version |
|
|
20 |
|
|
|
21 |
|
|
|
22 |
// Standard header files |
|
|
23 |
#include <avr/io.h> // Device Specific Defines |
|
|
24 |
#include <avr/interrupt.h> // For Timer and USART Interrupt |
|
|
25 |
#include <stdlib.h> // For rand() |
|
|
26 |
#include <avr/eeprom.h> // For EEPROM access (for configuration) |
|
|
27 |
#include <stdio.h> // For printf() etc |
|
|
28 |
#include <string.h> // For strcmp() etc |
|
|
29 |
#include <avr/pgmspace.h> // Data in Program Memory (strings) |
|
|
30 |
|
|
|
31 |
#include "TRAIN.h" // Hardware Definitions |
|
|
32 |
#include "TRAIN_TIMER.h" // Project Definitions - default configuration is here |
|
|
33 |
|
|
|
34 |
|
|
|
35 |
// Set Relay Outputs |
|
|
36 |
void SetOutput(const unsigned char Number, const unsigned char State) |
|
|
37 |
{ |
|
|
38 |
// Check |
|
|
39 |
if(Number>7) |
|
|
40 |
return; |
|
|
41 |
|
|
|
42 |
// Set DDR (for output) |
|
|
43 |
(*RE_DDR_Table[Number]) |= RE_BIT_MASK[Number]; |
|
|
44 |
|
|
|
45 |
// Set/Clear data |
|
|
46 |
if(State) |
|
|
47 |
(*RE_PORT_Table[Number]) |= RE_BIT_MASK[Number]; |
|
|
48 |
else |
|
|
49 |
(*RE_PORT_Table[Number]) &= ~RE_BIT_MASK[Number]; |
|
|
50 |
} |
|
|
51 |
|
|
|
52 |
|
|
|
53 |
// Get Switch Input State |
|
|
54 |
unsigned char GetInput(const unsigned char Number) |
|
|
55 |
{ |
|
|
56 |
// Check |
|
|
57 |
if(Number>7) |
|
|
58 |
return 0; |
|
|
59 |
// PullUp |
|
|
60 |
(*SW_PORT_Table[Number]) |= SW_BIT_MASK[Number]; |
|
|
61 |
// Get Value |
|
|
62 |
return ((*SW_PIN_Table[Number]) & SW_BIT_MASK[Number]) == 0 ? 1 : 0; |
|
|
63 |
} |
|
|
64 |
|
|
|
65 |
|
|
|
66 |
// EEPROM Data |
|
|
67 |
unsigned int EEMEM EE_TimesOn[8] = DEFAULT_TIMES_ON ; |
|
|
68 |
unsigned int EEMEM EE_TimesOff[8] = DEFAULT_TIMES_OFF ; |
|
|
69 |
unsigned int EEMEM EE_TimesOnRnd[8] = DEFAULT_TIMES_ON_RND ; |
|
|
70 |
unsigned int EEMEM EE_TimesOffRnd[8] = DEFAULT_TIMES_OFF_RND ; |
|
|
71 |
|
|
|
72 |
|
|
|
73 |
// Runtime configuration |
|
|
74 |
static volatile unsigned int TimesOn[8]; |
|
|
75 |
static volatile unsigned int TimesOff[8]; |
|
|
76 |
static volatile unsigned int TimesOnRnd[8]; |
|
|
77 |
static volatile unsigned int TimesOffRnd[8]; |
|
|
78 |
|
|
|
79 |
|
|
|
80 |
// Load configuration from EEPROM to RAM |
|
|
81 |
void EE_Load() |
|
|
82 |
{ |
|
|
83 |
// Copy data from EEPROM to RAM |
|
|
84 |
eeprom_read_block(&TimesOn, &EE_TimesOn, sizeof(TimesOn) ); |
|
|
85 |
eeprom_read_block(&TimesOff, &EE_TimesOff, sizeof(TimesOff) ); |
|
|
86 |
eeprom_read_block(&TimesOnRnd, &EE_TimesOnRnd, sizeof(TimesOnRnd) ); |
|
|
87 |
eeprom_read_block(&TimesOffRnd, &EE_TimesOffRnd, sizeof(TimesOffRnd) ); |
|
|
88 |
} |
|
|
89 |
|
|
|
90 |
|
|
|
91 |
// Store configuration to EEPROM from RAM |
|
|
92 |
void EE_Store() |
|
|
93 |
{ |
|
|
94 |
// Copy data from RAM to EEPROM |
|
|
95 |
eeprom_write_block(&TimesOn, &EE_TimesOn, sizeof(TimesOn) ); |
|
|
96 |
eeprom_write_block(&TimesOff, &EE_TimesOff, sizeof(TimesOff) ); |
|
|
97 |
eeprom_write_block(&TimesOnRnd, &EE_TimesOnRnd, sizeof(TimesOnRnd) ); |
|
|
98 |
eeprom_write_block(&TimesOffRnd, &EE_TimesOffRnd, sizeof(TimesOffRnd) ); |
|
|
99 |
} |
|
|
100 |
|
|
|
101 |
|
|
|
102 |
// Init Timer 1 |
|
|
103 |
void TimerInit() |
|
|
104 |
{ |
|
|
105 |
TCCR1B |= (1<<WGM12); // Configure timer 1 for CTC mode |
|
|
106 |
TIMSK |= (1<<OCIE1A); // Enable CTC interrupt (Output Compare) |
|
|
107 |
OCR1A = F_CPU/F_TIME_GRAIN/8; // Peridic interrupt |
|
|
108 |
TCCR1B |= (1 << CS11); // Start timer at Fcpu/8 |
|
|
109 |
} |
|
|
110 |
|
|
|
111 |
|
|
|
112 |
// Global State of Realays |
|
|
113 |
static volatile unsigned char RelayState[8]; |
|
|
114 |
static volatile unsigned int Timers[8]; |
|
|
115 |
|
|
|
116 |
|
|
|
117 |
// ISR - TIMER - 10ms |
|
|
118 |
ISR(TIMER1_COMPA_vect) |
|
|
119 |
{ |
|
|
120 |
// Time granularity to 1s counter |
|
|
121 |
static volatile unsigned int Timer; |
|
|
122 |
|
|
|
123 |
Timer++; |
|
|
124 |
if(Timer==F_TIME_GRAIN) |
|
|
125 |
{ |
|
|
126 |
// 1s |
|
|
127 |
for(unsigned char i=0; i<8; i++) |
|
|
128 |
{ |
|
|
129 |
// Decrement all timers |
|
|
130 |
if(Timers[i]) |
|
|
131 |
{ |
|
|
132 |
Timers[i]--; |
|
|
133 |
} |
|
|
134 |
else |
|
|
135 |
{ |
|
|
136 |
// Switch state |
|
|
137 |
if(RelayState[i]) |
|
|
138 |
{ |
|
|
139 |
Timers[i] = TimesOff[i]-1 + (rand()%(TimesOffRnd[i]+1)); |
|
|
140 |
RelayState[i] = 0; |
|
|
141 |
} |
|
|
142 |
else |
|
|
143 |
{ |
|
|
144 |
Timers[i] = TimesOn[i]-1 + (rand()%(TimesOnRnd[i]+1)); |
|
|
145 |
RelayState[i] = 1; |
|
|
146 |
} |
|
|
147 |
// Send new state to realy output |
|
|
148 |
SetOutput(i, RelayState[i]); |
|
|
149 |
} |
|
|
150 |
} |
|
|
151 |
// Restart granularity counter |
|
|
152 |
Timer=0; |
|
|
153 |
} |
|
|
154 |
|
|
|
155 |
// Inputs state |
|
|
156 |
static volatile unsigned char ButtonState[8]; |
|
|
157 |
|
|
|
158 |
// Read all inputs |
|
|
159 |
for(unsigned char i=0; i<8; i++) |
|
|
160 |
{ |
|
|
161 |
// Read buttons to shift register (each button has its own) |
|
|
162 |
ButtonState[i] = (ButtonState[i] << 1) + GetInput(i); |
|
|
163 |
if(ButtonState[i]==1) |
|
|
164 |
{ |
|
|
165 |
// Just activated - direct action! |
|
|
166 |
/* |
|
|
167 |
RelayState[i] = !RelayState[i]; |
|
|
168 |
SetOutput(i, RelayState[i]); |
|
|
169 |
*/ |
|
|
170 |
// Just activated - change relay and exspire timer |
|
|
171 |
SetOutput(i, !RelayState[i]); |
|
|
172 |
Timers[i] = 0; |
|
|
173 |
} |
|
|
174 |
} |
|
|
175 |
} |
|
|
176 |
|
|
|
177 |
|
|
|
178 |
// USART TX buffer |
|
|
179 |
static volatile uint8_t UART_TxBuf[UART_TX0_BUFFER_SIZE]; |
|
|
180 |
|
|
|
181 |
#if UART_TX0_BUFFER_SIZE > 256 |
|
|
182 |
static volatile uint16_t UART_TxHead; |
|
|
183 |
static volatile uint16_t UART_TxTail; |
|
|
184 |
#else |
|
|
185 |
static volatile uint8_t UART_TxHead; |
|
|
186 |
static volatile uint8_t UART_TxTail; |
|
|
187 |
#endif |
|
|
188 |
|
|
|
189 |
// USART RX buffer |
|
|
190 |
static volatile uint8_t UART_RxBuf[UART_RX0_BUFFER_SIZE]; |
|
|
191 |
|
|
|
192 |
#if UART_RX0_BUFFER_SIZE > 256 |
|
|
193 |
static volatile uint16_t UART_RxHead; |
|
|
194 |
static volatile uint16_t UART_RxTail; |
|
|
195 |
#else |
|
|
196 |
static volatile uint8_t UART_RxHead; |
|
|
197 |
static volatile uint8_t UART_RxTail; |
|
|
198 |
#endif |
|
|
199 |
|
|
|
200 |
|
|
|
201 |
// USART Init |
|
|
202 |
void USART_Init() |
|
|
203 |
{ |
|
|
204 |
// Init RX and TX FIFO |
|
|
205 |
UART_TxHead = 0; |
|
|
206 |
UART_TxTail = 0; |
|
|
207 |
UART_RxHead = 0; |
|
|
208 |
UART_RxTail = 0; |
|
|
209 |
|
|
|
210 |
// Set baud rate |
|
|
211 |
#define MYUBRR (F_CPU/16/BAUD-1) |
|
|
212 |
UBRRH = (unsigned char)(MYUBRR>>8); |
|
|
213 |
UBRRL = (unsigned char)MYUBRR; |
|
|
214 |
#undef MYUBRR |
|
|
215 |
// Enable RX, TX and Receive Interrupt |
|
|
216 |
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); |
|
|
217 |
// Set frame format: 8data, 1stop bit |
|
|
218 |
UCSRC = (1<<URSEL)|(3<<UCSZ0); |
|
|
219 |
// Enable Interrupt |
|
|
220 |
// sei(); // not here (in main) |
|
|
221 |
} |
|
|
222 |
|
|
|
223 |
|
|
|
224 |
// ISR - USART - Receive Interrupt |
|
|
225 |
ISR(USART_RXC_vect) |
|
|
226 |
{ |
|
|
227 |
uint16_t tmphead; |
|
|
228 |
|
|
|
229 |
// Circular Buffer Index |
|
|
230 |
tmphead = ( UART_RxHead + 1) & UART_RX0_BUFFER_MASK; |
|
|
231 |
|
|
|
232 |
if ( tmphead != UART_RxTail ) { |
|
|
233 |
// Increment head pointer |
|
|
234 |
UART_RxHead = tmphead; |
|
|
235 |
// Store received data |
|
|
236 |
UART_RxBuf[tmphead] = UDR; |
|
|
237 |
} |
|
|
238 |
} |
|
|
239 |
|
|
|
240 |
|
|
|
241 |
// USRAT get char (receive form FIFO) |
|
|
242 |
// If no char available wait |
|
|
243 |
uint8_t USART_getc(void) |
|
|
244 |
{ |
|
|
245 |
uint16_t tmptail; |
|
|
246 |
|
|
|
247 |
// wait for data |
|
|
248 |
while(UART_RxHead==UART_RxTail) |
|
|
249 |
;//wait |
|
|
250 |
/* |
|
|
251 |
if ( UART_RxHead==UART_RxTail ) |
|
|
252 |
{ |
|
|
253 |
return 0; // no data |
|
|
254 |
} |
|
|
255 |
*/ |
|
|
256 |
|
|
|
257 |
// Increment Pointer |
|
|
258 |
tmptail = (UART_RxTail + 1) & UART_RX0_BUFFER_MASK; |
|
|
259 |
UART_RxTail = tmptail; |
|
|
260 |
|
|
|
261 |
// Get data from buffer |
|
|
262 |
return UART_RxBuf[tmptail]; |
|
|
263 |
} |
|
|
264 |
|
|
|
265 |
|
|
|
266 |
// ISR - UART - Transmit Interrupt (on empty) |
|
|
267 |
ISR(USART_UDRE_vect) |
|
|
268 |
{ |
|
|
269 |
uint16_t tmptail; |
|
|
270 |
|
|
|
271 |
if(UART_TxHead != UART_TxTail) |
|
|
272 |
{ |
|
|
273 |
// Increment Tail Pointer |
|
|
274 |
tmptail = (UART_TxTail + 1) & UART_TX0_BUFFER_MASK; |
|
|
275 |
UART_TxTail = tmptail; |
|
|
276 |
// Send Byte |
|
|
277 |
UDR = UART_TxBuf[tmptail]; |
|
|
278 |
} else |
|
|
279 |
{ |
|
|
280 |
// TX FIFO empty, disable UDRE interrupt |
|
|
281 |
UCSRB &= ~(1<<UDRIE); |
|
|
282 |
} |
|
|
283 |
} |
|
|
284 |
|
|
|
285 |
|
|
|
286 |
// USART put char (send to FIFO) |
|
|
287 |
// If no free room in buffer wait |
|
|
288 |
void USART_putc(char data) |
|
|
289 |
{ |
|
|
290 |
uint16_t tmphead; |
|
|
291 |
|
|
|
292 |
// Increment FIFO pointer |
|
|
293 |
tmphead = (UART_TxHead + 1) & UART_TX0_BUFFER_MASK; |
|
|
294 |
|
|
|
295 |
while (tmphead == UART_TxTail) |
|
|
296 |
{ |
|
|
297 |
;// wait for free space in buffer |
|
|
298 |
} |
|
|
299 |
|
|
|
300 |
// Put data to FIFO |
|
|
301 |
UART_TxBuf[tmphead] = data; |
|
|
302 |
UART_TxHead = tmphead; |
|
|
303 |
|
|
|
304 |
// Enable UDRE interrupt |
|
|
305 |
UCSRB |= (1<<UDRIE); |
|
|
306 |
} |
|
|
307 |
|
|
|
308 |
|
|
|
309 |
// Send string from Program Memory |
|
|
310 |
void USART_TxString_P(const char * data) |
|
|
311 |
{ |
|
|
312 |
while(pgm_read_byte(data)!=0 ) |
|
|
313 |
USART_putc(pgm_read_byte(data++)); |
|
|
314 |
} |
|
|
315 |
|
|
|
316 |
|
|
|
317 |
// Print current config from RAM |
|
|
318 |
void PrintConfig() |
|
|
319 |
{ |
|
|
320 |
USART_TxString_P(PSTR( |
|
|
321 |
"COMMAND CHANNEL TIME_ON TIME_OFF RND_ON RND_OFF\n\r" |
|
|
322 |
"-----------------------------------------------------------\n\r" |
|
|
323 |
)); |
|
|
324 |
for(unsigned char i=0; i<8; i++) |
|
|
325 |
{ |
|
|
326 |
printf("CONFIG %u %5u %5u %5u %5u\n\r", |
|
|
327 |
i, TimesOn[i], TimesOff[i], TimesOnRnd[i], TimesOffRnd[i]); |
|
|
328 |
} |
|
|
329 |
} |
|
|
330 |
|
|
|
331 |
|
|
|
332 |
// Print Error |
|
|
333 |
void PrintError() |
|
|
334 |
{ |
|
|
335 |
printf("\n\r??"); |
|
|
336 |
} |
|
|
337 |
|
|
|
338 |
|
|
|
339 |
// USART RX/TX stream |
|
|
340 |
static FILE uart_io = FDEV_SETUP_STREAM(USART_putc, USART_getc, _FDEV_SETUP_RW); |
|
|
341 |
|
|
|
342 |
|
|
|
343 |
// Program modes |
|
|
344 |
#define MODE_MANUAL 1 |
|
|
345 |
#define MODE_COMMAND 0 |
|
|
346 |
|
|
|
347 |
char Mode = MODE_COMMAND; |
|
|
348 |
|
|
|
349 |
|
|
|
350 |
// Main Program |
|
|
351 |
int main () |
|
|
352 |
{ |
|
|
353 |
// Load Config from EEPROM |
|
|
354 |
EE_Load(); |
|
|
355 |
|
|
|
356 |
// Timer Init |
|
|
357 |
TimerInit(); |
|
|
358 |
|
|
|
359 |
// USART Init |
|
|
360 |
USART_Init(); |
|
|
361 |
stdout = &uart_io; |
|
|
362 |
stdin = &uart_io; |
|
|
363 |
|
|
|
364 |
// Enable Interrupt (timer and USART) |
|
|
365 |
sei(); |
|
|
366 |
|
|
|
367 |
// Print Info |
|
|
368 |
USART_TxString_P(PSTR( |
|
|
369 |
"\n\r\n\rTrain Timer\n\r----------------\n\r(c) miho "YEAR" WWW.MLAB.CZ\n\r"VERSION"\n\r\n\r" |
|
|
370 |
)); |
|
|
371 |
PrintConfig(); |
|
|
372 |
|
|
|
373 |
// Main Loop (deals with user via serial console) |
|
|
374 |
char ReceivedByte; |
|
|
375 |
for(;;) |
|
|
376 |
{ |
|
|
377 |
// MODE COMMAND (wait for line and proces it) |
|
|
378 |
// ---------------------------------------------------- |
|
|
379 |
if(Mode==MODE_COMMAND) |
|
|
380 |
{ |
|
|
381 |
// Line |
|
|
382 |
char Line[LINE_LENGTH]; |
|
|
383 |
unsigned char LinePtr=0; |
|
|
384 |
|
|
|
385 |
// Print help for command mode |
|
|
386 |
USART_TxString_P(PSTR( |
|
|
387 |
"\n\rCommand Mode\n\r\n\r" |
|
|
388 |
" MANUAL -- Start Interactive Mode\n\r" |
|
|
389 |
" CONFIG Channel On Off Random_On Random_Off -- Set Time Config\n\r" |
|
|
390 |
" SAVE -- Save to EEPROM\n\r" |
|
|
391 |
" LIST -- Display Curent Settings\n\r" |
|
|
392 |
)); |
|
|
393 |
|
|
|
394 |
// Get Line |
|
|
395 |
for(;;) |
|
|
396 |
{ |
|
|
397 |
// Prompt |
|
|
398 |
printf("\n\r> "); |
|
|
399 |
LinePtr=0; |
|
|
400 |
for(;;) |
|
|
401 |
{ |
|
|
402 |
// Get Char |
|
|
403 |
ReceivedByte = USART_getc(); |
|
|
404 |
|
|
|
405 |
// CR |
|
|
406 |
if(ReceivedByte==CR) |
|
|
407 |
{ |
|
|
408 |
// Enter |
|
|
409 |
Line[LinePtr]=0; |
|
|
410 |
break; |
|
|
411 |
} |
|
|
412 |
|
|
|
413 |
// BS/DEL |
|
|
414 |
if((ReceivedByte==BS) || (ReceivedByte==DEL)) |
|
|
415 |
{ |
|
|
416 |
// Backspace or delete |
|
|
417 |
if(LinePtr>0) |
|
|
418 |
{ |
|
|
419 |
USART_putc(BS); |
|
|
420 |
USART_putc(' '); |
|
|
421 |
USART_putc(BS); |
|
|
422 |
LinePtr--; |
|
|
423 |
} |
|
|
424 |
continue; |
|
|
425 |
} |
|
|
426 |
|
|
|
427 |
// Not printable ASCII |
|
|
428 |
if((ReceivedByte<' ') || (ReceivedByte>0x7E)) |
|
|
429 |
{ |
|
|
430 |
// Ignore control chars |
|
|
431 |
continue; |
|
|
432 |
} |
|
|
433 |
|
|
|
434 |
// Space at the beginning |
|
|
435 |
if((ReceivedByte==' ') && (LinePtr==0)) |
|
|
436 |
{ |
|
|
437 |
// Ignore space at the beginning |
|
|
438 |
continue; |
|
|
439 |
} |
|
|
440 |
|
|
|
441 |
// Store Char to Line Buffer |
|
|
442 |
if(LinePtr<sizeof(Line)-2) |
|
|
443 |
{ |
|
|
444 |
// UpCase |
|
|
445 |
if(ReceivedByte>='a' && ReceivedByte<='z') |
|
|
446 |
ReceivedByte+='A'-'a'; |
|
|
447 |
// Echo |
|
|
448 |
USART_putc(ReceivedByte); |
|
|
449 |
// Store to Line |
|
|
450 |
Line[LinePtr++] = ReceivedByte; |
|
|
451 |
} |
|
|
452 |
|
|
|
453 |
} |
|
|
454 |
|
|
|
455 |
// Process Line |
|
|
456 |
//printf(" [%s]\n\r", Line); |
|
|
457 |
|
|
|
458 |
char * LineP = Line; |
|
|
459 |
char s[sizeof(Line)]; |
|
|
460 |
|
|
|
461 |
// Get Command (first word) |
|
|
462 |
if(sscanf(LineP, "%s", s)!=1) |
|
|
463 |
continue; |
|
|
464 |
|
|
|
465 |
// Empty line or comment |
|
|
466 |
if((s[0]=='#')||(s[0]==0)) |
|
|
467 |
{ |
|
|
468 |
continue; |
|
|
469 |
} |
|
|
470 |
|
|
|
471 |
// Command MANUAL |
|
|
472 |
if(strcmp(s, "MANUAL")==0) |
|
|
473 |
{ |
|
|
474 |
printf("\n\r"); |
|
|
475 |
Mode=MODE_MANUAL; |
|
|
476 |
break; |
|
|
477 |
} |
|
|
478 |
|
|
|
479 |
// Command LIST |
|
|
480 |
if(strcmp(s, "LIST")==0) |
|
|
481 |
{ |
|
|
482 |
printf("\n\r\n\r"); |
|
|
483 |
PrintConfig(); |
|
|
484 |
continue; |
|
|
485 |
} |
|
|
486 |
|
|
|
487 |
// Command CONFIG |
|
|
488 |
if(strcmp(s, "CONFIG")==0) |
|
|
489 |
{ |
|
|
490 |
char * LineP = Line+sizeof("CONFIG"); |
|
|
491 |
unsigned char ch; |
|
|
492 |
|
|
|
493 |
// Read channel number |
|
|
494 |
if(sscanf(LineP, "%hhu", &ch)!=1) |
|
|
495 |
{ |
|
|
496 |
PrintError(); |
|
|
497 |
continue; |
|
|
498 |
} |
|
|
499 |
|
|
|
500 |
// Test max number of channels |
|
|
501 |
if(ch>8) |
|
|
502 |
{ |
|
|
503 |
PrintError(); |
|
|
504 |
continue; |
|
|
505 |
} |
|
|
506 |
|
|
|
507 |
// Get data from RAM |
|
|
508 |
unsigned int a = TimesOn[ch]; |
|
|
509 |
unsigned int b = TimesOff[ch]; |
|
|
510 |
unsigned int c = TimesOnRnd[ch]; |
|
|
511 |
unsigned int d = TimesOffRnd[ch]; |
|
|
512 |
|
|
|
513 |
// Process input data |
|
|
514 |
if(sscanf(LineP, "%hhu%u%u%u%u", &ch, &a, &b, &c, &d)<2) |
|
|
515 |
{ |
|
|
516 |
PrintError(); |
|
|
517 |
continue; |
|
|
518 |
} |
|
|
519 |
|
|
|
520 |
//printf("New Config %u %u %u %u %u", ch, a,b,c,d); |
|
|
521 |
// Store new data to ram |
|
|
522 |
TimesOn[ch] = a; |
|
|
523 |
TimesOff[ch] = b; |
|
|
524 |
TimesOnRnd[ch] = c; |
|
|
525 |
TimesOffRnd[ch] = d; |
|
|
526 |
|
|
|
527 |
// Clear Timer |
|
|
528 |
Timers[ch] = 0; |
|
|
529 |
continue; |
|
|
530 |
} |
|
|
531 |
|
|
|
532 |
// Command SAVE |
|
|
533 |
if(strcmp(s, "SAVE")==0) |
|
|
534 |
{ |
|
|
535 |
EE_Store(); |
|
|
536 |
continue; |
|
|
537 |
} |
|
|
538 |
|
|
|
539 |
// Unknown Command |
|
|
540 |
PrintError(); |
|
|
541 |
} |
|
|
542 |
} |
|
|
543 |
|
|
|
544 |
// MODE MANUAL (Interactive Mode) |
|
|
545 |
// ---------------------------------------------------- |
|
|
546 |
if(Mode==MODE_MANUAL) |
|
|
547 |
{ |
|
|
548 |
// Print help for command mode |
|
|
549 |
USART_TxString_P(PSTR( |
|
|
550 |
"\n\r" |
|
|
551 |
"Interactive Mode\n\r\n\r" |
|
|
552 |
"0..7 Reverse Channel 0..7 (and reset timer)\n\r" |
|
|
553 |
"A..H Set Channel 0..7 on\n\r" |
|
|
554 |
"a..h Set Channel 0..7 off\n\r" |
|
|
555 |
"ESC Return from Interactive Mode\n\r\n\r> " |
|
|
556 |
)); |
|
|
557 |
|
|
|
558 |
// Interractive loop |
|
|
559 |
for(;;) |
|
|
560 |
{ |
|
|
561 |
// Get CHar |
|
|
562 |
ReceivedByte = USART_getc(); |
|
|
563 |
|
|
|
564 |
// Commands A-H - Switch the relay on |
|
|
565 |
if(ReceivedByte>='A' && ReceivedByte<='H') |
|
|
566 |
{ |
|
|
567 |
RelayState[ReceivedByte-'A'] = 1; |
|
|
568 |
SetOutput(ReceivedByte-'A', 1); |
|
|
569 |
} |
|
|
570 |
|
|
|
571 |
// Commands a-h - Switch the relay off |
|
|
572 |
else if(ReceivedByte>='a' && ReceivedByte<='h') |
|
|
573 |
{ |
|
|
574 |
RelayState[ReceivedByte-'a'] = 0; |
|
|
575 |
SetOutput(ReceivedByte-'a', 0); |
|
|
576 |
} |
|
|
577 |
|
|
|
578 |
// Command 0-7 - Negate realay |
|
|
579 |
else if(ReceivedByte>='0' && ReceivedByte<='7') |
|
|
580 |
{ |
|
|
581 |
// Just activated - set relay and exspire timer |
|
|
582 |
SetOutput(ReceivedByte-'0', !RelayState[ReceivedByte-'0']); |
|
|
583 |
Timers[ReceivedByte-'0'] = 0; |
|
|
584 |
} |
|
|
585 |
|
|
|
586 |
// ESC - return from interractive mode |
|
|
587 |
else if(ReceivedByte==ESC) |
|
|
588 |
{ |
|
|
589 |
printf("\n\r"); |
|
|
590 |
Mode=MODE_COMMAND; |
|
|
591 |
break; |
|
|
592 |
} |
|
|
593 |
|
|
|
594 |
// Unknown Command |
|
|
595 |
else |
|
|
596 |
{ |
|
|
597 |
USART_putc(BS); |
|
|
598 |
USART_putc('?'); |
|
|
599 |
continue; |
|
|
600 |
} |
|
|
601 |
|
|
|
602 |
// Display Char |
|
|
603 |
USART_putc(BS); |
|
|
604 |
USART_putc(ReceivedByte); |
|
|
605 |
} |
|
|
606 |
} |
|
|
607 |
} |
|
|
608 |
|
|
|
609 |
return 0; |
|
|
610 |
} |