Stránka 1 z 1

Automatické rozsvícení světel do šera nebo tunelu - BH1750

Napsal: 20 čer 2025, 19:21
od vojta_1
Níže je kompletní kód pro Arduino Nano, který řeší automatické ovládání světel v šeru a vjeti do tunelu. Kód využívá BH1750 přes I2C, dvě relé (potkávací a tlumená světla), tlačítko pro uložení LUXu , tři LED (pro indikaci stavů relé a uložení LUXu).
Jak funguje uložení pro nastavení, když se začne stmívat a Vy si myslíte že je vhodná doba pro rozsvícení světel tak prostě zmáčknete tlačítko na 3 sekundy a hodnota se uloží a potvrdí se to indikací ledky -3x blikne a jeto, stav je uložen i po vypnutí klíče, hodnotu můžete kdykoliv změnit....
Logika pro relátka:
Při tmě se rozsvítí první rele1 (potkávací) má zpoždění 4 sekundy a potom rele2 (tlumené) má zpoždění 1 sekundu, vypadá to jak kdyby jste je zapínali ručně, při zhasínaní světel je to naopak ...., každé relé má diodu pro indikací.
Proč jsem nepoužil Fotorezistor protože jsem na bázi BH175O nic nenašel a taky mě to zajímalo ...

Typické hodnoty luxů
0,0001 luxu - Bezměsíčná, zatažená noční obloha (hvězdné světlo)
0,002 luxu - Bezměsíčná jasná noční obloha se záři vzduchu
0,27–1,0 luxu - Úplněk za jasné noci[3][4]
3,4 luxu - Temná hranice občanského soumraku za jasné oblohy
50 luxů - Osvětlení obývacího pokoje v rodině (Austrálie, 1998)
80 luxů - Osvětlení chodby/toalety v kancelářské budově
100 luxů - Velmi tmavý, zatažený den
320–500 luxů - Osvětlení kanceláře
400 luxů - Východ nebo západ slunce za jasného dne.
1000 luxů - Zatažený den; typické osvětlení televizního studia
10000–25000 luxů - Plné denní světlo (ne přímé slunce)
32000–100000 luxů - Přímé sluneční světlo

Kód: Vybrat vše

#include <Wire.h>
#include <BH1750.h>
#include <EEPROM.h>

#define BUTTON_PIN 2
#define RELAY1_PIN 3
#define RELAY2_PIN 4
#define LED1_PIN 5
#define LED2_PIN 6
#define LED3_PIN 7

BH1750 lightMeter;

unsigned long buttonPressTime = 0;
bool buttonPressed = false;
bool buttonHeld = false;
bool led3Blink = false;
byte led3BlinkCount = 0;
unsigned long led3BlinkStart = 0;
const unsigned long buttonHoldTime = 3000; // 3 sekundy pro uložení LUX
const unsigned long led3BlinkInterval = 300; // 300 ms blikání LED3

int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // debounce 50 ms

unsigned long relay1Time = 0;
unsigned long relay2Time = 0;
const unsigned long relayDelay = 4000; // 4 sekundy pro zapnutí relé1 v tmě
const unsigned long relay1OffDelay = 1000; // 1 sekunda po relé2 vypnuto
const unsigned long relay2OffDelay = 3000; // 3 sekundy pro vypnutí relé2 ve světle
const unsigned long relay2OnDelay = 1000; // 1 sekunda po relé1 zapnuto

int luxThreshold;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  lightMeter.begin();

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(LED3_PIN, OUTPUT);

  digitalWrite(RELAY1_PIN, LOW);
  digitalWrite(RELAY2_PIN, LOW);
  digitalWrite(LED1_PIN, LOW);
  digitalWrite(LED2_PIN, LOW);
  digitalWrite(LED3_PIN, LOW);

  // Načtení LUX prahu z EEPROM
  EEPROM.get(0, luxThreshold);
  if (luxThreshold < 1 || luxThreshold > 60000) luxThreshold = 100; // Výchozí prahová hodnota
}

void loop() {
  unsigned long currentMillis = millis();

  // Debounce tlačítka
  int buttonState = digitalRead(BUTTON_PIN);
  if (buttonState != lastButtonState) {
    lastDebounceTime = currentMillis;
  }
  if ((currentMillis - lastDebounceTime) > debounceDelay) {
    if (buttonState == LOW && !buttonPressed) {
      buttonPressed = true;
      buttonPressTime = currentMillis;
    } else if (buttonState == HIGH && buttonPressed) {
      buttonPressed = false;
      buttonHeld = false;
    }
  }
  lastButtonState = buttonState;

  // Uložení LUX prahu při podržení tlačítka 3 sekundy
  if (buttonPressed && !buttonHeld && (currentMillis - buttonPressTime) > buttonHoldTime) {
    buttonHeld = true;
    float lux = lightMeter.readLightLevel();
    luxThreshold = (int)lux;
    EEPROM.put(0, luxThreshold);
    led3Blink = true;
    led3BlinkCount = 0;
    led3BlinkStart = currentMillis;
    Serial.print("LUX prah uložen: ");
    Serial.println(luxThreshold);
  }

  // Blikání LED3 při uložení LUXu
  if (led3Blink) {
    if (led3BlinkCount < 6) { // 3x bliknutí = 6 změn stavu
      if ((currentMillis - led3BlinkStart) > led3BlinkInterval) {
        led3BlinkStart = currentMillis;
        digitalWrite(LED3_PIN, !digitalRead(LED3_PIN));
        led3BlinkCount++;
      }
    } else {
      led3Blink = false;
      digitalWrite(LED3_PIN, LOW);
    }
  }

  // Čtení BH1750
  float lux = lightMeter.readLightLevel();
  Serial.print("LUX: ");
  Serial.print(lux);
  Serial.print(", prah: ");
  Serial.println(luxThreshold);

  // Ovládání relé a LED podle LUX a časovačů
  if (lux > luxThreshold) { // Světlo - vypnout světla
    if (digitalRead(RELAY2_PIN) == HIGH && relay2Time == 0) {
      relay2Time = currentMillis;
    }
    if (relay2Time > 0 && (currentMillis - relay2Time) > relay2OffDelay) {
      digitalWrite(RELAY2_PIN, LOW);
      digitalWrite(LED2_PIN, LOW);
      relay1Time = currentMillis;
      relay2Time = 0;
    }
    if (relay1Time > 0 && (currentMillis - relay1Time) > relay1OffDelay) {
      digitalWrite(RELAY1_PIN, LOW);
      digitalWrite(LED1_PIN, LOW);
      relay1Time = 0;
    }
  } else { // Tma - zapnout světla
    if (digitalRead(RELAY1_PIN) == LOW && relay1Time == 0) {
      relay1Time = currentMillis;
    }
    if (relay1Time > 0 && (currentMillis - relay1Time) > relayDelay) {
      digitalWrite(RELAY1_PIN, HIGH);
      digitalWrite(LED1_PIN, HIGH);
      relay2Time = currentMillis;
      relay1Time = 0;
    }
    if (relay2Time > 0 && (currentMillis - relay2Time) > relay2OnDelay) {
      digitalWrite(RELAY2_PIN, HIGH);
      digitalWrite(LED2_PIN, HIGH);
      relay2Time = 0;
    }
  }
}