Inicialmente, el termostato se hizo simplemente como un termómetro para controlar la temperatura fuera de la ventana. Luego, durante las heladas, las papas comenzaron a congelarse bajo tierra y se agregó la funcionalidad para controlar el microclima. Datos de pasaporte del relé de conmutación - 250V y 10A (2.5kW). Como el calor en el subsuelo no es necesario, un diez por kilovatio es suficiente.
Materiales y herramientas necesarios:caja de cuidado de zapatos
-USB de carga para el teléfono (cualquiera, al menos 0.7A)
-
Arduino-Pro-Mini
Pantalla de 8 caracteres y 2 líneas (WH0802A-NGA-CT es más compacto)
Codificador con un botón (se puede comprar en cualquier radio mag, el botón no se puede incorporar)
-niño con un relé de 5V (compré un montón de relés chinos sin aislamiento óptico a la vez, por lo que necesitaba otro Optocoupler PC817 y una resistencia de 470 Ohm. Si tiene aislamiento óptico en la placa de identificación, puede conectar la placa de identificación directamente al puerto arduino)
Conector USB
-2 cable de extensión USB de 3 metros (uno para el cable de alimentación, al segundo soldamos el DS1820)
- DS1820 (con cualquier letra)
soldador
pistola de pegamento
Placa de identificación FTDI232
Paso 1: Primero que nada, necesitamos flashear el arduino, porque tengo un Pro Mini (no tiene un convertidor USB-RS232), necesito soldar una regla con pines al arduino. Del lado de donde se derivan DTR, TXD, RXD, VCC, GND, GND. Ahora conecte FTDI232 DTR a DTR, VCC a VCC, GND a GND, TXD a RXD, RXD a TXD. Ejecute el IDE de Arduino, descargue el boceto y actualícelo (boceto al final).
Paso 2: Ahora cuidemos el casco. Arrancamos la esponja en el "FUKS", desengrasamos todo bien, la parte profunda de la caja se puede pasar con un paño de esmeril (algo se pegaría mejor). Marque el orificio para el codificador, el conector USB (madre) y la pantalla en sí. Pegue el relé a la tapa de la caja. Debemos tratar de colocar el relé más lejos del procesador y organizar los componentes para que la tapa se cierre más tarde (hay mucho espacio).
Paso 3: Ahora tomamos el cable de extensión USB, cortamos el conector (madre). Cortamos el extremo cortado, perforamos un agujero para el cable en el cuerpo, lo insertamos y pegamos la llave con una pistola. Además, el cable tiene rojo, menos negro (solo lo verifico), más el más del conector, menos el menos (no doy el pinout del conector, está en Internet). Entre el plus del conector y 2 medios (los tengo conectados), se debe soldar una resistencia de 4.7kOhm.
Paso 4: tomamos 2 cables de extensión USB, cortamos el conector (madre), cortamos el cable. Por si acaso, comprobaremos si todos soldamos correctamente. Conectamos el cable de alimentación con carga USB y a la red, pegamos el cable cortado en el conector USB, miramos el probador + en rojo - en negro. Sacamos el cable y soldamos el DS1820: - a 1, + a 3 los 2 cables restantes a 2. Luego cubro el compuesto epoxi (para reparar los tanques, radiadores), dejando un poco de la carcasa del sensor hacia afuera, para que haya una reacción más rápida a los cambios de temperatura.Bueno, hacemos la instalación de acuerdo con el diagrama del circuito (conectamos la alimentación y la tierra de la placa de relé con los circuitos comunes + y -, respectivamente).
Paso 5: Todos los componentes del circuito están conectados. Conectamos nuestro sensor (sin él, la pantalla permanecerá negra), aplicamos energía. En la primera línea, el valor de temperatura, en 2 si "*" está activado, el relé está activado, no desactivado. Ahora intentemos establecer los límites de conmutación del relé. Presione el eje del codificador (o su botón), aparece el valor límite en el que el relé se encenderá girando el eje; el valor aumenta o disminuye. Al hacer clic nuevamente en el eje, obtenemos el límite superior (el relé se apagará), establecemos el valor y presionamos nuevamente. El dispositivo controlará la temperatura, el valor de los límites se mantiene cuando se apaga la alimentación. Eso es todo.
#include
#include
#include
#define BUTTON_1_PIN 10 // el número de salida del botón 1 es 12
OneWire ds (12); // en el pin 10 (se necesita una resistencia de 4.7K)
// inicializa la biblioteca con los números de los pines de la interfaz
LCD de cristal líquido (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;
flotador n_pr = 24.1;
flotador b_pr = 26.2;
priz booleano = falso;
Botón de clase {
público:
Botón (pin de byte, byte timeButton); // descripción del constructor
bandera booleana Press; // el botón de bandera ahora está presionado
bandera booleana Haga clic; // se presionó el botón de marca (clic)
vacío scanState (); // método para verificar el estado de la señal
vacío setPinTime (pin byte, byte timeButton); // método para configurar el número de salida y el tiempo de confirmación (número)
privado:
byte _buttonCount; // contador de confirmación de estado estable
byte _timeButton; // hora de confirmación del estado del botón
byte _pin; // número de pin
};
Botón button1 (BUTTON_1_PIN, 30);
knopka vacío () {
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;
} más {
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;
} más {
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;
if (n_pr> b_pr) {
flotador 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 (flotante);
EEPROM.put (addr, b_pr);
retraso (300);
}
configuración nula (nula) {
pinMode (11, SALIDA);
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;
if (c == 'y') {
EEPROM.get (addr, n_pr);
addr + = sizeof (flotante);
EEPROM.get (addr, b_pr);
}
// Serial.begin (9600);
}
bucle vacío (vacío) {
byte i;
byte presente = 0;
byte type_s;
datos de bytes [12];
byte addr [8];
flotador celsius;
if (! ds.search (addr)) {
ds.reset_search ();
retraso (250);
volver
}
if (OneWire :: crc8 (addr, 7)! = addr [7]) {
volver
}
// el primer byte ROM indica qué chip
interruptor (addr [0]) {
caso 0x10:
type_s = 1;
romper
caso 0x28:
type_s = 0;
romper
caso 0x22:
type_s = 0;
romper
por defecto:
volver
}
ds.reset ();
ds.select (addr);
ds.write (0x44, 1); // comienza la conversión, con el parásito encendido al final
enc_A = digitalRead (pin_A);
enc_A_prev = enc_A;
currentTime = millis ();
while ((millis () - currentTime) <2000) {
button1.scanState ();
if (button1.flagClick == true) {
// hubo un clic en el botón
button1.flagClick = false; // restablecer atributo de clic
knopka ();
}
}
// retraso (1000); // quizás 750 ms es suficiente, quizás no
// podríamos hacer un ds.depower () aquí, pero el reinicio se encargará de ello.
presente = ds.reset ();
ds.select (addr);
ds.write (0xBE); // Leer Scratchpad
for (i = 0; i <9; i ++) {// necesitamos 9 bytes
datos [i] = ds.read ();
}
// Convertir los datos a la temperatura real
// porque el resultado es un entero con signo de 16 bits, debería
// se almacena en un tipo "int16_t", que siempre tiene 16 bits
// incluso cuando se compila en un procesador de 32 bits.
int16_t raw = (datos [1] << 8) | datos [0];
if (type_s) {
raw = raw << 3; // resolución predeterminada de 9 bits
if (datos [7] == 0x10) {
// "cuenta restante" ofrece una resolución completa de 12 bits
raw = (raw & 0xFFF0) + 12 - datos [6];
}
} más {
byte cfg = (datos [4] y 0x60);
// a baja resolución, los bits bajos no están definidos, así que pongamos a cero
if (cfg == 0x00) raw = raw & ~ 7; // Resolución de 9 bits, 93,75 ms
si no (cfg == 0x20) raw = raw & ~ 3; // resolución de 10 bits, 187,5 ms
más si (cfg == 0x40) raw = raw & ~ 1; // 11 bits de resolución, 375 ms
//// el valor predeterminado es 12 bits de resolución, 750 ms de tiempo de conversión
}
celsius = (flotante) crudo / 16.0;
lcd.clear ();
lcd.setCursor (1,0);
lcd.print (celsius);
si (priz) {
lcd.setCursor (0,1);
lcd.print ('*');
}
if (n_pr! = b_pr) {
if (celsius b_pr) {
digitalWrite (11, BAJO);
priz = falso;
}
}
}
// método de verificación del estado del botón
// flagPress = true - hecho clic
// flagPress = false - presionado
// flagClick = true - se hizo clic (clic)
Botón vacío :: scanState () {
if (flagPress == (! digitalRead (_pin))) {
// el estado de la señal permanece igual
_buttonCount = 0; // restablecer el contador de estado de la señal
}
más {
// el estado de la señal ha cambiado
_buttonCount ++; // +1 al contador de estado de señal
if (_buttonCount> = _timeButton) {
// el estado de la señal no cambió el tiempo especificado
// el estado de la señal se ha estabilizado
flagPress =! flagPress; // inverso del indicador de estado
_buttonCount = 0; // restablecer el contador de estado de la señal
if (flagPress == true) flagClick = true; // signo de clic en clic
}
}
}
// método para configurar el número de salida y el tiempo de confirmación
Botón vacío :: setPinTime (pin byte, byte timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // define la salida como entrada
}
// descripción del constructor de la clase Button
Botón :: Botón (byte pin, byte timeButton) {
_pin = pin;
_timeButton = timeButton;
pinMode (_pin, INPUT_PULLUP); // define la salida como entrada
}