GHS_nadazny.zip

Układ nadążny za słońcem, ATMEGA16, LCD, ds18b20,L298, PWM, ADC

http://obrazki.elektroda.pl/5016503100_1355324077_thumb.jpg Układ nadążny za słońcem- inaczej układ śledzący, jest rodzajem układu sterowania, który umożliwia automatyczne lub półautomatyczne wodzenie za Słońcem. Układy tego typu wykorzystuje się najczęściej w celu znacznego podniesienia wydajności baterii fotowoltaicznych lub kolektorów słonecznych. Podstawowym założeniem projektu jest realizacja układu nadążnego za słońcem, czyli możliwość wykrycia słońca oraz odpowiednie wysterowanie silników DC w taki sposób, aby płaszczyzna odbiorników solarnych była ustawiana w kierunku prostopadłym do promieni słonecznych. Założenia w skrócie: -układ nadążny za słońcem; -możliwość pomiaru temperatury służących do kontrolowania przepływu czynnika cieplnego; -podstawowe alarmy, konfiguracja ich; -interface LCD + 4 klawisze. Program wykonany w AtmelStudio w C. No to prezentacja: 1. Hardware 1.1 mózg Projekt układu nadążnego oparty jest na ośmiobitowym mikrokontrolerze Atmega16P. Zasilany zgodnie z kartą katalogową. 1.2 Interfejs wejściowy Wejściowy interfejs użytkownika zrealizowałem za pomocą czterech, popularnie używanych w dziedzinie elektroniki, monostabilnych mikroprzycisków. http://obrazki.elektroda.pl/5856989500_1355307548_thumb.jpg Obsługa przycisków zrealizowałem za pomocą pinów 0, 1, 2, 3 portu C w taki sposób, że przy wciśnięciu zwierają dany pin portu C z masą, podając w ten sposób stan niski. Przy takim połączeniu linie wejścia/wyjścia pinów 0, 1, 2, 3 portu C zostały skonfigurowane jako wejścia z podciągnięciem do VCC. Drgania przycisków są obsłużone softwarem. http://obrazki.elektroda.pl/3011821200_1355307643_thumb.jpg 1.3 Interfejs wyjściowy Wyjściowy interfejs użytkownika zrealizowałem za pomocą alfanumerycznego wyświetlacza LCD HD44780, podłączonego do pinów 0-7 portu B. http://obrazki.elektroda.pl/4458084100_1355307802_thumb.jpg Jako wizualny, pomocniczy wskaźnik stanów sterownika wykorzystałem elektroluminescencyjne diody LED. Obsługę diod LED zrealizowałem pomocą pinów 6, 5 i 4 portu C oraz pinu 6 portu D, które skonfigurowałem jako wyjście. Gdy na którymś z pinów ustawiony zostanie stan wysoki, będzie to zasygnalizowane świeceniem diody. Za pomocą zielonej diody LED1 sygnalizuje się poprawną pracę sterownika. Gdy dioda mruga z częstotliwością 3Hz, sterownik działa poprawnie, gdy dioda LED1 świeci bądź jest zgaszona, sterownik jest w stanie zawieszenia i konieczne jest przeprowadzenie zerowania. Czerwone diody LED2, LED3 i LED4 służą do sygnalizacji aktywnych alarmów temperatury. Jeżeli któryś z alarmów zostanie aktywowany, odpowiednia dioda zostanie zapalona (alarmy temperatury zostały opisane niżej). http://obrazki.elektroda.pl/4202250200_1355307927_thumb.jpg Jako dźwiękowy wskaźnik stanów sterownika użyłem brzęczyka z generatorem. Obsługa brzęczyka zrealizowałem za pomocą pinu 7 portu D, który skonfigurowany jest jako wyjście. Gdy na pinie 7 portu D ustawiony zostanie stan wysoki, spowoduje to wygenerowanie sygnału dźwiękowego. Brzęczyk może być wykorzystywany przy obsłudze przycisków - ustawienie to można włączyć lub wyłączyć, każdorazowe wciśnięcie któregoś z przycisków może być dodatkowo sygnalizowane krótkim dźwiękiem. Drugą funkcją, gdzie wykorzystuje się sygnał dźwiękowy jest sygnalizacja aktywnych alarmów. Jeżeli któryś z alarmów zostanie aktywowany, zasygnalizowane zostanie to przerywanym sygnałem. http://obrazki.elektroda.pl/4863716300_1355307987_thumb.jpg 1.4. Układ sterowania silnikami DC Układ sterowania silnikami DC jest oparty na układzie L298, który realizuje dwa układy mostka typu H. Może być zasilany napięciem stałym o wartości nieprzekraczającej 40V. Posiada cztery wejścia, za pomocą których możliwe jest sterowanie 2 silnikami DC. Sterowanie realizuje się poprzez ustawienie stanu niskiego lub wysokiego na jedno z wejść INPUT. Układ wyposażony jest również w wejście ENABLE służące do włączenia lub wyłączenia któregoś z silników. Odpowiednie ustawienie prędkości silnika realizowane jest za pomocą techniki modulacji szerokością impulsu PWM. Dwa wejścia CURENT SENSING podłączone do masy służą do kontroli prądu obciążenia – w razie przekroczenia 4A układ zostanie wyłączony. Obsługa układu L298 zrealizowałem za pomocą pinów 0, 1, 2, 3, 4 i 5 portu D. http://obrazki.elektroda.pl/3706457700_1355321812_thumb.jpg 1.5. Układ pomiarowy natężenia oświetlenia Układ pomiarowy zrealizowałem za pomocą czterech zestawów fotorezystora RPP130 wraz z potencjometrem dopasowującym 10kΩ, połączonych w typowy układ dzielnika napięcia. Oporność fotorezystora jest ściśle związana z natężeniem światła, które pada na niego i zmienia się z przedziału od 1Ω do 10MΩ. Im większe jest natężenie światła, tym mniejszą oporność ma fotorezystor. http://obrazki.elektroda.pl/7811672900_1355322076_thumb.jpg Potencjometr jest wykorzystywany jako opornik dopasowujący. Dzięki niemu możemy przesuwać krzywą zależności między Uwy i R2, a co za tym idzie - między Uwy i natężeniem światła padającego na fotorezystor. Tak skonstruowane cztery zestawy dzielnika napięcia podłączone są do wejść analogowo-cyfrowych mikrokontrolera Atmega16, gdzie Uwy odpowiednio podłączone są do pinów 0, 1, 2, 3 Portu A, a Uwe jest równe 5V. Przy takim połączeniu linie wejścia/wyjścia pinów 0, 1, 2, 3 portu A skonfigurowałem jako 10-bitowe wejścia przetwornika analogowo-cyfrowego. http://obrazki.elektroda.pl/9318174500_1355322164_thumb.jpg 1.5. Układ pomiaru temperatury Do pomiaru temperatury wykorzystałem piny 4 i 5 portu A oraz termometr cyfrowy DS18B20 firmy Dallas. Układ scalony DS18B20 jest czujnikiem cyfrowym, który komunikuje się z mikrokontrolerem za pomocą popularnego interfejsu 1-wire, mikrokontroler komunikuje się z DS18B20 wykorzystując tylko jedną linię we/wy. http://obrazki.elektroda.pl/8141357500_1355322285_thumb.jpg 2. Software Do realizacji tego założenia wykorzystałem układ mierzący natężenie oświetlenia, układ sterowania silnikami DC oraz odpowiedni algorytm opisany w dalszej części. Dzięki układowi mierzącego natężenia oświetlania oraz wykorzystaniu odpowiednich przesłon, można określić, w jakiej pozycji płaszczyzna, na której znajdują się czujniki znajduje się w stosunku do źródła światła. Jeżeli źródło światła nie znajduje się w pozycji prostopadłej do płaszczyzny z czujnikami, przesłony znajdujące się na płaszczyźnie rzucają cień na niektóre czujniki. Jeżeli źródło światła znajduje się z lewej strony, czujniki będące po stronie prawej znajdują się w cieniu. Odpowiednio, jeżeli źródło światła znajduje się z prawej strony, czujniki będące po lewej stronie znajdują się wówczas w cieniu, jeżeli źródło światła znajduje się z dołu lub z góry, odpowiednie pary czujników dolne lub górne znajdują się w cieniu. Dzięki pomiarowi napięcia Uwy można określić, czy czujnik jest oświetlony, czy znajduje się aktualnie w cieniu, a co za tym idzie - możemy określić położenie źródła światła w stosunku do płaszczyzny, na której umiejscowione są czujniki. http://obrazki.elektroda.pl/3136175500_1355322587_thumb.jpg W pierwszej kolejności wyniki są odpowiednio grupowane i liczone są średnie arytmetyczne. Jeżeli średnia z dwóch czujników górnych (PA01) jest niższa od średniej z dwóch czujników dolnych (PA23). Oznacza to, iż na czujniki dolne pada więcej światła niż na górne. Dodatkowo, jeżeli ta różnica jest większa od stałej T – tolerancja, wykorzystany jest układ L298, który sterując silnikiem M2 porusza 1-krok płaszczyznę odbiornika solarnego w dół. Odpowiednio, jeżeli te zależności są odwrotne, układ sterując silnikiem M2, porusza płaszczyznę odbiornika solarnego 1-krok w górę. Jeżeli średnie są sobie równe lub ta różnica jest mniejsza niż stała T, wówczas silnik zachowuje swoją pozycję. Analogicznie operacja przeprowadzona jest dla średnich wyliczanych przez grupowanie czujników z lewej (PA02) i prawej (PA13) strony. Jeżeli występuje różnica w którymś z przypadków i ta różnica jest większa od stałej T, silnik porusza płaszczyznę odbiornika solarnego odpowiednio w prawo lub w lewo. W ten sposób jest zrealizowana funkcja układu nadążnego za słońcem. Proces jest powtarzany co 0,5s. 3. Menu - opis funkcji sterownika Menu sterownika jest wielopoziomowe. Niektóre funkcje są niedostępne, zostaną one uaktywnione w miarę dalszego rozwijania projektu. Do poruszania się po menu sterownika wykorzystałem 4 mikroprzyciski: S2, S3, S4, S5. S2 „BACK” poruszanie się w tył po poziomie menu, wyłączanie edycji zmiennych; S3 „LEWO” poruszanie się po funkcjach danego poziomu menu, zmiana wartości zmiennych o jednostkę w dół; S4 „PRAWO” poruszanie się po funkcjach danego poziomu menu, zmiana wartości zmiennych o jednostkę w górę; S5 „ENTER” poruszanie się w przód po poziomie menu, wyłączanie edycji zmiennych. 4. Włączamy Po włączeniu zasilania układ kalibruje się ok. 2ms i zostają wgrane ustawienia domyślne, a na wyświetlaczu LCD zostaje wyświetlony ekran powitalny. http://obrazki.elektroda.pl/1070950300_1355323126_thumb.jpg Ekran powitalny jest zarazem ekranem, który wyświetla się podczas działania funkcji STAND_BY. Funkcja ta jest aktywowana samoistnie, gdy sterownik przez 30s. nie jest używany przez operatora tzn. żaden z przycisków nie został wciśnięty przez 30s. a po upływie 40s. wyłączane jest oświetlenie wyświetlacza LCD. Gdy któryś z przycisków zostanie wciśnięty, funkcja STAND_BY zostaje przerwana, a sterownik przechodzi do głównego poziomu menu. Główny poziom menu składa się z 4 pozycji, pomiędzy którymi przełącza się za pomocą przycisków S3 „LEWO” oraz S4 „PRAWO”. http://obrazki.elektroda.pl/7744395900_1355323175_thumb.jpg Wybór sterowania W oknie „Wybór sterowania” użytkownik może wybrać jedną z dwóch metod pozycjonowania odbiorników solarnych. Pierwsza z nich jest to sterowanie nadążne, druga sterowanie czasowe. Sterownik nie posiada układu zegara czasu rzeczywistego RTC (z ang. Real Time Clock), dlatego też wybór sterowania czasowego nie jest możliwy. Ewentualnie do dalszej rozbudowy. http://obrazki.elektroda.pl/3946684700_1355323289_thumb.jpg Pomiar temperatury W oknie „Pomiar temperatury” użytkownik może odczytać wartość temperatury mierzonej przez dwa czujniki Dallas DS18b20 oraz skalibrować dwa typy alarmu temperatury. http://obrazki.elektroda.pl/6913754200_1355323335_thumb.jpg Pierwszy typ alarmu temperatury określa się dla czujnika pierwszego i/lub drugiego. Ustawienie alarmu polega na ustawieniu wartości granicznej dla mierzonej temperatury. Jeżeli ta wartość zostanie przekroczona dla któregoś z czujników, alarm zostaje uaktywniony. Drugi typ alarmu określa się dla obu czujników. Kalibracja tego typu alarmu polega na ustawieniu wartości granicznej, o którą mierzona wartość temperatury czujnika drugiego jest większa od mierzonej temperatury czujnika pierwszego. Jeżeli różnica między temperaturą mierzoną przez czujnik drugi, a temperaturą mierzoną przez czujnik pierwszy będzie większa od ustawionej wartości granicznej zostanie uaktywniony alarm. http://obrazki.elektroda.pl/6768213700_1355323378_thumb.jpg Pomiar napięcia Pomiar napięć jest opcjonalny i można go zrealizować zamiast pomiaru temperatury w zależności, czy to ma być sterownik do kolektorów czy baterii solarnych. Ustawienia Okno ustawienia składa się z trzech pozycji. Pierwsza z nich służy do włączenia lub wyłączenia dźwięku podczas obsługi klawiszy. Druga pozycja służy do ustawienia zegara RTC (sterownik opisany tu nie posiada jeszcze układu RTC, a więc ta opcja nie jest dostępna). Trzecia pozycja służy do kalibracji układów dzielnika napięcia służących do określenia pozycji słońca względem płaszczyzny, w której znajdują się fotorezystory - czujniki. Kalibracja polega na ustawieniu płaszczyzny pomiarowej w kierunku prostopadłym do padających promieni słonecznych. Wskazania dla wszystkich czujników powinny być zbliżone i wartości oscylować wokół 800, a różnica między poszczególnymi układami dzielników napięcia nie powinny przekraczać 50. Wartości mierzone na ADC są w granicach <0; 1024>. http://obrazki.elektroda.pl/3200037700_1355323601_thumb.jpg Przykładowe zastosowanie powyżej opisanych alarmów dla odbiornika solarnego typu kolektor słoneczny http://obrazki.elektroda.pl/1208803000_1355323455_thumb.jpg Czujnik T1 jest umieszczony przy ujściu z kolektora słonecznego. Czujnik T2 zamieszczony jest przy ujściu z bojlera, wówczas alarmy można skonfigurować w poniższy sposób: Konfiguracja ALARM1- Jeżeli woda w kolektorze wzrośnie do np. 100st., włącza się alarm oraz zawór bezpieczeństwa Z1. Konfiguracja ALARM2 - Jeżeli woda w bojlerze wzrośnie do np. 100st., włącza się alarm oraz zawór bezpieczeństwa Z2. Konfiguracja ALARM 1-2 - Jeżeli różnica temperatury między czujnikiem T1 a T2 jest większa niż 50st., oznacza to np. awarię pompy wymuszającej obieg. Włącza się alarm i zawór bezpieczeństwa. Alarm ten można wykorzystać jako sterowanie wł./wł. pompę obiegową, jeżeli nie jest to rozwiązane - w inny sposób. Do sterownika można podłączyć dowolną ilość termometrów poprzez zastosowanie multiplexera. Jednak jest to już rozwiązanie pod konkretny układ. A teraz najlepsze, czyli prototyp Głowica pomiarowa została wykonana z atrapy kamery, która, o dziwo, posiada w sobie ruchomą platformę w jednej osi, co ułatwiło sprawę. Obrotu wykorzystano serwa modelarskie przerobione na silniki DC. Tak prezentuje się głowica w całości: http://obrazki.elektroda.pl/1129471200_1355324072_thumb.jpg http://obrazki.elektroda.pl/6647662500_1355324074_thumb.jpg http://obrazki.elektroda.pl/5016503100_1355324077_thumb.jpg http://obrazki.elektroda.pl/9259537000_1355324079_thumb.jpg Część obliczeniowa wraz z interfejsem została wykonana za pomocą uniwersalnej płytki testowej. http://obrazki.elektroda.pl/7267924300_1355324172_thumb.jpg Filmy: Menu + alarm http://www.youtube.com/watch?v=4fsvJJgP5CM Głowica http://www.youtube.com/watch?v=EfctCiyMuQs To jest mój 2. projekt z wykorzystaniem mikrokontrolera, wykonałem go na bazie ogólnodostępnych przykładów z internetu i kart katalogowych. Zdecydowałem się go Wam przedstawić ze względu na to, iż zawiera w sobie większość funkcji wykorzystywanych przez początkujących programistów (tytuł). Czemu ma taką postać? Projekt uważam jako skończony i nie potrzebuję go w lepszej wersji. Dla wszystkich użytkowników którzy mi pomagali download bez punktów. Download zawiera cały folder projektu z AtmelStudio i schemat w PDF. Pamiętaj - kod, program zawsze da się zoptymalizować, dlatego proszę bez zbędnych uwag. Wbrew pozorom najwięcej problemów mi zrobiło zrobienie wielopoziomowego menu. :)

  • GHS_nadazny.zip
    • ghouse.aws
    • hd44780.c
    • pwm.h
    • TcfTransactionLog.csv
    • pwm.c
    • pomiarv.c
    • GHouse.c
    • ds18b20.c
    • pomiarv.h
    • ds18b20.h
    • GHouse.aps
    • Array
    • hd44780.h


