Początkowo termostat był wykonany po prostu jako termometr do kontroli temperatury za oknem. Następnie, podczas mrozów, ziemniaki zaczęły zamarzać pod ziemią i dodano funkcjonalność kontrolującą mikroklimat. Dane paszportowe przekaźnika przełączającego - 250 V i 10 A (2,5 kW). Ponieważ ciepło w podziemiach nie jest potrzebne, wystarczy dziesięć na kilowat.
Niezbędne materiały i narzędzia:pudełko do pielęgnacji obuwia
- Ładowanie przez USB za telefon (dowolny, co najmniej 0,7A)
-
Arduino-Pro-Mini
-2-liniowy 8-znakowy wyświetlacz (WH0802A-NGA-CT jest bardziej kompaktowy)
Enkoder z przyciskiem (można kupić w dowolnym magazynie radiowym, przycisk nie może być wbudowany)
- dziecko z przekaźnikiem 5 V (kupiłem jednocześnie kilka chińskich przekaźników bez izolacji optycznej, więc potrzebowałem innego transoptora PC817 i rezystora 470 Ohm. Jeśli masz izolację optyczną na tabliczce znamionowej, możesz podłączyć tabliczkę znamionową bezpośrednio do portu arduino)
Złącze USB
-2 3-metrowy przedłużacz USB (jeden na przewód zasilający, przylutowany do drugiego DS1820)
- DS1820 (z dowolną literą)
lutownica
-klej pistolet
Tabliczka znamionowa FTDI232
Krok 1: Przede wszystkim musimy sflashować arduino, ponieważ mam Pro Mini (nie ma konwertera USB-RS232), muszę przylutować linijkę z pinami do arduino. Ze strony, z której pochodzą DTR, TXD, RXD, VCC, GND, GND. Teraz podłączamy FTDI232 DTR do DTR, VCC do VCC, GND do GND, TXD do RXD, RXD do TXD. Uruchom arduino IDE, pobierz szkic i sflashuj go (szkic na końcu).
Krok 2: Zajmijmy się teraz kadłubem. Odrywamy gąbkę w „FUKS”, wszystko dobrze odtłuszczamy, głęboką część pudełka można przełożyć szmerglową ściereczką (coś mocno utknęłoby). Zaznacz otwór na enkoder, złącze USB (matka) i sam wyświetlacz. Przyklej przekaźnik do pokrywy skrzynki. Musimy spróbować umieścić przekaźnik dalej od procesora i tak ustawić komponenty, aby pokrywa zamykała się później (jest dużo miejsca).
Krok 3: Teraz bierzemy przedłużacz USB, odcinamy gniazdo złącza (matka). Odcinamy odcięty koniec, wiercimy otwór na kabel w ciele, wkładamy go i przyklejamy klucz pistoletem. Dodatkowo kabel ma czerwony, minus czarny (po prostu to sprawdzam), plus plus złącza, minus minus (nie podaję wyprowadzenia złącza - jest w Internecie). Pomiędzy plusem złącza a 2 medium (mam je podłączone) należy przylutować opornik 4,7 kOhm.
Krok 4: bierzemy 2 przedłużacze USB, odcinamy złącze (matka), odcinamy kabel. Na wszelki wypadek sprawdzimy, czy wszyscy poprawnie przylutowaliśmy. Podłączamy kabel zasilający z ładowaniem USB i do sieci, wtykamy przecięty kabel do złącza USB, spójrz na tester + na czerwono - na czarno. Wyciągamy kabel i lutujemy DS1820: - do 1, + do 3 pozostałych 2 drutów do 2. Następnie pokrywam związek epoksydowy (do naprawy zbiorników, grzejników), pozostawiając trochę obudowy czujnika na zewnątrz, aby szybciej nastąpiła reakcja na zmiany temperatury.Cóż, wykonujemy instalację zgodnie ze schematem obwodu (łączymy moc i masę płytki przekaźnikowej odpowiednio ze wspólnymi obwodami + i -).
Krok 5: Wszystkie elementy obwodu są połączone. Podłączamy nasz czujnik (bez niego wyświetlacz pozostanie czarny), włączymy zasilanie. W pierwszym wierszu - wartość temperatury, w 2, jeśli „*” jest włączony - przekaźnik jest włączony, nie - wyłączony. Teraz spróbujmy ustawić limity przełączania przekaźnika. Naciśnij wałek enkodera (lub przycisk), pojawi się wartość graniczna, przy której przekaźnik włączy się poprzez obrót wału - wartość wzrasta lub maleje. Klikając ponownie wałek - otrzymujemy górną granicę (przekaźnik się wyłączy), ustaw wartość i naciśnij ponownie. Urządzenie będzie monitorować temperaturę, wartość limitów jest utrzymywana po wyłączeniu zasilania. To wszystko.
#include
#include
#include
# zdefiniować BUTTON_1_PIN 10 // numer wyjścia przycisku 1 to 12
OneWire ds (12); // na pinie 10 (wymagany rezystor 4,7 K)
// zainicjuj bibliotekę numerami pinów interfejsu
Liquid Crystal lcd (3, 2, 4, 5, 6, 7);
unsigned long currentTime;
const int pin_A = 8; // pin 12
const int pin_B = 9; // pin 11
unsigned char enc_A;
unsigned char enc_B;
unsigned char enc_A_prev = 0;
zmiennoprzecinkowa n_pr = 24,1;
zmiennoprzecinkowe b_pr = 26,2;
boolean priz = false;
Przycisk klasy {
publiczne:
Przycisk (bajt pin, bajt timeButton); // opis konstruktora
flaga logicznaPress; // przycisk flagi jest teraz wciśnięty
flaga logiczna Kliknij; // przycisk flagi został naciśnięty (kliknij)
void scanState (); // metoda sprawdzania stanu sygnału
void setPinTime (bajt pin, bajt timeButton); // metoda ustawiania numeru wyjściowego i czasu potwierdzenia (liczba)
prywatny:
byte _buttonCount; // licznik potwierdzenia stanu stabilnego
byte _timeButton; // czas potwierdzenia stanu przycisku
bajt _pin; // numer pin
};
Przycisk button1 (BUTTON_1_PIN, 30);
void knopka () {
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (n_pr);
// button1.scanState ();
while (button1.flagClick == false) {
enc_A = digitalRead (pin_A);
enc_B = digitalRead (pin_B);
if ((! enc_A) && (enc_A_prev)) {
if (enc_B) {
n_pr = n_pr-0,1;
} else {
n_pr = n_pr + 0,1;
}
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (n_pr);
}
enc_A_prev = enc_A;
button1.scanState ();
}
button1.flagClick = false;
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (b_pr);
while (button1.flagClick == false) {
enc_A = digitalRead (pin_A);
enc_B = digitalRead (pin_B);
if ((! enc_A) && (enc_A_prev)) {
if (enc_B) {
b_pr = b_pr-0,1;
} else {
b_pr = b_pr + 0,1;
}
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (b_pr);
}
enc_A_prev = enc_A;
button1.scanState ();
}
button1.flagClick = false;
jeśli (n_pr> b_pr) {
float wr = n_pr;
n_pr = b_pr;
b_pr = wr;
}
int addr = 0;
EEPROM.write (addr, 'y');
addr = 1;
EEPROM.put (addr, n_pr);
addr + = sizeof (liczba zmiennoprzecinkowa);
EEPROM.put (addr, b_pr);
opóźnienie (300);
}
void setup (void) {
pinMode (11, WYJŚCIE);
pinMode (pin_A, INPUT_PULLUP);
pinMode (pin_B, INPUT_PULLUP);
lcd.begin (8.2);
int addr = 0;
char c = EEPROM.read (addr);
addr = addr + 1;
jeśli (c == „y”) {
EEPROM.get (addr, n_pr);
addr + = sizeof (liczba zmiennoprzecinkowa);
EEPROM.get (addr, b_pr);
}
// Serial.begin (9600);
}
void loop (void) {
bajt i;
bajt obecny = 0;
bajt type_s;
dane bajtowe [12];
bajt addr [8];
pływak Celsjusza;
if (! ds.search (addr)) {
ds.reset_search ();
opóźnienie (250);
powrót
}
if (OneWire :: crc8 (addr, 7)! = addr [7]) {
powrót
}
// pierwszy bajt ROM wskazuje, który układ
przełącznik (addr [0]) {
przypadek 0x10:
type_s = 1;
przerwa;
przypadek 0x28:
typ_s = 0;
przerwa;
przypadek 0x22:
typ_s = 0;
przerwa;
domyślnie:
powrót
}
ds.reset ();
ds.select (addr);
ds.write (0x44, 1); // rozpocznij konwersję z włączoną mocą pasożyta na końcu
enc_A = digitalRead (pin_A);
enc_A_prev = enc_A;
currentTime = millis ();
while ((millis () - currentTime) <2000) {
button1.scanState ();
if (button1.flagClick == true) {
// nastąpiło kliknięcie przycisku
button1.flagClick = false; // reset atrybutu kliknięcia
knopka ();
}
}
// opóźnienie (1000); // może 750 ms wystarczy, może nie
// możemy zrobić tutaj ds.depower (), ale reset zajmie się tym.
present = ds.reset ();
ds.select (addr);
ds.write (0xBE); // Przeczytaj Brudnopis
dla (i = 0; i <9; i ++) {// potrzebujemy 9 bajtów
data [i] = ds.read ();
}
// Konwertuj dane na rzeczywistą temperaturę
// ponieważ wynikiem jest 16-bitowa liczba całkowita ze znakiem, powinno
// być przechowywane na typ „int16_t”, który zawsze ma 16 bitów
// nawet po skompilowaniu na 32-bitowym procesorze.
int16_t raw = (data [1] << 8) | dane [0];
if (type_s) {
surowe = surowe << 3; // Domyślna rozdzielczość 9 bitów
if (data [7] == 0x10) {
// „liczba pozostań” daje pełną 12-bitową rozdzielczość
raw = (raw & 0xFFF0) + 12 - data [6];
}
} else {
bajt cfg = (dane [4] i 0x60);
// w niższej rozdzielczości niskie bity są niezdefiniowane, więc wyzerujmy je
if (cfg == 0x00) raw = raw & ~ 7; // Rozdzielczość 9 bitów, 93,75 ms
w przeciwnym razie, jeśli (cfg == 0x20) raw = raw & ~ 3; // 10 bitów res, 187,5 ms
w przeciwnym razie, jeśli (cfg == 0x40) raw = raw & ~ 1; // 11 bitów res, 375 ms
Domyślnie //// ma rozdzielczość 12 bitów i czas konwersji 750 ms
}
Celsjusz = (liczba zmiennoprzecinkowa) raw / 16.0;
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (Celsjusz);
if (priz) {
lcd.setCursor (0,1);
lcd.print ('*');
}
jeśli (n_pr! = b_pr) {
if (Celsius b_pr) {
digitalWrite (11, LOW);
priz = fałsz;
}
}
}
// metoda sprawdzania stanu przycisku
// flagPress = true - kliknięty
// flagPress = false - wciśnięty
// flagClick = true - został kliknięty (kliknij)
void Button :: scanState () {
if (flagPress == (! digitalRead (_pin))) {
// stan sygnału pozostaje taki sam
_buttonCount = 0; // zresetować licznik stanu sygnału
}
jeszcze {
// stan sygnału zmienił się
_buttonCount ++; // +1 do licznika stanu sygnału
if (_buttonCount> = _timeButton) {
// stan sygnału nie zmienił określonego czasu
// stan sygnału się ustabilizował
flagPress =! flagPress; // odwrotność wskaźnika stanu
_buttonCount = 0; // zresetować licznik stanu sygnału
if (flagPress == true) flagClick = true; // znak kliknięcia kliknięcia
}
}
}
// metoda ustawiania numeru wyjściowego i czasu potwierdzenia
void Button :: setPinTime (bajt pin, bajt timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // zdefiniuj dane wyjściowe jako dane wejściowe
}
// opis konstruktora klasy Button
Button :: Button (bajt pin, bajt timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // zdefiniuj dane wyjściowe jako dane wejściowe
}