Initialement, le thermostat était conçu simplement comme un thermomètre pour contrôler la température à l'extérieur de la fenêtre. Puis, pendant les gelées, les pommes de terre ont commencé à geler sous terre et une fonctionnalité a été ajoutée pour contrôler le microclimat. Données de passeport du relais de commutation - 250 V et 10 A (2,5 kW). Puisque la chaleur dans le sous-sol n'est pas nécessaire, une dizaine par kilowatt suffit.
Matériaux et outils nécessaires:boîte d'entretien des chaussures
-USB-charge pour le téléphone (tout, au moins 0,7A)
-
Arduino-Pro-Mini
Affichage de 2 lignes à 8 caractères (WH0802A-NGA-CT est plus compact)
Encodeur avec un bouton (peut être acheté dans n'importe quel chargeur radio, le bouton ne peut pas être intégré)
-schild avec un relais 5V (j'ai acheté un tas de relais chinois sans isolation optique à la fois, donc j'avais besoin d'un autre optocoupleur PC817 et d'une résistance de 470 Ohm. Si vous avez une isolation optique sur la plaque signalétique, vous pouvez connecter la plaque directement au port arduino)
Connecteur USB
-2 rallonge USB de 3 mètres (une pour le cordon d'alimentation, à la seconde on soude le DS1820)
- DS1820 (avec n'importe quelle lettre)
fer à souder
- pistolet à colle
Plaque signalétique FTDI232
Étape 1: Tout d'abord, nous devons flasher l'arduino, car j'ai un Pro Mini (il va sans convertisseur USB-RS232), j'ai besoin de souder une règle avec des broches à l'arduino. Du côté où DTR, TXD, RXD, VCC, GND, GND sont dérivés. Connectez maintenant FTDI232 DTR à DTR, VCC à VCC, GND à GND, TXD à RXD, RXD à TXD. Exécutez l'IDE Arduino, téléchargez le croquis et flashez-le (croquis à la fin).
Étape 2: Maintenant, prenons soin de la coque. On arrache l'éponge au "FUKS", on dégraisse bien tout, la partie profonde de la boite peut être passée avec une toile émeri (quelque chose collerait mieux). Marquez le trou pour l'encodeur, le connecteur USB (mère) et l'écran lui-même. Collez le relais sur le couvercle de la boîte. Nous devons essayer de placer le relais plus loin du processeur et de disposer les composants de manière à ce que le couvercle se ferme plus tard (il y a beaucoup d'espace).
Étape 3: Maintenant, nous prenons le câble d'extension USB, coupons la prise du connecteur (mère). Nous coupons l'extrémité coupée, forons un trou pour le câble dans le corps, l'insérons et collons la clé avec un pistolet. De plus, le câble est rouge, moins noir (je le vérifie juste), plus le plus du connecteur, moins le moins (je ne donne pas le brochage du connecteur - c'est sur Internet). Entre le plus du connecteur et 2 medium (je les ai connectés), une résistance de 4.7kOhm doit être soudée.
Étape 4: Nous prenons 2 câbles d'extension USB, coupons le connecteur (mère), coupons le câble. Au cas où, nous vérifierons si nous avons tous correctement soudé. Nous connectons le câble d'alimentation avec une charge USB et au réseau, collons le câble coupé dans le connecteur USB, regardons le testeur + sur rouge - sur noir. Nous retirons le câble et soudons le DS1820: - à 1, + à 3 les 2 fils restants à 2. Je recouvre ensuite le composé époxy (pour réparer les réservoirs, les radiateurs), en laissant un peu du boîtier du capteur vers l'extérieur, afin qu'il y ait une réaction plus rapide aux changements de température.Eh bien, nous faisons l'installation selon le schéma de circuit (nous connectons la puissance et la masse de la plaque de relais avec les circuits communs + et -, respectivement).
Étape 5: Tous les composants du circuit sont connectés. Nous connectons notre capteur (sans lui, l'affichage restera noir), mettons sous tension. Dans la première ligne - la valeur de la température, en 2 si «*» est activé - le relais est activé, non - désactivé. Essayons maintenant de définir les limites de commutation des relais. Appuyez sur l'arbre du codeur (ou sur votre bouton) la valeur limite apparaît à laquelle le relais s'allumera en tournant l'arbre - la valeur augmente ou diminue. En cliquant à nouveau sur l'arbre - nous obtenons la limite supérieure (le relais s'éteindra), définissez la valeur et appuyez à nouveau. L'appareil surveillera la température, la valeur des limites est maintenue lorsque l'alimentation est coupée. C’est tout.
#include
#include
#include
#define BUTTON_1_PIN 10 // le numéro de sortie du bouton 1 est 12
OneWire ds (12); // sur la broche 10 (une résistance de 4,7 K est nécessaire)
// initialise la bibliothèque avec les numéros des broches d'interface
LCD à cristaux liquides (3, 2, 4, 5, 6, 7);
unsigned long currentTime;
const int pin_A = 8; // broche 12
const int pin_B = 9; // broche 11
unsigned char enc_A;
unsigned char enc_B;
caractère non signé enc_A_prev = 0;
float n_pr = 24,1;
float b_pr = 26,2;
prix booléen = faux;
Bouton de classe {
public:
Button (octet pin, octet timeButton); // description du constructeur
drapeau booléenPress; // le bouton indicateur est maintenant enfoncé
flag booléenClick; // le bouton indicateur a été enfoncé (cliquez)
void scanState (); // méthode pour vérifier l'état du signal
void setPinTime (octet pin, octet timeButton); // méthode pour définir le numéro de sortie et l'heure de confirmation (nombre)
privé:
byte _buttonCount; // compteur de confirmation d'état stable
byte _timeButton; // heure de confirmation de l'état du bouton
byte _pin; // numéro de broche
};
Button 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)) {
si (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)) {
si (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;
si (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 (float);
EEPROM.put (addr, b_pr);
retard (300);
}
void setup (void) {
pinMode (11, SORTIE);
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;
si (c == 'y') {
EEPROM.get (addr, n_pr);
addr + = sizeof (float);
EEPROM.get (addr, b_pr);
}
// Serial.begin (9600);
}
boucle vide (void) {
octet i;
octet présent = 0;
byte type_s;
données d'octets [12];
octet addr [8];
flotter celsius;
if (! ds.search (addr)) {
ds.reset_search ();
retard (250);
retour
}
if (OneWire :: crc8 (addr, 7)! = addr [7]) {
retour
}
// le premier octet ROM indique quelle puce
switch (addr [0]) {
cas 0x10:
type_s = 1;
casser;
cas 0x28:
type_s = 0;
casser;
cas 0x22:
type_s = 0;
casser;
par défaut:
retour
}
ds.reset ();
ds.select (addr);
ds.write (0x44, 1); // démarre la conversion, le parasite étant sous tension à la fin
enc_A = digitalRead (pin_A);
enc_A_prev = enc_A;
currentTime = millis ();
while ((millis () - currentTime) <2000) {
button1.scanState ();
if (button1.flagClick == true) {
// il y a eu un clic sur le bouton
button1.flagClick = false; // réinitialiser l'attribut de clic
knopka ();
}
}
// délai (1000); // peut-être que 750 ms suffisent, peut-être pas
// nous pourrions faire un ds.depower () ici, mais la réinitialisation s'en occupera.
présent = ds.reset ();
ds.select (addr);
ds.write (0xBE); // Lire le bloc-notes
pour (i = 0; i <9; i ++) {// nous avons besoin de 9 octets
data [i] = ds.read ();
}
// Convertit les données en température réelle
// parce que le résultat est un entier signé 16 bits, il devrait
// être stocké dans un type "int16_t", qui est toujours 16 bits
// même lorsqu'il est compilé sur un processeur 32 bits.
int16_t raw = (données [1] << 8) | données [0];
if (type_s) {
raw = raw << 3; // Résolution 9 bits par défaut
if (données [7] == 0x10) {
// "count count" donne une résolution complète de 12 bits
raw = (raw & 0xFFF0) + 12 - données [6];
}
} else {
octet cfg = (données [4] & 0x60);
// à une résolution inférieure, les bits bas ne sont pas définis, alors mettons-les à zéro
if (cfg == 0x00) raw = raw & ~ 7; // Résolution 9 bits, 93,75 ms
sinon si (cfg == 0x20) raw = raw & ~ 3; // 10 bits res, 187,5 ms
sinon si (cfg == 0x40) raw = raw & ~ 1; // résolution 11 bits, 375 ms
//// par défaut est une résolution de 12 bits, un temps de conversion de 750 ms
}
celsius = (float) raw / 16.0;
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (celsius);
if (priz) {
lcd.setCursor (0,1);
lcd.print ('*');
}
si (n_pr! = b_pr) {
if (celsius b_pr) {
digitalWrite (11, LOW);
priz = false;
}
}
}
// Méthode de vérification de l'état des boutons
// flagPress = true - cliqué
// flagPress = false - pressé
// flagClick = true - a été cliqué (cliquez)
void Button :: scanState () {
if (flagPress == (! digitalRead (_pin))) {
// l'état du signal reste le même
_buttonCount = 0; // réinitialise le compteur d'état du signal
}
sinon {
// l'état du signal a changé
_buttonCount ++; // +1 au compteur d'état du signal
if (_buttonCount> = _timeButton) {
// l'état du signal n'a pas changé l'heure spécifiée
// l'état du signal est devenu stable
flagPress =! flagPress; // inverse de l'indicateur d'état
_buttonCount = 0; // réinitialise le compteur d'état du signal
if (flagPress == true) flagClick = true; // signe de clic sur clic
}
}
}
// méthode pour régler le numéro de sortie et l'heure de confirmation
void Button :: setPinTime (octet pin, octet timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // définir la sortie comme entrée
}
// description du constructeur de la classe Button
Button :: Button (octet pin, octet timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // définir la sortie comme entrée
}