Strona 1 z 1

Sterownik oświetlenia dla 2 szt. HID

: niedziela 28 kwie 2013, 11:41
autor: fredek
Pozwolę sobie przedstawić mój mały projekt sterownika oświetlenia dla 2 metahalogenów :grin:
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.
Drobnego wyjaśnienia wymaga ostatni pkt. Działa to tak, że jak np. włączę metahalogen (zaczyna działać w tym przypadku timer 15 min) to led miga krótkimi impulsami, mogę od razu zażądać jego wyłączenia (po upływie blokady) to sygnalizowane jest to dłuższym miganiem diody led.

Schemat układu:

Obrazek

Wzór małej płytki sterownika:

Obrazek

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 &#40;1 sek&#41;
#define WORK_TIME 50400	// max czas pracy do autowyłączenia ~8 godz.

// definicje podłączenia portów
#define LED_PIN  &#40;1<<PB0&#41;	// dioda LED &#40;anoda do 5V&#41;
#define KEY1_PIN &#40;1<<PB1&#41;	// klawisz 1
#define KEY2_PIN &#40;1<<PB2&#41;	// klawisz 2
#define HID1_PIN &#40;1<<PB3&#41;	// HID nr 1
#define HID2_PIN &#40;1<<PB4&#41;	// HID nr 2

// definicje klawiatury
#define KEY_PIN &#40; KEY1_PIN | KEY2_PIN &#41;
#define KEY_S1 !&#40; PINB & KEY1_PIN &#41; // klawisz S1 wcinięty
#define KEY_S2 !&#40; PINB & KEY2_PIN &#41; // 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 &#40; HID1_PIN | HID2_PIN &#41;
#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&#40;void&#41;
&#123;

	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 |= &#40;1<<WDTIE&#41;;		// Watchdog Timer Interrupt Enable
	WDTCR |= &#40;1<<WDP2&#41;|&#40;1<<WDP0&#41;;	// 0.5 s

	// Ustawienie Timer0 CTC mode
	TCCR0A |= &#40;1<<WGM01&#41;;		// tryb CTC
	TCCR0B |= &#40;1<<CS02&#41;|&#40;1<<CS00&#41;;	// preskaler = 1024
	OCR0A = 234;			// ~ 20 Hz dla zegara 4,8 MHz
	TIMSK0 |= &#40;1<<OCIE0A&#41;;		// Timer/Counter0 Output Compare Match

	sei&#40;&#41;;				// włączenie przerwań

	// definiujemy stan początkowy hid-ów
	u08 hid1=0;
	u08 hid2=0;

	while &#40;1&#41;	// główna pętla
	&#123;
		// ===== obsługa HID nr 1 =====
		if &#40;!lock1&#41; 	// brak blokady
		&#123;
			if &#40;sw1&#41; 		// nacisnieto klawisz
			&#123;
				if &#40;hid1&#41; 	// hid włączony
				&#123;
					HID1_OFF;	// wyłączamy
					hid1=0;
					lock1=WAIT_5M;	// blokada 5 min na ostygnięcie
				&#125;
				else			// hid wyłączony
				&#123;
					HID1_ON;		// włączamy
					hid1=1;
					lock1=WAIT_15M;		// blokada 15 min na rozgrzanie
					time1=WORK_TIME;	// ustawienie czasu autowyłączenia
				&#125;
				sw1=0;		// kasujemy stan klawisza
			&#125;
		&#125;

		// ===== obsługa HID nr 2 =====
		if &#40;!lock2&#41; 	// brak blokady
		&#123;
			if &#40;sw2&#41; 		// nacisnieto klawisz
			&#123;
				if &#40;hid2&#41; 	// hid włączony
				&#123;
					HID2_OFF;	// wyłączamy
					hid2=0;
					lock2=WAIT_5M;	// blokada 5 min na ostygnięcie
				&#125;
				else			// hid wyłączony
				&#123;
					HID2_ON;		// włączamy
					hid2=1;
					lock2=WAIT_15M;		// blokada 15 min na rozgrzanie
					time2=WORK_TIME;	// ustawienie czasu autowyłączenia
				&#125;
				sw2=0;		// kasujemy stan klawisza
			&#125;
		&#125;

		// obsługa automatycznego wyłączenia oswietlenia
		if &#40;hid1 && !time1&#41;		// obsługa automatycznego wyłączenia HID1
		&#123;
			HID1_OFF;		// wyłączamy
			hid1=0;
			lock1=WAIT_5M;		// blokada 5 min na ostygnięcie
		&#125;
		if &#40;hid2 && !time2&#41;		// obsługa automatycznego wyłączenia HID2
		&#123;
			HID2_OFF;		// wyłączamy
			hid2=0;
			lock2=WAIT_5M;		// blokada 5 min na ostygnięcie
		&#125;

		// wyłączamy WDT na czas obsługi klawiszy &#40;eliminacja gaszenia LED&#41;
		if &#40;cnt1 || cnt2&#41; WDTCR &= ~&#40;1<<WDTIE&#41;; else WDTCR |= &#40;1<<WDTIE&#41;;
	&#125;
