Założenia projektu były takie:
- - po włączeniu HID blokujemy możliwość wyłączenia na 15 min - dla dobrego rozgrzania żarnika
- po wyłączeniu trzeba odczekać 5 min by po raz kolejny załączyć
- automatyczne wyłączanie po ok 8 h pracy - jak bym wyszedł i zapomniał wyłączyć oświetlenie
- możliwość awaryjnego włączenia/wyłączenia po naciśnięciu przycisku przez 10 sek.
- sygnalizacja stanu pracy na 1 led - szybkie miganie: aktywne timery (15 lub 5 minut), dłuższe miganie: po upływie czasu blokady zostanie wykonane dodatkowe załączenie/wyłączenie HID.
Schemat układu:
Wzór małej płytki sterownika:
Prosty kod sterujący napisany w C:
Kod: Zaznacz cały
/*
* T13_HID.c
*
* Created on: 31-03-2013
* Autor: fredek
*
* CPU: ATtiny13A
* FUSEBIT: LOW=0x39 HIGH=0xEB
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
// definicje opóźnień
#define WAIT_5M 525 // przerwa ponownego odpalenia hid ~5 min.
#define WAIT_15M 1575 // minimalny czas pracy hid ~15 min.
#define WAIT_KEY 20 // blokada odczytu klawiszy (1 sek)
#define WORK_TIME 50400 // max czas pracy do autowyłączenia ~8 godz.
// definicje podłączenia portów
#define LED_PIN (1<<PB0) // dioda LED (anoda do 5V)
#define KEY1_PIN (1<<PB1) // klawisz 1
#define KEY2_PIN (1<<PB2) // klawisz 2
#define HID1_PIN (1<<PB3) // HID nr 1
#define HID2_PIN (1<<PB4) // HID nr 2
// definicje klawiatury
#define KEY_PIN ( KEY1_PIN | KEY2_PIN )
#define KEY_S1 !( PINB & KEY1_PIN ) // klawisz S1 wcinięty
#define KEY_S2 !( PINB & KEY2_PIN ) // klawisz S2 wcinięty
// definicje dla LED
#define LED_ON PORTB &= ~LED_PIN
#define LED_OFF PORTB |= LED_PIN
#define LED_TOG PORTB ^= LED_PIN
// definicje dla 2-ch relay module
#define HID_PIN ( HID1_PIN | HID2_PIN )
#define HID1_ON PORTB &= ~HID1_PIN
#define HID1_OFF PORTB |= HID1_PIN
#define HID2_ON PORTB &= ~HID2_PIN
#define HID2_OFF PORTB |= HID2_PIN
// definicje typów
typedef uint8_t u08;
typedef uint16_t u16;
typedef uint32_t u32;
// definicje zmiennych
volatile u16 lock1=WAIT_5M; // czas blokady dla HID 1
volatile u16 lock2=WAIT_5M; // czas blokady dla HID 2
volatile u08 cnt1=WAIT_KEY; // blokada odczytu klawisza S1
volatile u08 cnt2=WAIT_KEY; // blokada odczytu klawisza S1
volatile u32 time1, time2; // czas do autowyłączenia
volatile u08 sw1, sw2; // sygnalizacja nacisniecia klawisza
int main(void)
{
DDRB |= LED_PIN | HID_PIN ; // ustawiamy wyjscia
LED_OFF; // wyłączamy LED
HID1_OFF; // wyłączamy HID1
HID2_OFF; // wyłączamy HID2
DDRB &= ~KEY_PIN; // kierunek pinów klawiszy - wejściowy
PORTB |= KEY_PIN; // podciągnięcie pinów klawiszy do VCC
// Ustawienie przerwania watchdog
WDTCR |= (1<<WDTIE); // Watchdog Timer Interrupt Enable
WDTCR |= (1<<WDP2)|(1<<WDP0); // 0.5 s
// Ustawienie Timer0 CTC mode
TCCR0A |= (1<<WGM01); // tryb CTC
TCCR0B |= (1<<CS02)|(1<<CS00); // preskaler = 1024
OCR0A = 234; // ~ 20 Hz dla zegara 4,8 MHz
TIMSK0 |= (1<<OCIE0A); // Timer/Counter0 Output Compare Match
sei(); // włączenie przerwań
// definiujemy stan początkowy hid-ów
u08 hid1=0;
u08 hid2=0;
while (1) // główna pętla
{
// ===== obsługa HID nr 1 =====
if (!lock1) // brak blokady
{
if (sw1) // nacisnieto klawisz
{
if (hid1) // hid włączony
{
HID1_OFF; // wyłączamy
hid1=0;
lock1=WAIT_5M; // blokada 5 min na ostygnięcie
}
else // hid wyłączony
{
HID1_ON; // włączamy
hid1=1;
lock1=WAIT_15M; // blokada 15 min na rozgrzanie
time1=WORK_TIME; // ustawienie czasu autowyłączenia
}
sw1=0; // kasujemy stan klawisza
}
}
// ===== obsługa HID nr 2 =====
if (!lock2) // brak blokady
{
if (sw2) // nacisnieto klawisz
{
if (hid2) // hid włączony
{
HID2_OFF; // wyłączamy
hid2=0;
lock2=WAIT_5M; // blokada 5 min na ostygnięcie
}
else // hid wyłączony
{
HID2_ON; // włączamy
hid2=1;
lock2=WAIT_15M; // blokada 15 min na rozgrzanie
time2=WORK_TIME; // ustawienie czasu autowyłączenia
}
sw2=0; // kasujemy stan klawisza
}
}
// obsługa automatycznego wyłączenia oswietlenia
if (hid1 && !time1) // obsługa automatycznego wyłączenia HID1
{
HID1_OFF; // wyłączamy
hid1=0;
lock1=WAIT_5M; // blokada 5 min na ostygnięcie
}
if (hid2 && !time2) // obsługa automatycznego wyłączenia HID2
{
HID2_OFF; // wyłączamy
hid2=0;
lock2=WAIT_5M; // blokada 5 min na ostygnięcie
}
// wyłączamy WDT na czas obsługi klawiszy (eliminacja gaszenia LED)
if (cnt1 || cnt2) WDTCR &= ~(1<<WDTIE); else WDTCR |= (1<<WDTIE);
}
}
// ===== obsługa blokady czasowej (przerwanie 2 Hz) =====
ISR (WDT_vect)
{
// zmniejszanie czasu blokady
if (lock1) lock1--;
if (lock2) lock2--;
if (time1) time1--;
if (time2) time2--;
// jeżeli jakas operacja będzie się wykonywała po upłynięciu
// czasu blokady to migamy długo LED
if ( (lock1 && sw1) || (lock2 && sw2) ) LED_TOG; else LED_OFF;
// jeżeli nie ma żadnej operacji do wykonania ale aktywna
// jest jakas blokada to krótkie mignięcie LED
if ( (lock1 || lock2) && !sw1 && !sw2 )
{
LED_ON;
_delay_ms(2);
LED_OFF;
}
}
// ===== obsługa klawiatury (przerwanie 20 Hz) =====
ISR (TIM0_COMPA_vect)
{
/* ===== obsługa awaryjnego zmianu stanu =====
* następuje po nacinięciu przycisku S1 lub S2
* przez minimum 5 sek (gasnie LED) */
static u08 reset_lock1 = 0;
static u08 reset_lock2 = 0;
if ( KEY_S1 ) reset_lock1++; else reset_lock1=0;
if ( KEY_S2 ) reset_lock2++; else reset_lock2=0;
if (reset_lock1>=100) // min. 5 sek
{
lock1=0; // kasowanie blokady
sw1=1; // klawisz wcisnięty - nastąpi zmiana stanu
LED_OFF; // sygnalizacja upływu 5 sek
while (KEY_S1); // czekamy na zwolnienie przycisku
cnt1=WAIT_KEY; // blokada odczytu
}
if (reset_lock2>=100) // min. 5 sek
{
lock2=0; // kasowanie blokady
sw2=1; // klawisz wcisnięty - nastąpi zmiana stanu
LED_OFF; // sygnalizacja upływu 5 sek
while (KEY_S2); // czekamy na zwolnienie przycisku
cnt2=WAIT_KEY; // blokada odczytu
}
// ===== obsługa S1 =====
if ( !(cnt1) ) // jeżeli cnt = 0 - brak blokady S1, sprawdzamy
{
if ( KEY_S1 )
{
sw1=!sw1; // zmiana stanu klawisza
cnt1=WAIT_KEY; // blokada odczytu klawiszy
}
}
else
{
cnt1--; // blokada klawiszy - zmniejszamy tylko licznik
LED_ON;
}
// ===== obsługa S2 =====
if ( !(cnt2) ) // jeżeli cnt = 0 - brak blokady S2, sprawdzamy
{
if ( KEY_S2 )
{
sw2=!sw2; // zmiana stanu klawisza
cnt2=WAIT_KEY; // blokada odczytu klawiszy
}
}
else
{
cnt2--; // blokada klawiszy - zmniejszamy tylko licznik
LED_ON;
}
}
Układ został sprawdzony i przetestowany przez 3 tygodnie, działa zgodnie z założeniami
Fotki z montażu: układ zewnętrzny z przekaźnikami (zakup na e-bay) + zmontowana płytka
Zasilanie układu to zbędny driver LED, który daje 6V przy małym obciążeniu - napięcie to jest obniżane do ok 4,8V dwoma szeregowo podłączonymi diodami prostowniczymi:
Przygotowane okablowanie do montażu w obudowie:
Tu już powiercona obudowa i zamocowane płytki:
A tak się prezentuje podczas pracy:
Na koniec, jakby ktoś chciał sobie zrobić coś podobnego, to do ściągnięcia są pliki eagle (schemat i board) oraz kod źródłowy i plik wynikowy dla ATtiny13A: http://fredek.no-ip.org/HID/fredek_2xHID.zip