Pobierz plik - link do postu

GHS_nadazny.zip > hd44780.c

/*
Plik hd44780.c

Definicje kilku funkcji do obs?ugi alfanumerycznego
wyœwietlacza LCD HD44780
*/


#include &amp; lt; avr/io.h &amp; gt;
#include &amp; lt; util/delay.h &amp; gt;
#include &quot; hd44780.h &quot;

/*--------------------------------------------------------*/
/* Zapis danej lub instrukcji */

void WriteToLCD (unsigned char v,unsigned char rs)
{
unsigned char bf;

SET_OUT_LCD_D4;
SET_OUT_LCD_D5;
SET_OUT_LCD_D6;
SET_OUT_LCD_D7;

if(v &amp; 0x10) SET_LCD_D4; else CLR_LCD_D4;
if(v &amp; 0x20) SET_LCD_D5; else CLR_LCD_D5;
if(v &amp; 0x40) SET_LCD_D6; else CLR_LCD_D6;
if(v &amp; 0x80) SET_LCD_D7; else CLR_LCD_D7;

CLR_LCD_E;
if(rs) SET_LCD_RS;else CLR_LCD_RS;
CLR_LCD_RW;

LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;

if(v &amp; 0x01) SET_LCD_D4; else CLR_LCD_D4;
if(v &amp; 0x02) SET_LCD_D5; else CLR_LCD_D5;
if(v &amp; 0x04) SET_LCD_D6; else CLR_LCD_D6;
if(v &amp; 0x08) SET_LCD_D7; else CLR_LCD_D7;

LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;

SET_IN_LCD_D4;
SET_IN_LCD_D5;
SET_IN_LCD_D6;
SET_IN_LCD_D7;

CLR_LCD_RS;
SET_LCD_RW;
SET_LCD_D7;


/* Przyda?by si? pe?ny odczyt */
do
{
LCD_NOP;
SET_LCD_E;
LCD_NOP;
bf = IS_SET_LCD_D7;
CLR_LCD_E;
LCD_NOP;
SET_LCD_E;
LCD_NOP;
LCD_NOP;
CLR_LCD_E;

}while( bf );
}