&#125;

// ===== obsługa blokady czasowej &#40;przerwanie 2 Hz&#41; =====
ISR &#40;WDT_vect&#41;
&#123;
	// zmniejszanie czasu blokady
	if &#40;lock1&#41; lock1--;
	if &#40;lock2&#41; lock2--;
	if &#40;time1&#41; time1--;
	if &#40;time2&#41; time2--;

	// jeżeli jakas operacja będzie się wykonywała po upłynięciu
	// czasu blokady to migamy długo LED
	if &#40; &#40;lock1 && sw1&#41; || &#40;lock2 && sw2&#41; &#41; 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 &#40; &#40;lock1 || lock2&#41; && !sw1  && !sw2 &#41;
		&#123;
		LED_ON;
		_delay_ms&#40;2&#41;;
		LED_OFF;
		&#125;
&#125;

// ===== obsługa klawiatury &#40;przerwanie 20 Hz&#41; =====
ISR &#40;TIM0_COMPA_vect&#41;
&#123;
	/* ===== obsługa awaryjnego zmianu stanu =====
	 * następuje po nacinięciu przycisku S1 lub S2
	 * przez minimum 5 sek &#40;gasnie LED&#41; */
	static u08 reset_lock1 = 0;
	static u08 reset_lock2 = 0;

	if &#40; KEY_S1 &#41; reset_lock1++; else reset_lock1=0;
	if &#40; KEY_S2 &#41; reset_lock2++; else reset_lock2=0;

	if &#40;reset_lock1>=100&#41;	// min. 5 sek
	&#123;
		lock1=0;		// kasowanie blokady
		sw1=1;			// klawisz wcisnięty - nastąpi zmiana stanu
		LED_OFF;		// sygnalizacja upływu 5 sek
		while &#40;KEY_S1&#41;;	// czekamy na zwolnienie przycisku
		cnt1=WAIT_KEY;	// blokada odczytu
	&#125;
	if &#40;reset_lock2>=100&#41;	// min. 5 sek
	&#123;
		lock2=0;		// kasowanie blokady
		sw2=1;			// klawisz wcisnięty - nastąpi zmiana stanu
		LED_OFF;		// sygnalizacja upływu 5 sek
		while &#40;KEY_S2&#41;;	// czekamy na zwolnienie przycisku
		cnt2=WAIT_KEY;	// blokada odczytu
	&#125;

	// ===== obsługa S1 =====
	if &#40; !&#40;cnt1&#41; &#41; 		// jeżeli cnt = 0 - brak blokady S1, sprawdzamy
	&#123;
		if &#40; KEY_S1 &#41;
		&#123;
			sw1=!sw1;	// zmiana stanu klawisza
			cnt1=WAIT_KEY;	// blokada odczytu klawiszy
		&#125;
	&#125;
	else
		&#123;
			cnt1--;		// blokada klawiszy - zmniejszamy tylko licznik
			LED_ON;
		&#125;

	// ===== obsługa S2 =====
	if &#40; !&#40;cnt2&#41; &#41; 		// jeżeli cnt = 0 - brak blokady S2, sprawdzamy
	&#123;
		if &#40; KEY_S2 &#41;
		&#123;
			sw2=!sw2;	// zmiana stanu klawisza
			cnt2=WAIT_KEY;	// blokada odczytu klawiszy
		&#125;
	&#125;
	else
		&#123;
			cnt2--;		// blokada klawiszy - zmniejszamy tylko licznik
			LED_ON;
		&#125;

&#125;

Układ został sprawdzony i przetestowany przez 3 tygodnie, działa zgodnie z założeniami :grin:

Fotki z montażu: układ zewnętrzny z przekaźnikami (zakup na e-bay) + zmontowana płytka

Obrazek

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:

Obrazek

Przygotowane okablowanie do montażu w obudowie:

Obrazek

Tu już powiercona obudowa i zamocowane płytki:

Obrazek

A tak się prezentuje podczas pracy:

Obrazek

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

: wtorek 30 kwie 2013, 13:45
autor: DNF
Fajne to :D Gratulacje :)