Вытяжка по влажности

А, вон Вы про что.

Да, нет, подтяжку можно и так как выше было делать. Вернее, даже, это единственный путь, просто INPUT_PULLUP именно так и поступает – пишет HIGH в порт, сконфигурированный как INPUT.

В даташите написано: If PORTxn is written logic one when the pin is configured as an input pin, the pull-up resistor is activated.

1 лайк

Вы меня окончательно запутали. Ну, да, подтяжку, а я про что? Да, ладно, хрен с нею с подтяжкой, устал я сегодня.

3 лайка

Ты что-то совсем запутался

Чёй-то. Вона

И можно перенести в https://forum.arduino.ru/t/a-vo-skolko-let-vy-uznali-chto-v-segodnya-let :slightly_smiling_face:

помогло ?

#include <SPI.h>
#include "Adafruit_GFX.h"
#include <Adafruit_ST7789.h>
#include <Arduino_ST7789_Fast.h>
#include "OneWire.h"
#include "DallasTemperature.h"
#include <SparkFun_Qwiic_Humidity_AHT20.h>

AHT20 humiditySensor;
#define CS 10
#define DC 8
#define RST 9
#define MISO 12
#define MOSI 11
#define CLK 13
Adafruit_ST7789 tft = Adafruit_ST7789(CS, DC, RST);

#define button A1    // кнопка включения вентилятора
#define fan A3       // Выход на вытяжку
int maxHum = 60;     // максимальная влажность
unsigned long time_fan = 60000;  // 60 секунд = 1 минута (60000 мс)

OneWire oneWire(2);  // порт подключения датчика 18b20
DallasTemperature ds(&oneWire);
DallasTemperature sensors(&oneWire);

int buttonFlag = 0;          // флаг включения кнопкой
unsigned long buttonTime = 0; // время нажатия кнопки
bool humidityControl = false; // флаг управления по влажности

void setup() {
pinMode(button, INPUT_PULLUP);  // Используем внутренний подтягивающий резистор
pinMode(fan, OUTPUT);
ds.begin();
Serial.begin(9600);
Wire.begin(); 
if (humiditySensor.begin() == false) {
Serial.println("AHT20 not detected");
while (1);
}
tft.cp437(true);
tft.init(240, 320);
tft.invertDisplay(false);
tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK);
}

void loop() {
// Обработка кнопки
if (digitalRead(button) == LOW && buttonFlag == 0) {
buttonFlag = 1;
buttonTime = millis();
delay(50); // антидребезг
}
  
// Автоматическое выключение через time_fan
if (buttonFlag == 1 && (millis() - buttonTime) > time_fan) { buttonFlag = 0; } 
// Получение данных с датчиков
ds.requestTemperatures();
if (humiditySensor.available() == true) {
float temperature = humiditySensor.getTemperature();
float humidity = humiditySensor.getHumidity(); 
// Управление по влажности
if (humidity > maxHum) {
humidityControl = true;
} else { humidityControl = false; }
// Логика включения вытяжки: либо кнопкой, либо по влажности
if (buttonFlag == 1 || humidityControl == true) {
digitalWrite(fan, HIGH);
} else { digitalWrite(fan, LOW); }
// Отображение на дисплее
displayData(temperature, humidity, ds.getTempCByIndex(0));
}
delay(1000); // Задержка для стабильности
}

void displayData(float tempAHT, float humidity, float tempDS18) {
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(2);
// Температура AHT20
tft.setCursor(40, 1);
tft.print(utf8rus("Темп."));
tft.setCursor(112, 1);
tft.print(tempAHT, 1);
// Влажность
tft.setTextColor(CYAN, BLACK);
tft.setCursor(40, 20);
tft.print(utf8rus("Влаж."));
tft.setCursor(112, 20);
tft.print(humidity, 1);
// Уставка влажности
tft.setCursor(170, 20);
tft.setTextColor(RED, BLACK);
tft.print(utf8rus("Уст."));
tft.setCursor(225, 20);
tft.print(maxHum);
// Температура DS18B20
tft.setTextColor(YELLOW, BLACK);
tft.setCursor(40, 40);
tft.print(utf8rus("Темп."));
tft.setCursor(112, 40);
tft.print(tempDS18, 1);
// Статус вентилятора
tft.setCursor(40, 60);
tft.setTextColor(GREEN, BLACK);
if (digitalRead(fan) == HIGH) {
if (buttonFlag == 1) {
tft.print(utf8rus("ВЕНТ. (КНОПКА)"));
} else { tft.print(utf8rus("ВЕНТ. (ВЛАЖН.)")); }
} else { tft.print(utf8rus("ВЕНТ. ВЫКЛ")); }
}

// Функция для русских символов (если нужна)
String utf8rus(String source) {
// Ваша реализация конвертации
return source;
}
1 лайк

Логическое или знаю. это ||.

Почищу, на тот момент надо было быстрее. спасибо!

Макет и все все все, на работе, там я буду через 2 дня.
Попробую установить программу ардуино и все библиотеки на домашнем ПК, а также собрать на макетке дома и попробовать в ближайшее время. Спасибо.

Нет. Это побитовое ИЛИ.

Ваше условие простое
для ВКЛ используйте ИЛИ (Или датчик , или кнопка активны)
для ВЫКЛ используйте И (Выключаем, если и датчик, и кнопка не активны)
Зачастую, условие можно описать при помощи оператора else

Та не, усё правильно :slightly_smiling_face:

Да, замена бывает прокатывает, но основы надо знать твёрдо))

Цитируя классиков:

Ха-ха! Вот что значит без очков! Отчётливо видел на экране одну полосу |
@николай76 , @толстый , извиняйте, зрение подвело, впредь буду внимательней

Специально для этого придумали логические функции: конъюнкцию и дизъюнкцию.
Выбор между ними осуществляется, исходя из того, что нужно: чтобы заданное действие наступало либо при одновременном наличии двух условий, либо, наоборот, при наличии хотя бы одного из них.
Вы не приводите схему и не описываете, чего хотите, поэтому наверняка сказать нельзя, но есть подозрение, что Вы перепутали эти функции между собой.
Ну и еще несколько замечаний по коду:

  1. digitalRead() принято вызывать один раз за проход цикла. Если величина должна использоваться более одного раза, принято запоминать ее в переменной. Иначе в программе возможно непредсказуемое поведение, например, при дребезге контактов.
  2. Для логических переменных вместо someValue == 0 (или == LOW) принято писать !someValue, вместо someValue == 1 - someValue.

Начать следует с изучения учебника математической логики.

ндаа.. пойдука я спать..

2 лайка

А где почитать?

А тупо false/true не катит? Или дело в дополнительных математических операциях?

Отчего же? Именно их и следует использовать. Но только там, где нужно.

Основных источников два:

  1. Учебник по математической логике (чтобы знать, что именно нужно написать).
  2. Справочник по языку Си (чтобы знать, как то, что нужно, пишется на Си).

Сыпасиба!

так точно :slight_smile:

Что-то я этот код не осилил.
Читается состояние кнопки, и, через несколько микросекунд - опять оно же. С чего бы оно должно разными значениями - непонятно.

Т.е., если кнопка НЕ нажата, flag = 1, и millis() перезапоминаются каждый раз. А если кнопка нажата, а потом быстро отпущена?

Тут явно что-то не то.

Тебе надо реагировать на два события - кнопка нажата и кнопка отпущена. Сделать это можно используя attachInterrupt().

Почему

?

Я вижу, что через time_fan (определено как 60 000) миллисекунд.