/*--------------------------------------------------------*/
/* Funkcja odczytuje adres i flage zajetosci */

unsigned char ReadAddressLCD ( void)
{
unsigned char g = 0 ;

CLR_LCD_RS;
SET_LCD_RW;

SET_IN_LCD_D4;
SET_IN_LCD_D5;
SET_IN_LCD_D6;
SET_IN_LCD_D7;

LCD_NOP;
SET_LCD_E;
LCD_NOP;

if(IS_SET_LCD_D4) g+=16;
if(IS_SET_LCD_D4) g+=32;
if(IS_SET_LCD_D4) g+=64;
if(IS_SET_LCD_D4) g+=128;

CLR_LCD_E;
LCD_NOP;
SET_LCD_E;
LCD_NOP;

if(IS_SET_LCD_D4) g+=8;
if(IS_SET_LCD_D4) g+=4;
if(IS_SET_LCD_D4) g+=2;
if(IS_SET_LCD_D4) g+=1;

CLR_LCD_E;

return g ;
}


/*---------------------------------------------------------*/
/* Inicjalizacja wyœwietlacza */

void lcd_init(void)
{
_delay_ms(31);

SET_OUT_LCD_RS;
SET_OUT_LCD_RW;
SET_OUT_LCD_E;
SET_OUT_LCD_D4;
SET_OUT_LCD_D5;
SET_OUT_LCD_D6;
SET_OUT_LCD_D7;

CLR_LCD_E;
CLR_LCD_RS;
CLR_LCD_RW;
SET_LCD_D4;
SET_LCD_D5;
CLR_LCD_D6;
CLR_LCD_D7;

LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;
_delay_ms(10);

LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;
_delay_ms(2);

LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;
_delay_ms(2);

CLR_LCD_D4;
LCD_NOP;
SET_LCD_E;
LCD_NOP;
CLR_LCD_E;
LCD_NOP;
_delay_us(80);

WriteToLCD (0x28 , LCDCOMMAND) ;
LCD_DISPLAY(0) ;
LCD_CLEAR ;
LCD_ENTRY_MODE(LCDINCREMENT) ;
}


/*--------------------------------------------------------*/
/* Wyswietla tekst na aktualnej pozycji kursora */

void lcd_puts(char *str)
{
unsigned char i =0;

while( str[i])
LCD_WRITE_DATA(str[i++]) ;
}


GHS_nadazny.zip > pwm.h

/*
pwm.h
*/

#ifndef pwm
#define pwm

//Zmienne obslugujace PWM
/* W tablicy b?dzie formulowane wyswietlanie predkosci */
char V1[10];
char V2[10];


#define SET_IN1 PORTD |= _BV(3) /* PB7 - &amp; gt; INPUT 1 L298 */
#define CLR_IN1 PORTD &amp; = ~_BV(3)
#define SET_IN1_OUT DDRD |= _BV(3)

#define SET_IN2 PORTD |= _BV(2) /* PB6 - &amp; gt; INPUT 2 L298 */
#define CLR_IN2 PORTD &amp; = ~_BV(2)
#define SET_IN2_OUT DDRD |= _BV(2)

#define SET_IN3 PORTD |= _BV(1) /* PB5 - &amp; gt; INPUT 3 L298 */
#define CLR_IN3 PORTD &amp; = ~_BV(1)
#define SET_IN3_OUT DDRD |= _BV(1)

#define SET_IN4 PORTD |= _BV(0) /* PB5 - &amp; gt; INPUT 4 L298 */
#define CLR_IN4 PORTD &amp; = ~_BV(0)
#define SET_IN4_OUT DDRD |= _BV(0)

/* Nie nalezy zmieniac */
#define SET_ENA_OUT DDRD |= _BV(5) /* PD5 (OC1A) - sygnal PWM - &amp; gt; ENABLE A L298 */
/* Nie nalezy zmieniac */
#define SET_ENB_OUT DDRD |= _BV(4) /* PD4 (OC1B) - sygnal PWM - &amp; gt; ENABLE B L298 */




#endif


GHS_nadazny.zip > TcfTransactionLog.csv

Service , Message , Max , Min , Average , Count , frequency , TimedOut

Stream,setLogBits,16.0009,16.0009,16.0009,1,0


GHS_nadazny.zip > pwm.c

/*
Plik pwm.c

Definicje kilku funkcji do obs?ugi pwm
*/


#include &amp; lt; avr/io.h &amp; gt;
#include &amp; lt; util/delay.h &amp; gt;
#include &quot; pwm.h &quot;

/* Wstepne ustawienia */

