Witam
Wczoraj popracowałem przy starym sterowniku, w celu zabudowy nowego transformatora, przesunąłem płytkę sterującą, przy okazji znalazłem uszkodzony przewód do sterowania przetwornicami LED.
Musiałem też wymienić 2 szt. białych XPG, bo padły po kilku miesiącach, jedna chyba po dwóch. Jeden szereg zmieniłem na 4 szt. SST-40 6500K, pozyskane sprawne poszły w miejsce uszkodzonych.
Wyświetlacz już się kończy, wyregulowałem kontrast, ale niewiele to dało, docelowo trzeba by go wymienić.
W nowym projekcie, żmudna dłubanina. Po całym dniu dzisiejszym, mam zrobione rozjaśnianie i ściemnianie oświetlenia i płynną zmianę temperatury (rano - wieczór). Tu napisałem kilka warunków rozróżniających stany. Jeśli trwa rozjaśnianie lub ściemnianie (lub zmiana temperatury) to mamy pół słoneczka, jeśli proces dobiegnie końca, to następuje zmiana na całe słoneczko (żółte) lub księżyc (biały).
Napisałem obsługę EEPromu, ustalanie adresów, konwersja liczb na bajty itp. Trochę było roboty.
Zmieniłem koncepcję obliczeń, zmienne float (zmiennoprzecinkowe) zamieniam na word (2 bajty) poprzez mnożenie przez 100. Dopiero na tych danych dokonuję obliczeń.
Czas też zmieniam, bajt godzin i minut łączę w jedną liczbę i tak porównuję w celu rozpoznania dnia i nocy.
PID niestety nie daje pełnej temperatury, lecz stabilizuje około 0,05 poniżej zadanej. Może się trochę poprawi, gdy wydłużę interwał pomiarowy co da możliwość zwiększenia dokładności regulacji. Teraz jest około 7s, docelowo chciałbym osiągnąć jakieś 5 - 10 minut, dostosowując do bezwładności ośrodka. Aktualnie mam 8 jednostek czasu, a celuję w 256 - 500.
Niestety nie do końca zrozumiałem zasadę wyświetlania znaków, i miałem kłopoty z zamazywaniem poprzedniej ikonki (słoneczko). Dodanie spacji nic nie dawało, bo zamazywała się np. połowa znaku. Docelowo najpierw zamazuję spacjami, potem dopiero drukuję. Nowy znak wyświetla się tylko jeśli nastąpiła zmiana. Ikonki wyświetlane są stabilniej, ale doszły kolejne warunki.
Zostało mi jeszcze 7kB na menu, jak mi zabraknie pamięci, to będę kombinował ze zmniejszeniem kodu.
Aktualnie:
"Szkic używa 23676 bajtów (77%) pamięci programu. Maksimum to 30720 bajtów.
Zmienne globalne używają 691 bajtów (33%) pamięci dynamicznej, pozostawiając 1357 bajtów dla zmiennych lokalnych. Maksimum to 2048 bajtów."
Pozdrawiam
Oświetlenie Akwarium
Re: Oświetlenie Akwarium
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Re: Oświetlenie Akwarium
Witam
Ostatnie prace, posunęły projekt o kilka rzeczy.
Najważniejsze, to zostało zrobione sterowanie oświetleniem. Przyjąłem dwa warianty, które mogą być stosowane osobno lub łącznie
Przy przejściu porannym, oświetlenie zmienia się od minimum do pełnej jasności. Po osiągnięciu pełnej jasności, załącza się dodatkowy przekaźnik, którym można załączać dodatkowe oświetlenie w postaci żarówek czy świetlówek, lub zespołu lamp LED na 230V. Czas rozjaśniania (i ściemniania) to około 30 minut. Aktualnie jest ustawiona opcja "oświetlenia nocnego", jak poczuję potrzebę to jeszcze dołączę możliwość zmiany tego parametru w menu.
Przy przejściu wieczornym, najpierw gaśnie oświetlenie dodatkowe, a potem zaczyna się ściemnianie LED.
W obu przypadkach, wartość PWM jest zwiększana lub zmniejszana w zakresie od 2 do 128, pomiędzy 128 a 255, następuje jednorazowy przeskok.
Jeśli chodzi o regulację jasności PWM, to szczególnie przy minimum, następują przeskoki jasności, chcę to wyeliminować przez zastosowanie układu RC o bardzo długim czasie, który będzie łagodził przejścia. Szczególnie jest to widoczne na pierwszych 4-ch poziomach jasności. Tu jeszcze chyba dobuduję jedną opcję, wyjście Enable do ewentualnych przetwornic zasilających LED.
Pomiar i wyświetlenie temperatury następuje co minutę, natomiast cykl termostatu, został wydłużony do 5 minut, i dało mi to rozdzielczość czasów załączenia grzałki na poziomie 25, mam nadzieję, że to wystarczy. Zasadniczo, mogę cykl wydłużyć nawet do 10 minut, i wtedy rozdzielczość wzrośnie do 50.
Zrobiłem też menu, które umożliwia zmianę nastaw czasu rozpoczęcia cyklu dnia oraz nocy, niestety, nie zrobiłem sprawdzania, czy rano < wieczór, ale zostawiam to inteligencji obsługującego. Dalej mam możliwość zmiany temperatury dnia i nocy. Zmiany dokonywane są osobno dla godzin i minut (osobna pozycja menu) ale wyświetlam pełny czas w formacie hh:mm.
Zastanawiam się czy zrobić możliwość zmiany czasu, na razie z tego zrezygnowałem w związku z bardzo dużą precyzją zegara. Zasadniczą jego rolą jest ustalanie punktu przełączenia dnia i nocy, a nie wskazywanie dokładnego czasu. Przyroda w końcu też nie zna zmiany czasu z zimowego na letni itp.
Temperaturę mierzę i przeliczam z rozdzielczością 0,01°C, natomiast wyświetlam i ustawiam z precyzją 0,1°C. Temperaturę zmieniam "na raz" w zakresie od 18°C do 35°C
Proces zmian parametrów niestety zatrzymuje wyświetlanie zegara, jednak samo menu już nie. Dodatkowo zrobiłem zabezpieczenie, które przy braku reakcji w ciągu 10s, powoduje automatyczne opuszczenie menu.
Zostało mi jeszcze 4kB pamięci, więc ewentualne modyfikacje jeszcze są możliwe.
Pozdrawiam
Ostatnie prace, posunęły projekt o kilka rzeczy.
Najważniejsze, to zostało zrobione sterowanie oświetleniem. Przyjąłem dwa warianty, które mogą być stosowane osobno lub łącznie
Przy przejściu porannym, oświetlenie zmienia się od minimum do pełnej jasności. Po osiągnięciu pełnej jasności, załącza się dodatkowy przekaźnik, którym można załączać dodatkowe oświetlenie w postaci żarówek czy świetlówek, lub zespołu lamp LED na 230V. Czas rozjaśniania (i ściemniania) to około 30 minut. Aktualnie jest ustawiona opcja "oświetlenia nocnego", jak poczuję potrzebę to jeszcze dołączę możliwość zmiany tego parametru w menu.
Przy przejściu wieczornym, najpierw gaśnie oświetlenie dodatkowe, a potem zaczyna się ściemnianie LED.
W obu przypadkach, wartość PWM jest zwiększana lub zmniejszana w zakresie od 2 do 128, pomiędzy 128 a 255, następuje jednorazowy przeskok.
Jeśli chodzi o regulację jasności PWM, to szczególnie przy minimum, następują przeskoki jasności, chcę to wyeliminować przez zastosowanie układu RC o bardzo długim czasie, który będzie łagodził przejścia. Szczególnie jest to widoczne na pierwszych 4-ch poziomach jasności. Tu jeszcze chyba dobuduję jedną opcję, wyjście Enable do ewentualnych przetwornic zasilających LED.
Pomiar i wyświetlenie temperatury następuje co minutę, natomiast cykl termostatu, został wydłużony do 5 minut, i dało mi to rozdzielczość czasów załączenia grzałki na poziomie 25, mam nadzieję, że to wystarczy. Zasadniczo, mogę cykl wydłużyć nawet do 10 minut, i wtedy rozdzielczość wzrośnie do 50.
Zrobiłem też menu, które umożliwia zmianę nastaw czasu rozpoczęcia cyklu dnia oraz nocy, niestety, nie zrobiłem sprawdzania, czy rano < wieczór, ale zostawiam to inteligencji obsługującego. Dalej mam możliwość zmiany temperatury dnia i nocy. Zmiany dokonywane są osobno dla godzin i minut (osobna pozycja menu) ale wyświetlam pełny czas w formacie hh:mm.
Zastanawiam się czy zrobić możliwość zmiany czasu, na razie z tego zrezygnowałem w związku z bardzo dużą precyzją zegara. Zasadniczą jego rolą jest ustalanie punktu przełączenia dnia i nocy, a nie wskazywanie dokładnego czasu. Przyroda w końcu też nie zna zmiany czasu z zimowego na letni itp.
Temperaturę mierzę i przeliczam z rozdzielczością 0,01°C, natomiast wyświetlam i ustawiam z precyzją 0,1°C. Temperaturę zmieniam "na raz" w zakresie od 18°C do 35°C
Proces zmian parametrów niestety zatrzymuje wyświetlanie zegara, jednak samo menu już nie. Dodatkowo zrobiłem zabezpieczenie, które przy braku reakcji w ciągu 10s, powoduje automatyczne opuszczenie menu.
Zostało mi jeszcze 4kB pamięci, więc ewentualne modyfikacje jeszcze są możliwe.
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Re: Oświetlenie Akwarium
Witam
Jako że ma być regulacja jasności LED, ale dużej mocy na oświetlenie nie przewiduję, będzie to niecały metr taśmy 12V zasilanej 11V, więc postanowiłem zrobić regulator analogowy. Jako element wykonawczy będzie pracował LM317 / LM350.
Jak widać układ jest bardzo prosty, a co za tym idzie, powinien być bardzo niezawodny.
Na wyjściu otrzymujemy napięcia z zakresu 7,5V - 11V, czyli światło księżyca, oraz słoneczko, chociaż bez szaleństw, dodatkowo przecież będzie światło dzienne. Dodatkowe światło, jednak przydaje się ze względu na obserwację wnętrza, oraz sam proces rozjaśniania i ściemniania.
Jeśli chodzi o wersję pełnego oświetlenia LED, będą to standardowe przetwornice sterowane napięciem, analogicznie jak w pierwotnym projekcie.
Wejście sygnału PWM z procesora, jest tu przedstawione jako napięcie V2. Kondensator jest tu w celu przefiltrowania sygnału PWM, i wygładzenia do napięcia stałego. Układ jest tak obliczony, że przy pełnym napięciu, w zasadzie działa na rezystorach, Napięcie uzyskane z PWM, jest zbliżone do normalnego napięcia panującego w punkcie przyłączenia, czyli u zbiegu rezystorów R2, R3 i R5.
Pozdrawiam
Jako że ma być regulacja jasności LED, ale dużej mocy na oświetlenie nie przewiduję, będzie to niecały metr taśmy 12V zasilanej 11V, więc postanowiłem zrobić regulator analogowy. Jako element wykonawczy będzie pracował LM317 / LM350.
Jak widać układ jest bardzo prosty, a co za tym idzie, powinien być bardzo niezawodny.
Na wyjściu otrzymujemy napięcia z zakresu 7,5V - 11V, czyli światło księżyca, oraz słoneczko, chociaż bez szaleństw, dodatkowo przecież będzie światło dzienne. Dodatkowe światło, jednak przydaje się ze względu na obserwację wnętrza, oraz sam proces rozjaśniania i ściemniania.
Jeśli chodzi o wersję pełnego oświetlenia LED, będą to standardowe przetwornice sterowane napięciem, analogicznie jak w pierwotnym projekcie.
Wejście sygnału PWM z procesora, jest tu przedstawione jako napięcie V2. Kondensator jest tu w celu przefiltrowania sygnału PWM, i wygładzenia do napięcia stałego. Układ jest tak obliczony, że przy pełnym napięciu, w zasadzie działa na rezystorach, Napięcie uzyskane z PWM, jest zbliżone do normalnego napięcia panującego w punkcie przyłączenia, czyli u zbiegu rezystorów R2, R3 i R5.
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Re: Oświetlenie Akwarium
Witam
Po pewnym czasie eksploatacji oraz kilku poprawkach baboli, kod uzyskał już działającą postać.
Gdyby ktoś miał ochotę, to wklejam całość.
Przy pierwszym uruchomieniu programu, należy zająć się poniższym fragmentem:
Tutaj należy "odkomentować" wszystkie linie, a następnie przy deklaracji zmiennych, wpisać wartości starowe. Po zapisaniu w eepromie, trzeba przywrócić pierwotny stan programu, gdyż wszystkie dane już będą zapamiętane.
Wyjaśnienia wymagają ostatnie trzy linijki:
//clock.setDateTime(__DATE__, __TIME__); //ustaw czas pobrany z serwaera
Ustawia czas ściągnięty z komputera. Niestety, dostajemy wtedy opóźnienie zegara o czas wgrywania programu.
// Manual (Year, Month, Day, Hour, Minute, Second) //ustawienia zegara
//clock.setDateTime(2014, 4, 25, 0, 0, 0);[/code]
Natomiast ten fragment, umożliwia ręczne ustawienie czasu, te dwa sposoby, należy traktować alternatywnie.
Nie zrobiłem ustawiania czasu, gdyż wyszedłem z założenia, że zwierząt nie obowiązują zmiany zima/lato, a niedokładność zegara wynosząca kilka minut w skali roku, jest w tym zstaosowaniu do pominięcia. Jeśli ktoś chce mieć możliwość ręcznego ustawienia czasu, może sobie dopisać odpowiedni fragment w menu.
Mała poprawka dostyczy też układu regulacji jasności taśmy LED, rezystor R2 ma teraz wartość 2k2, co dało zakłądany zakres regulacji jasności.
Pozdrawiam
Po pewnym czasie eksploatacji oraz kilku poprawkach baboli, kod uzyskał już działającą postać.
Gdyby ktoś miał ochotę, to wklejam całość.
Kod: Zaznacz cały
//#define ILI9341_BLACK 0x0000 /* 0, 0, 0 */
//#define ILI9341_NAVY 0x000F /* 0, 0, 128 */
//#define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */
//#define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */
//#define ILI9341_MAROON 0x7800 /* 128, 0, 0 */
//#define ILI9341_PURPLE 0x780F /* 128, 0, 128 */
//#define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */
//#define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */
//#define ILI9341_GREY 0x7BEF
//#define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */
//#define ILI9341_BLUE 0x001F /* 0, 0, 255 */
//#define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */
//#define ILI9341_CYAN 0x07FF /* 0, 255, 255 */
//#define ILI9341_RED 0xF800 /* 255, 0, 0 */
//#define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */
//#define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */
//#define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */
//#define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */
//#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
//#define ILI9341_PINK 0xF81F
#include <Wire.h>
#include <EEPROM.h>
#include <SHT2x.h>
#include <DS3231.h>
#include "SPI.h"
#include "Adafruit_GFX_AS.h"
#include "Adafruit_ILI9341_AS.h"
DS3231 clock;
RTCDateTime dt;
#define sclk 13 // Nie zmieniać
#define miso 12
#define mosi 11 // Nie zmieniać
#define cs 10
#define dc 9
#define rst 8 // można podłączyć do resetu arduino
#define adrdzien 0 //adres eepromu z zawartością godziny rozpoczęcia dnia: 0 > hh, 1 > mm
#define adrnoc 2 //adres nocy 2 > hh, 3 > mm
#define adrtempdzien 4 //adres temperatury w dzień: 4 starszy bajt, 5 młodszy bajt
#define adrtempnoc 6 //adres temperatury w nocy
#define grzalka 7 //wyjście grzałki
#define UP 2 // przycisk UP na Pin 3
#define OK 3 // przycisk OK na pinie 4
#define DOWN 4 // przycisk DOWN na pinie 5
#define PWMLED 5 //wyjście na sterowanie oświetleniem PWM
#define zarowka 6 //wyjście na żarówkę
Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(cs, dc, rst); //Deklaracja biblioteki wyświetlacza
unsigned long start = micros(); //licznik czasu pętli
float temperature = 0; //temperatura zmierzona
word temperatura = 0; //przekonwertowana temeratura ze zmiennoprzecinkowej na całkowitą, float x 100
word termostat = 5; //temperatura aktualna termostatu, po zmianie dąży do docelowej co 1
word termostata = 0; //temperatura docelowa dnia lub nocy
byte hhdzien = 8; //godzina rozpoczęcia dnia
byte mmdzien = 0; //minuta rozpoczęcia dnia
byte hhnoc = 20; //godzina rozpoczęcia końca dnia
byte mmnoc = 0; //minuta rozpoczecia nocy
byte poradoby = 0; //pora doby dzień = 1, rano lub wieczór =2, noc = 3
word licznik = 0; //liczenie czasu w pętli pomiarów
byte licznikLED = 0; //liczenie czasu rozjaśniania LEDów
byte liczniktemp = 0; //licznik czasu zmiany temperatury
word tsr = 0; //zmienna zawierająca sumę 10 pomiarów
byte oldss = 0; //poprzednie sekundy
byte LEDDN = 0; //jasność docelowa LED
byte LED = 0; //jasność światła LED
int ep; //uchyb poprzedni
int en; //uchyb następny
int U; //sygnał sterujący
int C; //część całkująca
byte menu = 0;
byte submenu = 0;
void setup() {
licznik = 500; //500 = 5 minut
licznikLED = 25; //25 = 15s
liczniktemp = 100; //200 = 1 minuty
Wire.begin();
clock.begin();
Serial.begin(9600);
pinMode(grzalka, OUTPUT); //grzałka
pinMode(PWMLED, OUTPUT); //wyjście LED
pinMode(zarowka, OUTPUT); //wyjście na sterowanie oświetleniem klasycznym
pinMode(DOWN,INPUT_PULLUP); // konfiguracja pinów dla przycisków
pinMode(UP,INPUT_PULLUP); // konfiguracja pinów dla przycisków
pinMode(OK,INPUT_PULLUP); // konfiguracja pinów dla przycisków
tft.init();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(1);
tft.drawString("Termostat - akwarium",40,0,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawString("Temp. Wilg.",40,30,4);
tft.drawString("Czas",20,170,4);
tft.drawString("Menu",20,210,4);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
tft.drawString("|",280,60,4);
tft.drawString("*",125,60,4); //st. C
pomiartemp();
tsr = temperature * 900;
temperature = temperature *10;
termostat = temperature; //przyjęcie zmierzonej temperatury, jako aktualną termostatu by dążyć do docelowej
termostat = termostat *10;
termostat = termostat + 5; //zaokrąglenie ostatniej cyfry do 5
//EEPROM.update(adrdzien,hhdzien);
//EEPROM.update((adrdzien+1),mmdzien);
//EEPROM.update(adrnoc,hhnoc);
//EEPROM.update((adrnoc+1),mmnoc);
// byte pomocnicza = 0;
// pomocnicza = termostat;
//EEPROM.update((adrtempdzien +1),pomocnicza);
//pomocnicza = termostat>>8;
//EEPROM.update(adrtempdzien,pomocnicza);
// pomocnicza = termostat;
//EEPROM.update((adrtempnoc +1),pomocnicza);
//pomocnicza = termostat>>8;
//EEPROM.update(adrtempnoc,pomocnicza);
//clock.setDateTime(__DATE__, __TIME__); //ustaw czas pobrany z serwaera
// Manual (Year, Month, Day, Hour, Minute, Second) //ustawienia zegara
//clock.setDateTime(2014, 4, 25, 0, 0, 0);
//termostata = (odczyteeprom(adrtempdzien)<<8) + odczyteeprom (adrtempdzien +1);
hhdzien = odczyteeprom(adrdzien);
mmdzien = odczyteeprom(adrdzien + 1);
hhnoc = odczyteeprom(adrnoc);
mmnoc = odczyteeprom(adrnoc + 1);
}
void loop(void) {
if(digitalRead(OK)==LOW){delay(40); if(digitalRead(OK)==LOW){delay(200); if (menu == 0) menu = 1;}} // jeśli OK
ustaw();
tft.setTextSize(2);
// tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
word dzien;
word noc;
word czas;
byte nowadoba = 0;
dt = clock.getDateTime(); //pobranie czasu z zegara
byte hh = dt.hour;
byte mm = dt.minute;
byte ss = dt.second;
czas = (hh << 8) + mm; //przeliczanie godzin i minut na jedną liczbę
dzien = (hhdzien << 8) + mmdzien;
noc = (hhnoc << 8) + mmnoc;
if (czas >= dzien && czas <= noc) { //rozpoznanie pory doby dla wyświetlenia ikony
nowadoba = 1;
termostata = (odczyteeprom(adrtempdzien)<<8) + odczyteeprom (adrtempdzien +1);
LEDDN = 255;
}
else {
nowadoba = 3;
termostata = (odczyteeprom(adrtempnoc)<<8) + odczyteeprom (adrtempnoc +1);
LEDDN = 2;
}
if (termostat != termostata) nowadoba = 2; //Jeśli temperatura aktualna i docelowa są różne to jest wieczór lub poranek
if (nowadoba != poradoby){ //Jeśli nastąpiła zmiana pory doby to wyświetl nowy symbol
poradnia(nowadoba);
poradoby = nowadoba;
}
if (oldss != ss){ //Nowa sekunda to wyświetl czas
oldss = ss;
zegar(hh,mm,ss);
}
if (liczniktemp == 200){ //cykl zmian temperatury 0,1C na 2 minuty
liczniktemp = 0;
if (termostata > termostat) termostat = termostat + 10;
if (termostata < termostat) termostat = termostat - 10;
}
if (licznik == 500){ //cykl grzania 5 minut
licznik = 0;
pomiartemp();
grzanie(); //Termostat obliczanie PID
}
if (licznikLED == 25){ //cykl zmiany jasności 15s
licznikLED = 0;
if (LED < LEDDN) {LED++; if (LED > 127) LED = LEDDN;} //rozjaśnianie LED
if (LED > LEDDN) {LED--; if (LED > 129) LED = 129;} //ściemnianie LED
if (LED == 255) digitalWrite(zarowka,HIGH); //załączenie żarówki
if (nowadoba == 3)digitalWrite(zarowka,LOW); //wyłaczenie żarówki
analogWrite(PWMLED,LED); //ustawienie jasności LED
pomiartemp();
temp(mm,ss); //wyświetlanie temperatury i wilgotności
}
if (licznik < U) { //Obsługa grzałki
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.drawString(")",70,110,4); //grzałka włączona
digitalWrite(grzalka,HIGH);
}
else {
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
tft.drawString(")",70,110,4); //grzałka wyłączona
digitalWrite(grzalka,LOW);
}
if ((millis() - start) > 600){ //600 to 0,6s
licznik ++;
licznikLED++;
liczniktemp++;
start = millis();
}
}
void nastawaczasu(byte adres, byte zakres){
byte dane;
byte godz;
byte minuty;
byte nowe = 255;
unsigned long czas;
czas = millis();
godz = odczyteeprom(adres);
minuty = odczyteeprom(adres + 1);
while (true){
byte xpos = 180;
byte ypos = 210;
if (zakres == 23) {dane = godz;}
else {dane = minuty;}
tft.setTextSize(1);
tft.setTextColor(ILI9341_GREEN,ILI9341_BLACK);
if (nowe != dane){
if (godz < 10) xpos+= tft.drawChar('0',xpos,ypos,4);
xpos+= tft.drawNumber(godz,xpos,ypos,4);
xpos+= tft.drawChar(':',xpos,ypos,4);
if (minuty<10) xpos+= tft.drawChar('0',xpos,ypos,4);
xpos+=tft.drawNumber(minuty,xpos,ypos,4);
nowe = dane;
}
if(digitalRead(UP)==LOW){delay(40);if(digitalRead(UP)==LOW) {delay(200); dane++; czas = millis(); if (dane > zakres) {dane = 0;}}} // jeśli UP
if(digitalRead(DOWN)==LOW){delay(40);if(digitalRead(DOWN)==LOW) {delay(200); czas = millis(); if (dane == 0) {dane = zakres + 1;}dane--;}} // jeśli DOWN
if(digitalRead(OK)==LOW){delay(40); if(digitalRead(OK)==LOW){delay(200); zapiszczas(adres,godz,minuty); break;}} // wejście submenu
if (zakres == 23) {godz = dane;}
else {minuty = dane;}
if (millis() - czas > 10000) {tft.drawString(" ",180,210,4); submenu = 0; break;}
dt = clock.getDateTime(); //pobranie czasu z zegara
byte hh = dt.hour;
byte mm = dt.minute;
byte ss = dt.second;
if (oldss != ss){
oldss = ss;
zegar(hh,mm,ss);
}
}
}
void zapiszczas(byte adres, byte godz, byte minuty){
tft.drawString("OK ",180,210,4);
EEPROM.update(adres,godz);
EEPROM.update((adres+1),minuty);
if (adres == adrdzien){hhdzien = godz; mmdzien = minuty;}
else {hhnoc = godz; mmnoc = minuty;}
delay(1000);
tft.drawString(" ",180,210,4);
submenu = 0;
}
void nastawatemp(byte adres){
word dane;
word nowe = 0;
float temp = 0;
unsigned long czas;
czas = millis();
dane = (odczyteeprom(adres)<<8) + odczyteeprom (adres +1); //odczyt temperatury do ustawienia
// dane = 2555;
while (true){
temp = dane;
temp = temp / 100; //przeliczenie temperatury na liczbę zmiennoprzecinkową do wyświetlenia
tft.setTextSize(1);
tft.setTextColor(ILI9341_GREEN,ILI9341_BLACK);
if (nowe != dane) {tft.drawFloat(temp,2,180,210,4); tft.drawString("*",250,210,4); nowe = dane;}
if(digitalRead(UP)==LOW){delay(40);if(digitalRead(UP)==LOW) {delay(200); if (dane < 3495) dane = dane + 10;czas = millis();}} // jeśli UP
if(digitalRead(DOWN)==LOW){delay(40);if(digitalRead(DOWN)==LOW) {delay(200); if (dane > 1815) dane = dane - 10;czas = millis();}} // jeśli DOWN
if(digitalRead(OK)==LOW){delay(40); if(digitalRead(OK)==LOW){delay(200);zapisztemp(adres,dane); break;}} // wejście submenu
if (millis() - czas > 10000) {tft.drawString(" ",180,210,4); submenu = 0; break;}
dt = clock.getDateTime(); //pobranie czasu z zegara
byte hh = dt.hour;
byte mm = dt.minute;
byte ss = dt.second;
if (oldss != ss){
oldss = ss;
zegar(hh,mm,ss);
}
}
}
void zapisztemp(byte adres, word dane){
tft.drawString("OK ",180,210,4);
byte pomocnicza = 0;
pomocnicza = dane;
EEPROM.update((adres +1),pomocnicza);
pomocnicza = dane>>8;
EEPROM.update(adres,pomocnicza);
delay(1000);
tft.drawString(" ",180,210,4);
submenu = 0;
}
void ustaw(){
tft.setTextSize(1);
tft.setTextColor(ILI9341_GREEN,ILI9341_BLACK);
if (menu >0){
if(digitalRead(UP)==LOW){delay(40);if(digitalRead(UP)==LOW) {delay(200); menu++; submenu = 0; if (menu > 7) menu = 1;}} // jeśli UP
if(digitalRead(DOWN)==LOW){delay(40);if(digitalRead(DOWN)==LOW) {delay(200); menu--; submenu = 0; if (menu < 1) menu = 7;}} // jeśli DOWN
if(digitalRead(OK)==LOW){delay(40); if(digitalRead(OK)==LOW){delay(200);if (submenu == 1) {submenu = 2;}}} // wejście submenu
}
switch(menu){
case 0:
break;
case 1:
if (submenu == 0) {tft.drawString("<<< ",100,210,4); submenu = 1;}
if(digitalRead(OK)==LOW){delay(40); if(digitalRead(OK)==LOW){menu = 0; submenu = 0; tft.drawString(" ",100,210,4);delay(200); }} // Powrót z menu
break;
case 2:
if (submenu == 0) {tft.drawString("D-h ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawaczasu(adrdzien, 23);} // wejście submenu
break;
case 3:
if (submenu == 0) {tft.drawString("D-m ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawaczasu(adrdzien, 59);} // wejście submenu
break;
case 4:
if (submenu == 0) {tft.drawString("N-h ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawaczasu(adrnoc, 23);} // wejście submenu
break;
case 5:
if (submenu == 0) {tft.drawString("N-m ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawaczasu(adrnoc, 59);} // wejście submenu
break;
case 6:
if (submenu == 0) {tft.drawString("TeD ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawatemp(adrtempdzien);} // wejście submenu
break;
case 7:
if (submenu == 0) {tft.drawString("TeN ",100,210,4); submenu = 1;}
if(submenu == 2){delay(200);nastawatemp(adrtempnoc);} // wejście submenu
break;
}
tft.drawString(" ",170,210,4);
}
void poradnia(byte symbol){
tft.drawString(" ",200,110,4);
switch (symbol){
case 1: //słońce
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.drawString("!",190,110,4); //pół słońca - ' 39; słońce - ! 33; księżyc - ( 40
break;
case 2: //pół słońca
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.drawString("'",190,110,4);
break;
case 3: //księżyc
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawString("(",190,110,4);
break;
}
}
byte odczyteeprom(byte adres){
return EEPROM.read(adres);
}
void zapiseeprom(byte adres,byte dane){
EEPROM.update(adres,dane);
}
void pomiartemp(){
temperature = SHT2x.GetTemperature();
temperatura = temperature * 100;
}
void temp(byte mm, byte ss){
tsr = tsr + temperatura;
temperatura = tsr /10;
tsr = tsr - temperatura;
temperature = temperatura;
temperature = temperature / 100;
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
tft.drawFloat(temperature,1,20,60,4);
tft.drawFloat(SHT2x.GetHumidity(),0,220,60,4);
}
void grzanie(){ //procedura termostatu
byte dt = 30; //co ile pobiera się próbkę
byte Kp = 20; //wzmocnienie
byte Ti = 30; //stała całkowania
byte Td = 40; //stała różniczkowania
en = (termostat - temperatura);
C += ((ep + en)/2)*dt;
U = Kp*(en + (1/Ti)*C + Td*(en - ep)/dt);
ep = en;
if (U < 0) U = 0;
if (U > 500) U = 500;
Serial.print(" LED ");
Serial.print(LED);
Serial.print(" termostat " );
Serial.print(termostat);
Serial.print(" temperatura " );
Serial.print(temperatura);
Serial.print(" temp = ");
Serial.print(temperature);
Serial.print(" en = ");
Serial.print(en);
Serial.print(" ep = ");
Serial.print(ep);
Serial.print(" C = ");
Serial.print(C);
Serial.print(" U =" );
Serial.println(U);
}
void zegar(byte hh, byte mm, byte ss){
byte xpos = 85;
byte ypos = 155;
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
if (hh<10) xpos+= tft.drawChar('0',xpos,ypos,4);
xpos+= tft.drawNumber(hh,xpos,ypos,4);
xpos+= tft.drawChar(':',xpos,ypos,4);
if (mm<10) xpos+= tft.drawChar('0',xpos,ypos,4);
xpos+=tft.drawNumber(mm,xpos,ypos,4);
xpos+= tft.drawChar(':',xpos,ypos,4);
if (ss<10) xpos+= tft.drawChar('0',xpos,ypos,4);
tft.drawNumber(ss,xpos,ypos,4);
}
Kod: Zaznacz cały
//EEPROM.update(adrdzien,hhdzien);
//EEPROM.update((adrdzien+1),mmdzien);
//EEPROM.update(adrnoc,hhnoc);
//EEPROM.update((adrnoc+1),mmnoc);
// byte pomocnicza = 0;
// pomocnicza = termostat;
//EEPROM.update((adrtempdzien +1),pomocnicza);
//pomocnicza = termostat>>8;
//EEPROM.update(adrtempdzien,pomocnicza);
// pomocnicza = termostat;
//EEPROM.update((adrtempnoc +1),pomocnicza);
//pomocnicza = termostat>>8;
//EEPROM.update(adrtempnoc,pomocnicza);
//clock.setDateTime(__DATE__, __TIME__); //ustaw czas pobrany z serwaera
// Manual (Year, Month, Day, Hour, Minute, Second) //ustawienia zegara
//clock.setDateTime(2014, 4, 25, 0, 0, 0);
Wyjaśnienia wymagają ostatnie trzy linijki:
//clock.setDateTime(__DATE__, __TIME__); //ustaw czas pobrany z serwaera
Ustawia czas ściągnięty z komputera. Niestety, dostajemy wtedy opóźnienie zegara o czas wgrywania programu.
// Manual (Year, Month, Day, Hour, Minute, Second) //ustawienia zegara
//clock.setDateTime(2014, 4, 25, 0, 0, 0);[/code]
Natomiast ten fragment, umożliwia ręczne ustawienie czasu, te dwa sposoby, należy traktować alternatywnie.
Nie zrobiłem ustawiania czasu, gdyż wyszedłem z założenia, że zwierząt nie obowiązują zmiany zima/lato, a niedokładność zegara wynosząca kilka minut w skali roku, jest w tym zstaosowaniu do pominięcia. Jeśli ktoś chce mieć możliwość ręcznego ustawienia czasu, może sobie dopisać odpowiedni fragment w menu.
Mała poprawka dostyczy też układu regulacji jasności taśmy LED, rezystor R2 ma teraz wartość 2k2, co dało zakłądany zakres regulacji jasności.
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Re: Oświetlenie Akwarium
Witam
Po małej zmianie oświetlenia, (4 x XPG i 4 x XML2 65000k + 4 x deep red i 4 x royal blue) Dołożeniu CO2, roślinki rosną całkiem przyjemnie, puszczając tlen strumieniami bąbelków.
Kliknij obrazek, aby powiększyć
Aktualnie pracuję nad nowymi przetwornicami, z których będę mógł wyciągnąć jakieś 2A. Najprawdopodobniej będzie to przeróbka popularnych modułów za pomocą dodatkowego wzmacniaczy operacyjnych.
Pozdrawiam
Po małej zmianie oświetlenia, (4 x XPG i 4 x XML2 65000k + 4 x deep red i 4 x royal blue) Dołożeniu CO2, roślinki rosną całkiem przyjemnie, puszczając tlen strumieniami bąbelków.
Kliknij obrazek, aby powiększyć
Aktualnie pracuję nad nowymi przetwornicami, z których będę mógł wyciągnąć jakieś 2A. Najprawdopodobniej będzie to przeróbka popularnych modułów za pomocą dodatkowego wzmacniaczy operacyjnych.
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.