void PWMinit(void)
{
/* Ustawienie kierunku uzytych portow jako wyjscia */
SET_IN1_OUT;
SET_IN2_OUT;
SET_IN3_OUT;
SET_IN4_OUT;
SET_ENA_OUT;
SET_ENB_OUT;

/* Ustawienie tajmera do pracy w trybie PWM */
ICR1 = 1000;
OCR1A = 0;
OCR1B = 0;

/* Tryb PWM phase and frequency correct, patrz ATmega32 datasheet */
// TCCR1A = 0xA0;
TCCR1A = (1 &amp; lt; &amp; lt; COM1A1)|(1 &amp; lt; &amp; lt; COM1B1)|(1 &amp; lt; &amp; lt; WGM10);
// TCCR1B = 0x12;
TCCR1B = (1 &amp; lt; &amp; lt; CS10)|(1 &amp; lt; &amp; lt; WGM12);
}



/*** MANEWRY ***/


/* zmienne: 'a' i 'b' przechowuja wartosci predkosci (od 0 do 255) dla dwoch linii PWM */
//silnik1 w lewo
void silnik1P( int a)
{
OCR1A = a;
// OCR1B = b;
CLR_IN1; /* lewe kolo w przod */
SET_IN2;
// CLR_IN3; /* prawe kolo w przod */
// SET_IN4;
}

//silnik1 w prawo
void silnik1L( int a)
{
OCR1A = a;
// OCR1B = b;
SET_IN1; /* lewe kolo wstecz */
CLR_IN2;
// SET_IN3; /* prawe kolo wstecz */
// CLR_IN4;
}
//silnik2 w lewo
void silnik2P( int b)
{
// OCR1A = a;
OCR1B = b;
// CLR_IN1; /* lewe kolo w przod */
// SET_IN2;
CLR_IN3; /* prawe kolo w przod */
SET_IN4;
}

//silnik2 w prawo
void silnik2L( int b)
{
// OCR1A = a;
OCR1B = b;
// SET_IN1; /* lewe kolo wstecz */
// CLR_IN2;
SET_IN3; /* prawe kolo wstecz */
CLR_IN4;
}

/* Zatrzymanie */
void zatrzymanieS1(void )
{
OCR1A = 0;
// OCR1B = 0;
CLR_IN1; /* lewe kolo stop */
CLR_IN2;
// CLR_IN3; /* prawe kolo stop */
// CLR_IN4;
}

/* Zatrzymanie */
void zatrzymanieS2(void )
{
// OCR1A = 0;
OCR1B = 0;
// CLR_IN1; /* lewe kolo stop */
// CLR_IN2;
CLR_IN3; /* prawe kolo stop */
CLR_IN4;
}


GHS_nadazny.zip > pomiarv.c

/*
Plik pomiarv.c

Definicje kilku funkcji do pomiaru napiecia na adc
*/


#include &amp; lt; avr/io.h &amp; gt;
#include &amp; lt; util/delay.h &amp; gt;
#include &quot; pomiarv.h &quot;



unsigned char ADCInit()
{
ADCSRA |= (1 &amp; lt; &amp; lt; ADEN) | (1 &amp; lt; &amp; lt; ADIE) | (1 &amp; lt; &amp; lt; ADPS0) | (1 &amp; lt; &amp; lt; ADPS1) | (1 &amp; lt; &amp; lt; ADPS2); //uruchomienie przetwornika, CLK/128

ADMUX |= (1 &amp; lt; &amp; lt; REFS0) | (1 &amp; lt; &amp; lt; REFS1) ; //Aref - wewnetrze zrodlo odniesienia 2,56 V

}


unsigned char ADCpomiar(uint8_t channel) //przypozadkowanie kanalu
{
switch (channel)
{
case 0 :
ADMUX = ((ADMUX &amp; 0xE0)+ 0);
ADCSRA |= (1 &amp; lt; &amp; lt; ADSC); //zacznij pomiar
while (ADCSRA &amp; (1 &amp; lt; &amp; lt; ADSC)); //czekaj na koniec pomiaru
Voltage0[0] = ADC; //zapisz pomiar do zmiannej

break;

case 1 :
ADMUX = ((ADMUX &amp; 0xE0)+ 1);
ADCSRA |= (1 &amp; lt; &amp; lt; ADSC); //zacznij pomiar
while (ADCSRA &amp; (1 &amp; lt; &amp; lt; ADSC)); //czekaj na koniec pomiaru
Voltage1[0] = ADC; //zapisz pomiar do zmiannej

break;

case 2 :
ADMUX = ((ADMUX &amp; 0xE0)+ 2);
ADCSRA |= (1 &amp; lt; &amp; lt; ADSC); //zacznij pomiar
while (ADCSRA &amp; (1 &amp; lt; &amp; lt; ADSC)); //czekaj na koniec pomiaru
Voltage2[0] = ADC; //zapisz pomiar do zmiannej

break;

case 3 :
ADMUX = ((ADMUX &amp; 0xE0)+ 3);
ADCSRA |= (1 &amp; lt; &amp; lt; ADSC); //zacznij pomiar
while (ADCSRA &amp; (1 &amp; lt; &amp; lt; ADSC)); //czekaj na koniec pomiaru
Voltage3[0] = ADC; //zapisz pomiar do zmiannej

break;


}
}


GHS_nadazny.zip > GHouse.c

//Plik g?ówny &quot; Ghouse.c &quot;



#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; avr/io.h &amp; gt; //biblioteka wejsc wyjsc
#include &amp; lt; util/delay.h &amp; gt; //biblioteka zliczania czasu
#include &amp; lt; inttypes.h &amp; gt; //biblioteka typu danych
#include &quot; hd44780.h &quot;
#include &quot; pwm.h &quot;
#include &quot; pomiarv.h &quot;
#include &quot; ds18b20.h &quot;


//deklaracja przyciskow podpietych do portu A
#define przycisk_1 0x01 //BACK
#define przycisk_2 0x02 // &amp; lt;
#define przycisk_3 0x04 // &amp; gt;
#define przycisk_4 0x08 //ENTER/CHANGE

//deklaracja pinu PB1 jako wyjscie podswietlenia
#define podswietlenie_ON PORTB |= _BV(PB3) //edycja pojedynczego bitu PB3=1
#define podswietlenie_OFF PORTB &amp; = ~(_BV(PB3)) //edycja pojedynczego bitu PB3=0


//Deklaracje zmiennych************************************************************


//Zmienna przechowuje predkosc silnikow - wypelnienie impulsu
double wsk=90;

//Zmienna przechowuje tolerancje wykrycia slonca
int tolerancja =30;

//Zmienna przechowuje chwilowe wartosci z czujnikow
volatile uint16_t czujnik1;
volatile uint16_t czujnik2;
volatile uint16_t czujnik3;
volatile uint16_t czujnik4;

//Zmienne przechowuje srednia z czujnikow
volatile uint16_t czujnik12;
volatile uint16_t czujnik34;
volatile uint16_t czujnik13;
volatile uint16_t czujnik24;

//Zmienne pomocnicze czujnikow
double czujnik111;
double czujnik222;
double czujnik333;
double czujnik444;

//Zmienne przechowujace srednia z czujnikow - tablice do LCD
char czujnik11[10];
char czujnik22[10];
char czujnik33[10];
char czujnik44[10];

//Zmienne przechowujace wynik czujnikow temperatury - tablice do LCD
char temp11[10];
char temp21[10];

// Zmienna przechowuje aktualn? wartosc temperatury
double temp12;
double temp22;

//Zmienne przechowywuj?ce dane odczytane z uk?adu ds18b20
unsigned char ds18b20_pad1[9];
unsigned char ds18b20_pad2[9];

//Zmienna wskazujaca polorzenie w MENU
int alokacja=0U;

//Zmienne lokacyjne MENU
int w1=0U;
int w2=0U;
int w3=0U;
int w4=0U;
int w5=0U;

//Wskaznik trubu sterowania
char SterowanieN=0U;
char SterowanieC=0U;

// Zmienne trubu i wartosci alarmu
char AlarmC1=0U;
double PoziomC1=20;
char PPoziomC1[10];

char AlarmC2=0U;
double PoziomC2=20;
char PPoziomC2[10];

char AlarmC1C2=0U;
double PoziomC1C2=20;
char PPoziomC1C2[10];

//Zmienna dzwieku trubu klawiszy
char Buzer=0U;

//Zmienna dzwieku alarmu
char Buzer1=0U;

//Tablica pomocnia MENU
char *Stan[]={ &quot; NIE &quot; , &quot; TAK &quot; };


//Zmienna wskazujaca na pozycje dla przyciskow
int pozycja=0U;

//Liczniki STAND BY
int wyswietlacz=0U; //stand by wyswietlacz podswietlenie
int powitanie=0U; //stand by powitanie

//Koniec deklaracje zmiennych-----------------------------------------------------



//Deklaracje funkcji**************************************************************


//--------------------------------------------------------------------------------
//Funkcja Buzer
void Pip(void)
{
if(Buzer==1)
{
PORTD |= _BV(PD7);
_delay_us(100);
PORTD &amp; = ~(_BV(PD7));

}

else
{
PORTD &amp; = ~(_BV(PD7));
}

}

//--------------------------------------------------------------------------------
//Funkcja szukania najaœniejszego punktu

void szukaj(tolerancja)
{
//Pomiar kanal 0
ADCpomiar(0);
czujnik1=Voltage0[0]; //Przypisanie wyniku do zmiennej czujnik 1
czujnik111=czujnik1;
sprintf(czujnik11, &quot; %4.0f &quot; , czujnik111);

//Pomiar kanal 1
ADCpomiar(1);
czujnik2=Voltage1[0];
czujnik222=czujnik2;
sprintf(czujnik22, &quot; %4.0f &quot; , czujnik222);

//Pomiarc kanal 2
ADCpomiar(2);
czujnik3=Voltage2[0];
czujnik333=czujnik3;
sprintf(czujnik33, &quot; %4.0f &quot; , czujnik333);

//Pomiar kanal 3
ADCpomiar(3);
czujnik4=Voltage3[0];
czujnik444=czujnik4;
sprintf(czujnik44, &quot; %4.0f &quot; , czujnik444);
}

//--------------------------------------------------------------------------------
//Funkcja sterowania silnikami

void pokaz(wsk)
{
//Liczenie sredniej z czujnikow
czujnik12=(czujnik1+czujnik2)/2;
czujnik34=(czujnik3+czujnik4)/2;
czujnik13=(czujnik1+czujnik3)/2;
czujnik24=(czujnik2+czujnik4)/2;

//Obsluga silniczka dolnego
if ((czujnik13+tolerancja) &amp; lt; czujnik24)
{
silnik1L(wsk);
_delay_ms(30);
zatrzymanieS1();
}

if ((czujnik24+tolerancja) &amp; lt; czujnik13)
{
silnik1P(wsk);
_delay_ms(30);
zatrzymanieS1();
}

if ((czujnik13-czujnik24) &amp; lt; (tolerancja - 10) || (czujnik24-czujnik13) &amp; lt; (tolerancja - 10))
{
zatrzymanieS1();
}

//Obsluga silniczka gornego

if ((czujnik12+tolerancja) &amp; lt; czujnik34)
{
silnik2P(wsk);
_delay_ms(30);
zatrzymanieS2();
}

if ((czujnik34+tolerancja) &amp; lt; czujnik12)
{
silnik2L(wsk);
_delay_ms(30);
zatrzymanieS2();
}

if ((czujnik12-czujnik34) &amp; lt; (tolerancja - 10) || (czujnik34-czujnik12) &amp; lt; tolerancja - 10)
{
zatrzymanieS2();
}

}

//--------------------------------------------------------------------------------
//Funkcja pomiaru temperatury

void temperatura()
{
//Zczytanie czujnika 1

//Wysy?anie polecenia do pomiaru

if(ds18b20_ConvertT1())
{
// Odczyt z uk?adu ds18b20,zapisanie danych do tablicy ds18b20_pad1.
ds18b20_Read1(ds18b20_pad1);

//Z?o?enie wyniku 2 bajty Cztery pierwsze bity mniej
// znacz?cego bajtu to cz?œae u?amkowa wartoœci temperatury, wi?c ca?oœae
// dzielona jest przez 16
temp12 = ((ds18b20_pad1[1] &amp; lt; &amp; lt; 8) + ds18b20_pad1[0]) / 16.0 ;

// Konwersja wyniku na LCD, %4.1f - format \xdf - st. &quot; &quot; C &quot; - celcjusza
sprintf(temp11, &quot; %4.1f\xdf &quot; &quot; C &quot; , temp12);

}

//Zczytanie czujnika 2
if(ds18b20_ConvertT2())
{
ds18b20_Read2(ds18b20_pad2);
temp22 = ((ds18b20_pad2[1] &amp; lt; &amp; lt; 8) + ds18b20_pad2[0]) / 16.0 ;
sprintf(temp21, &quot; %4.1f\xdf &quot; &quot; C &quot; , temp22);
}
}
//--------------------------------------------------------------------------------
//Funkcje alarmu
void Warning(void)
{
if(Buzer1==0)
{
Buzer1=1;
}
else
{
Buzer1=0;
}

if(PoziomC1 &amp; lt; =temp12 &amp; &amp; AlarmC1==1)
{
PORTC |= _BV(PC4);
if(Buzer1==1)
{
PORTD |= _BV(PD7);
}
}
else
{
PORTC &amp; = ~(_BV(PC4));
}
if(PoziomC2 &amp; lt; =temp22 &amp; &amp; AlarmC2==1)
{
PORTC |= _BV(PC5);
if(Buzer1==1)
{
PORTD |= _BV(PD7);
}
}
else
{
PORTC &amp; = ~(_BV(PC5));
}

if(temp12 &amp; gt; =(temp22+PoziomC1C2) &amp; &amp; AlarmC1C2==1)
{
PORTC |= _BV(PC6);
if(Buzer1==1)
{
PORTD |= _BV(PD7);
}
}
else
{
PORTC &amp; = ~(_BV(PC6));
}

if(Buzer1==0)
{
PORTD &amp; = ~(_BV(PD7));
}
}
//----------------------------------------------------------------------------
//STAND BY oswietlenie LCD

void STAND_BY_LIGHT(void)
{
if (wyswietlacz &amp; lt; = 500)
{
podswietlenie_ON;
}
else
{
podswietlenie_OFF;
}
}

//----------------------------------------------------------------------------
//STAND BY wyswietlenie powitania

void STAND_BY_MENU(void)
{
if (powitanie == 1000)
{
LCD_CLEAR;
w1=0;
w2=0;
w3=0;
w4=0;
pozycja=0;

}
}

//--------------------------------------------------------------------------------
//Funkcja wskaznika menu LCD

void MENU(void)

{
switch(alokacja)
{
case 0:
{

LCD_LOCATE(4,0);
lcd_puts( &quot; Sterownik &quot; );
LCD_LOCATE(1,1);
lcd_puts( &quot; -=GreenHOUSE=- &quot; );
}
break;
//----------------------------------------------------------------------------
case 1000:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; 1 Wybor &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; sterowania &quot; );
}
break;
case 1100:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Sterowanie &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; nadazne &quot; );
if(SterowanieN==0)
{
LCD_LOCATE(13,1);
lcd_puts(Stan[0]);
}
if(SterowanieN==1)
{
LCD_LOCATE(13,1);
lcd_puts(Stan[1]);
}
}
break;

case 1110:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Sterowanie &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; nadazne &quot; );
if(SterowanieN==0)
{
LCD_LOCATE(12,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(13,1);
lcd_puts(Stan[0]);
}
if(SterowanieN==1)
{
LCD_LOCATE(12,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(13,1);
lcd_puts(Stan[1]);
}

}
break;


case 1200:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Sterowanie &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; czasowe &quot; );
LCD_LOCATE(13,1); //Sterowanie czasowe nieosiagalne
lcd_puts( &quot; --- &quot; );
}
break;

//----------------------------------------------------------------------------

case 2000:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; 2 Pomiar &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; temperatury &quot; );
}
break;

case 2100:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik1: &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp11);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2200:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik2: &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp21);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2300:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Alarm &quot; );
LCD_LOCATE(0,1);
lcd_puts( &quot; temperatury &quot; );
}
break;
case 2310:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik1 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp11);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
if(AlarmC1==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2311:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik1 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp11);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
LCD_LOCATE(3,1);
lcd_puts( &quot; &amp; gt; &quot; );
if(AlarmC1==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2312:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik1 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp11);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
if(AlarmC1==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(9,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;

case 2320:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik2 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp21);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
if(AlarmC2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2321:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik2 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp21);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
LCD_LOCATE(3,1);
lcd_puts( &quot; &amp; gt; &quot; );
if(AlarmC2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2322:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Czujnik2 &quot; );
LCD_LOCATE(10,0);
lcd_puts(temp21);
lcd_puts( &quot; \xdf &quot; &quot; C &quot; );
if(AlarmC2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(9,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(10,1);
lcd_puts(PPoziomC2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;

case 2330:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Roznica1 &amp; gt; 2 &quot; );
if(AlarmC1C2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1C2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1C2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2331:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Roznica1 &amp; gt; 2 &quot; );
LCD_LOCATE(3,1);
lcd_puts( &quot; &amp; gt; &quot; );
if(AlarmC1C2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1C2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1C2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;
case 2332:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Roznica1 &amp; gt; 2 &quot; );
if(AlarmC1C2==0)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[0]);
}
if(AlarmC1C2==1)
{
LCD_LOCATE(4,1);
lcd_puts(Stan[1]);
}
LCD_LOCATE(9,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(10,1);
lcd_puts(PPoziomC1C2);
lcd_puts( &quot; .0 &quot; &quot; \xdf &quot; &quot; C &quot; );
}
break;

//----------------------------------------------------------------------------

case 3000:
{

LCD_LOCATE(0,0);
lcd_puts( &quot; 3 Pomiar &quot; );
LCD_LOCATE(3,1);
lcd_puts( &quot; napiecia &quot; );
}
break;

//----------------------------------------------------------------------------

case 4000:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; 4 Ustawienia &quot; );
}
break;

case 4100:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Buzer &quot; );
if(Buzer==0)
{
LCD_LOCATE(13,1);
lcd_puts(Stan[0]);
}
if(Buzer==1)
{
LCD_LOCATE(13,1);
lcd_puts(Stan[1]);
}
}
break;

case 4110:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Buzer &quot; );
if(Buzer==0)
{
LCD_LOCATE(12,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(13,1);
lcd_puts(Stan[0]);
}
if(Buzer==1)
{
LCD_LOCATE(12,1);
lcd_puts( &quot; &amp; gt; &quot; );
LCD_LOCATE(13,1);
lcd_puts(Stan[1]);
}
}
break;

case 4200:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Zegar &quot; );
LCD_LOCATE(4,1);
lcd_puts( &quot; NIEDOSTEPNY &quot; );
}
break;

case 4300:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; Kalibracja &quot; );
LCD_LOCATE(3,1);
lcd_puts( &quot; czujnikow &quot; );
}
break;
case 4310:
{
LCD_LOCATE(0,0);
lcd_puts( &quot; C1: &quot; );
lcd_puts(czujnik11);
LCD_LOCATE(9,0);
lcd_puts( &quot; C2: &quot; );
lcd_puts(czujnik33);
LCD_LOCATE(0,1);
lcd_puts( &quot; C3: &quot; );
lcd_puts(czujnik22);
LCD_LOCATE(9,1);
lcd_puts( &quot; C4: &quot; );
lcd_puts(czujnik44);
}
break;


case 5000:
{
LCD_LOCATE(4,0);
lcd_puts(temp11);
LCD_LOCATE(4,1);
lcd_puts(temp21);
LCD_LOCATE(0,0);
lcd_puts(czujnik11);
LCD_LOCATE(0,1);
lcd_puts(czujnik33);
LCD_LOCATE(8,0);
lcd_puts(czujnik22);
LCD_LOCATE(8,1);
lcd_puts(czujnik44);
}
break;
}
}

//Koniec deklaracja funkcji-------------------------------------------------------


//Program glowny******************************************************************

int main(void)
{
//Inicjalizacja wyœwietlacza
lcd_init();

//Wlaczenie wyswietlania
LCD_DISPLAY(LCDDISPLAY);

//Czyszczenie ekranu
LCD_CLEAR;

//Alokacja kursora
LCD_LOCATE(0,0);

//Inicjalizacja pomiaru
ADCInit();

//Inicjalizacja PWM
PWMinit();


// Porty PC0, PC1, PC2, PC3 b?d? wejœciami z podci?gni?ciem do VCC -klawisze
// Porty PC4, PC5, PC6, PC7 b?d? wyjœciami - alarmy
DDRC = 0xf0;
PORTC = 0x0f;

//Ustawienie pojedynczegfo bitu na wyjscie - podswietlenie
DDRB |= _BV(PB3);

//Ustawienie pojedynczego bitu na wyjscie - dioda kontrolna
DDRD |= _BV(PD6);

//Ustawienie pojedynczegfo bitu na wyjscie - buzer
DDRD |= _BV(PD7);


while(1)
{

STAND_BY_LIGHT();
STAND_BY_MENU();

szukaj(tolerancja);
temperatura();

Warning();


if(SterowanieN==1) //Jezeli jest wlaczone Sterowanie nadazne
{
pokaz(wsk);
}
if(SterowanieN==0)
{
zatrzymanieS1();
zatrzymanieS2();
}


//----------------------------------------------------------------------------
//Obsloga klawisza ***********************************************************
if (!(PINC &amp; przycisk_1)) //BACK
{
Pip();
wyswietlacz=0;
powitanie=0;

if(pozycja==0)
{
pozycja=0;
w1=0;
w2=0;
w3=0;
w4=0;
}
switch (pozycja)
{
case(1):
{
pozycja=0;
w1=0;
w2=0;
w3=0;
w4=0;
}
break;
case 2:
{
pozycja=1;
w2=0;
w3=0;
w4=0;
}
break;
case 3:
{
pozycja=2;
w3=0;
w4=0;
}
break;
case 4:
{
pozycja=3;
w4=0;
}
break;
}

LCD_CLEAR;
_delay_ms(80);
while(!(PINC &amp; przycisk_1)) {}
_delay_ms(80);
}
//----------------------------------------------------------------------------
//Obsloga klawisza &amp; lt; *********************************************************
if (!(PINC &amp; przycisk_2)) // &quot; &amp; lt; &quot;
{
Pip();
wyswietlacz=0;
powitanie=0;

switch(pozycja)
{
case 1:
{
w1-=1;
if(w1==0)
{
w1=4;
}
}
break;
case 2:
{
w2-=1;
if(w1==1 &amp; &amp; w2==0)
{
w2=2;
}
if(w1==2 &amp; &amp; w2==0)
{
w2=3;
}
if(w1==4 &amp; &amp; w2==0)
{
w2=3;
}
}
break;
case 3:
{
w3-=1;
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==0)
{
w3=3;
}
if(w1==1 &amp; &amp; w2==1 &amp; &amp; w3==0)
{
w3=1;
SterowanieN=0;
}
if(w1==4 &amp; &amp; w2==1 &amp; &amp; w3==0)
{
Buzer=0;
w3=1;
}
if(w1==4 &amp; &amp; w2==3 &amp; &amp; w3==0)
{
w3=1;
}
}
break;
case 4:
{
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==1 &amp; &amp; w4==1)
{
AlarmC1=0;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==2 &amp; &amp; w4==1)
{
AlarmC2=0;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==3 &amp; &amp; w4==1)
{
AlarmC1C2=0;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==1 &amp; &amp; w4==2)
{
PoziomC1-=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==2 &amp; &amp; w4==2)
{
PoziomC2-=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==3 &amp; &amp; w4==2)
{
PoziomC1C2-=1;
}
}
break;
}

if(pozycja==0)
{
pozycja=1;
w1=4;
w2=0;
w3=0;
w4=0;
}

LCD_CLEAR;
_delay_ms(80);
while(!(PINC &amp; przycisk_2)) {}
_delay_ms(80);
}
//----------------------------------------------------------------------------
//Obsloga klawisza &amp; gt; *********************************************************

if (!(PINC &amp; przycisk_3)) // &quot; &amp; gt; &quot;
{
Pip();
wyswietlacz=0;
powitanie=0;
switch(pozycja)
{
case 1:
{
if(w1==4 &amp; &amp; w2==0)
{
w1=1;
}
else
{
w1+=1;
}
}
break;
case 2:
{
w2+=1;

if(w1==1 &amp; &amp; w2==3)
{
w2=1;
}
if(w1==2 &amp; &amp; w2==4)
{
w2=1;
}
if(w1==4 &amp; &amp; w2==4)
{
w2=1;
}

}
break;
case 3:
{
w3+=1;
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==4)
{
w3=1;
}
if(w1==4 &amp; &amp; w2==3 &amp; &amp; w3==1)
{
w3=1;
}
if(w1==1 &amp; &amp; w2==1 &amp; &amp; w3==2)
{
w3=1;
SterowanieN=1;
}
if(w1==4 &amp; &amp; w2==1 &amp; &amp; w3==2)
{
Buzer=1;
w3=1;
}
if(w1==4 &amp; &amp; w2==3 &amp; &amp; w3==2)
{
w3=1;
}

}
break;
case 4:
{
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==1 &amp; &amp; w4==1)
{
AlarmC1=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==2 &amp; &amp; w4==1)
{
AlarmC2=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==3 &amp; &amp; w4==1)
{
AlarmC1C2=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==1 &amp; &amp; w4==2)
{
PoziomC1+=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==2 &amp; &amp; w4==2)
{
PoziomC2+=1;
}
if(w1==2 &amp; &amp; w2==3 &amp; &amp; w3==3 &amp; &amp; w4==2)
{
PoziomC1C2+=1;
}

}
break;

}

if(pozycja==0)
{
pozycja=1;
w1=1;
w2=0;
w3=0;
w4=0;
}

LCD_CLEAR;
_delay_ms(80);
while(!(PINC &amp; przycisk_3)) {}
_delay_ms(80);

}
//----------------------------------------------------------------------------
//Obsloga klawisza ENTER/CHANGE **********************************************

if (!(PINC &amp; przycisk_4)) // &quot; ENTER/CHANGE &quot;
{
Pip();
wyswietlacz=0;
powitanie=0;

switch(pozycja)
{

case 4:
{

if(w4==1)
{
w4=2;
}
else
{
w4=1;
}

}
break;

case 3:
{
if(w1==2 &amp; &amp; w2==3 &amp; &amp; (w3==1||w3==2||w3==3))
{
pozycja=4;
w4=1;
}

}
break;
case 2:
{
if(w1==1 &amp; &amp; w2==1)
{
pozycja=3;
w3=1;
w4=0;
}
if(w1==2 &amp; &amp; w2==3)
{
pozycja=3;
w3=1;
w4=0;
}
if(w1==4 &amp; &amp; w2==1)
{
pozycja=3;
w3=1;
}
if(w1==4 &amp; &amp; w2==3)
{
pozycja=3;
w3=1;
}
}
break;
case 1:
{
pozycja=2;
w2=1;
w3=0;
w4=0;

if(w1==3)
{
pozycja=1;
w1=3;
w2=0;
w3=0;
w4=0;

}

}
break;
case 0:
{
pozycja=1;
w1=1;
w2=0;
w3=0;
w4=0;
}
break;
}


LCD_CLEAR;
_delay_ms(80);
while(!(PINC &amp; przycisk_4)) {}
_delay_ms(80);
}
//----------------------------------------------------------------------------

//Zmiana formatu -wyswietlenie wartosci alarmow LCD

sprintf(PPoziomC1, &quot; %1.0f &quot; ,PoziomC1);
sprintf(PPoziomC2, &quot; %1.0f &quot; ,PoziomC2);
sprintf(PPoziomC1C2, &quot; %1.0f &quot; ,PoziomC1C2);


alokacja=(w1*1000)+(w2*100)+(w3*10)+w4;

MENU();

PORTD ^= 0x40;

wyswietlacz+=1;
if(wyswietlacz==2200)
{
wyswietlacz=2100;
}

powitanie+=1;
if(powitanie==3200)
{
powitanie=3100;
}

}

}
//Koniec program glowny-----------------------------------------------------------


GHS_nadazny.zip > ds18b20.c

/*
Plik ds18b20.c
(minimum kodu do odczytu temperatury z ds18b20)

xyz.isgreat.org
*/

#include &amp; lt; avr/io.h &amp; gt;
#include &amp; lt; util/delay.h &amp; gt;
#include &quot; ds18b20.h &quot;

//Funkcje czujnika 1
/**********************************************************/

unsigned char ds18b20_ConvertT1(void)
{
if (!OneWireReset1()) return 0;

OneWireWriteByte1(0xcc); // SKIP ROM
OneWireWriteByte1(0x44); // CONVERT T

return -1;
}

/***********************************************************/

int ds18b20_Read1(unsigned char scratchpad[])
{
unsigned char i;

if (!OneWireReset1()) return 0;

OneWireWriteByte1(0xcc); // SKIP ROM
OneWireWriteByte1(0xbe); // READ SCRATCHPAD

for(i=0; i &amp; lt; 10; i++) scratchpad[i] = OneWireReadByte1();

return 1;
}

/**********************************************************/

void OneWireStrong1(char s)
{
if (s)
{
SET_ONEWIRE_PORT1;
SET_OUT_ONEWIRE_DDR1;
}
else
{
SET_IN_ONEWIRE_DDR1;
}
}

/**********************************************************/

unsigned char OneWireReset1()
{
CLR_ONEWIRE_PORT1;

if (!(IS_SET_ONEWIRE_PIN1)) return 0;

SET_OUT_ONEWIRE_DDR1;
_delay_us(500);
SET_IN_ONEWIRE_DDR1;
_delay_us(70);

if(!(IS_SET_ONEWIRE_PIN1))
{
_delay_us(500);
return(1);
}

_delay_us(500);

return(0);
}

/**********************************************************/

void OneWireWriteByte1(unsigned char byte)
{
unsigned char i;

CLR_ONEWIRE_PORT1;

for (i=0; i &amp; lt; 8; i++)
{
SET_OUT_ONEWIRE_DDR1;

if (byte &amp; 0x01)
{
_delay_us(7);
SET_IN_ONEWIRE_DDR1;
_delay_us(70);
}
else
{
_delay_us(70);
SET_IN_ONEWIRE_DDR1;
_delay_us(7);
}

byte &amp; gt; &amp; gt; = 1;
}
}

/***********************************************************/

unsigned char OneWireReadByte1(void)
{
unsigned char i, byte = 0;

SET_IN_ONEWIRE_DDR1;

for (i=0; i &amp; lt; 8; i++)
{
SET_OUT_ONEWIRE_DDR1;
_delay_us(7);
SET_IN_ONEWIRE_DDR1;
_delay_us(7);
byte &amp; gt; &amp; gt; = 1;

if(IS_SET_ONEWIRE_PIN1) byte |= 0x80;

_delay_us(70);
}

return byte;
}

//Funkcje czujnika 2
/**********************************************************/

unsigned char ds18b20_ConvertT2(void)
{
if (!OneWireReset2()) return 0;

OneWireWriteByte2(0xcc); // SKIP ROM
OneWireWriteByte2(0x44); // CONVERT T

return -1;
}

/***********************************************************/

int ds18b20_Read2(unsigned char scratchpad[])
{
unsigned char i;

if (!OneWireReset2()) return 0;

OneWireWriteByte2(0xcc); // SKIP ROM
OneWireWriteByte2(0xbe); // READ SCRATCHPAD

for(i=0; i &amp; lt; 10; i++) scratchpad[i] = OneWireReadByte2();

return 1;
}

/**********************************************************/

void OneWireStrong2(char s)
{
if (s)
{
SET_ONEWIRE_PORT2;
SET_OUT_ONEWIRE_DDR2;
}
else
{
SET_IN_ONEWIRE_DDR2;
}
}

/**********************************************************/

unsigned char OneWireReset2()
{
CLR_ONEWIRE_PORT2;

if (!(IS_SET_ONEWIRE_PIN2)) return 0;

SET_OUT_ONEWIRE_DDR2;
_delay_us(500);
SET_IN_ONEWIRE_DDR2;
_delay_us(70);

if(!(IS_SET_ONEWIRE_PIN2))
{
_delay_us(500);
return(1);
}

_delay_us(500);

return(0);
}

/**********************************************************/

void OneWireWriteByte2(unsigned char byte)
{
unsigned char i;

CLR_ONEWIRE_PORT2;

for (i=0; i &amp; lt; 8; i++)
{
SET_OUT_ONEWIRE_DDR2;

if (byte &amp; 0x01)
{
_delay_us(7);
SET_IN_ONEWIRE_DDR2;
_delay_us(70);
}
else
{
_delay_us(70);
SET_IN_ONEWIRE_DDR2;
_delay_us(7);
}

byte &amp; gt; &amp; gt; = 1;
}
}

/***********************************************************/

unsigned char OneWireReadByte2(void)
{
unsigned char i, byte = 0;

SET_IN_ONEWIRE_DDR2;

for (i=0; i &amp; lt; 8; i++)
{
SET_OUT_ONEWIRE_DDR2;
_delay_us(7);
SET_IN_ONEWIRE_DDR2;
_delay_us(7);
byte &amp; gt; &amp; gt; = 1;

if(IS_SET_ONEWIRE_PIN2) byte |= 0x80;

_delay_us(70);
}

return byte;
}


GHS_nadazny.zip > pomiarv.h

/*
Plik pomiarv.h
*/

#ifndef pomiarV
#define pomiarV



char bufferC0[8]; //zmienna do konwersji wyniku
char bufferC1[8]; //zmienna do konwersji wyniku
char bufferC2[8]; //zmienna do konwersji wyniku
char bufferC3[8]; //zmienna do konwersji wyniku


float Voltage0[0]; // zmienna przechowuje wynik
float Voltage1[0]; // zmienna przechowuje wynik
float Voltage2[0]; // zmienna przechowuje wynik
float Voltage3[0]; // zmienna przechowuje wynik


char bufferV0[8]; //zmienna do konwersji wyniku
char bufferV1[8]; //zmienna do konwersji wyniku
char bufferV2[8]; //zmienna do konwersji wyniku
char bufferV3[8]; //zmienna do konwersji wyniku





#endif


GHS_nadazny.zip > ds18b20.h

/*
Plik ds18b20.h

(xyz.isgreat.org)
*/

#ifndef DS18B20_H
#define DS18B20_H

/* DS18B20 przy??czony do portu PA4 AVRa */
#define SET_ONEWIRE_PORT1 PORTA |= _BV(4)
#define CLR_ONEWIRE_PORT1 PORTA &amp; = ~_BV(4)
#define IS_SET_ONEWIRE_PIN1 PINA &amp; _BV(4)
#define SET_OUT_ONEWIRE_DDR1 DDRA |= _BV(4)
#define SET_IN_ONEWIRE_DDR1 DDRA &amp; = ~_BV(4)

unsigned char ds18b20_ConvertT1(void);
int ds18b20_Read1(unsigned char []);
void OneWireStrong1(char);
unsigned char OneWireReset1(void);
void OneWireWriteByte1(unsigned char);
unsigned char OneWireReadByte1(void);

/* DS18B20 przy??czony do portu PA5 AVRa */
#define SET_ONEWIRE_PORT2 PORTA |= _BV(5)
#define CLR_ONEWIRE_PORT2 PORTA &amp; = ~_BV(5)
#define IS_SET_ONEWIRE_PIN2 PINA &amp; _BV(5)
#define SET_OUT_ONEWIRE_DDR2 DDRA |= _BV(5)
#define SET_IN_ONEWIRE_DDR2 DDRA &amp; = ~_BV(5)

unsigned char ds18b20_ConvertT2(void);
int ds18b20_Read2(unsigned char []);
void OneWireStrong2(char);
unsigned char OneWireReset2(void);
void OneWireWriteByte2(unsigned char);
unsigned char OneWireReadByte2(void);

#endif


GHS_nadazny.zip > hd44780.h

/*
Plik hd44780.h
*/

#ifndef LCD_HD44780
#define LCD_HD44780

/* RS */
#define SET_OUT_LCD_RS DDRB |= _BV(PB0)
#define SET_LCD_RS PORTB |= _BV(PB0)
#define CLR_LCD_RS PORTB &amp; = ~_BV(PB0)

/* RW */
#define SET_OUT_LCD_RW DDRB |= _BV(PB1)
#define SET_LCD_RW PORTB |= _BV(PB1)
#define CLR_LCD_RW PORTB &amp; = ~_BV(PB1)

/* E */
#define SET_OUT_LCD_E DDRB |= _BV(PB2)
#define SET_LCD_E PORTB |= _BV(PB2)
#define CLR_LCD_E PORTB &amp; = ~_BV(PB2)

/* D4 */
#define SET_OUT_LCD_D4 DDRB |= _BV(PB4)
#define SET_IN_LCD_D4 DDRB &amp; = ~_BV(PB4)
#define SET_LCD_D4 PORTB |= _BV(PB4)
#define CLR_LCD_D4 PORTB &amp; = ~_BV(PB4)
#define IS_SET_LCD_D4 PINB &amp; _BV(PB4)

/* D5 */
#define SET_OUT_LCD_D5 DDRB |= _BV(PB5)
#define SET_IN_LCD_D5 DDRB &amp; = ~_BV(PB5)
#define SET_LCD_D5 PORTB |= _BV(PB5)
#define CLR_LCD_D5 PORTB &amp; = ~_BV(PB5)
#define IS_SET_LCD_D5 PINB &amp; _BV(PB5)

/* D6 */
#define SET_OUT_LCD_D6 DDRB |= _BV(PB6)
#define SET_IN_LCD_D6 DDRB &amp; = ~_BV(PB6)
#define SET_LCD_D6 PORTB |= _BV(PB6)
#define CLR_LCD_D6 PORTB &amp; = ~_BV(PB6)
#define IS_SET_LCD_D6 PINB &amp; _BV(PB6)

/* D7 */
#define SET_OUT_LCD_D7 DDRB |= _BV(PB7)
#define SET_IN_LCD_D7 DDRB &amp; = ~_BV(PB7)
#define SET_LCD_D7 PORTB |= _BV(PB7)
#define CLR_LCD_D7 PORTB &amp; = ~_BV(PB7)
#define IS_SET_LCD_D7 PINB &amp; _BV(PB7)


#define LCD_NOP asm volatile( &quot; nop\n\t &quot; &quot; nop\n\t &quot; &quot; nop\n\t &quot; &quot; nop\n\t &quot; ::);



#define LCDCOMMAND 0
#define LCDDATA 1

#define LCD_LOCATE(x,y) WriteToLCD(0x80|((x)+((y)*0x40)), LCDCOMMAND) //kolumna , wiersz

#define LCD_CLEAR WriteToLCD(0x01, LCDCOMMAND)
#define LCD_HOME WriteToLCD(0x02, LCDCOMMAND)

/* IDS */

#define LCDINCREMENT 0x02
#define LCDDECREMENT 0x00
#define LCDDISPLAYSHIFT 0x01

#define LCD_ENTRY_MODE(IDS) WriteToLCD(0x04|(IDS), LCDCOMMAND)

/* BCD */
#define LCDDISPLAY 0x04
#define LCDCURSOR 0x02
#define LCDBLINK 0x01

#define LCD_DISPLAY(DCB) WriteToLCD(0x08|(DCB), LCDCOMMAND)

/* RL */
#define LCDLEFT 0x00
#define LCDRIGHT 0x04

#define LCD_SHIFT_DISPLAY(RL) WriteToLCD(0x18|(RL), LCDCOMMAND)
#define LCD_SHIFT_CURSOR(RL) WriteToLCD(0x10|(RL), LCDCOMMAND)

#define LCD_CGRAM_ADDRESS(A) WriteToLCD(0x40|((A) &amp; 0x3f), LCDCOMMAND)
#define LCD_DDRAM_ADDRESS(A) WriteToLCD(0x80|((A) &amp; 0x7f), LCDCOMMAND)

#define LCD_WRITE_DATA(D) WriteToLCD((D),LCDDATA)


void lcd_init(void);
void WriteToLCD(unsigned char v,unsigned char rs);
unsigned char ReadAddressLCD(void);
void lcd_puts(char *str);

#endif


TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo