Releu activat de lumină sau întuneric cu Arduino

 Autor:   Publicat pe:   Actualizat pe:  2017-10-28T17:07:45Z

Releu acționat de lumină sau întuneric comandat de microcontroller ATmega328 și reglat folosind un encoder rotativ.

Un releu activat de lumină sau întuneric este un dispozitiv util pentru pornirea automată a luminilor sau a altui dispozitiv electric în funcție de iluminarea unui senzor. În general, un astfel de dispozitiv se poate construi cu un fotorezistor și mai multe rezistoare care sunt conectate pentru a forma divizoare de tensiune. Un amplificator operațional compară tensiunea unui divizor cu tensiunea de pe fotorezistor și acționează releul printr-un tranzistor.

Dar, folosind un microcontroller se poate proiecta un dispozitiv cu mai multe funcții și comportament ușor de modificat. De exemplu acest dispozitiv, nu acționează releul la modificări rapide ale luminii care cade pe senzor. De asemenea, printr-o apăsare de buton, dispozitivul se transformă din releu acționat de întuneric în releu acționat de lumină.

Dispozitivul prezentat pe bazează pe o placă de dezvoltare cu microcontroller (MCU) ATmega328 și câteva module ce fac parte dintr-un kit de senzori pentru Arduino. Modulele nu sunt necesare - se pot construi, fiind circuite simple.
Releu activat de lumină sau întuneric cu Arduino
Principiul de funcționare este simplu. Un divizor de tensiune din care face parte fotorezistorul este conectat la o intrare analogică a microcontroller-ului. În funcție de această valoare, dar și de pragul de acționare ce poate fi modificat de utilizator și de modul de funcționare, programul decide dacă acționează sau nu releul. Encoderul rotativ este folosit pentru a seta pragul de declanșare (prin rotire) și pentru a comuta pe unul din cele patru moduri de funcționare (prin apăsare): întotdeauna oprit, întotdeauna pornit, releu acționat de întuneric sau releu acționat de lumină. Pragul și modul de funcționare sunt memorate în memoria EEPROM a microcontroller-ului și sunt citite la fiecare pornire.

Modul de conectare și schema releului acționat de lumină/întuneric
Modul de conectare și schema
Circuitul a fost proiectat folosind o placă Nano. Pentru un dispozitiv independent, se poate folosi o placă Pro Mini care este mai mică și mai ieftină. Encoderul rotativ este conectat la pinul D2, iar comutatorul lui la pinul D3. Acești pini generează întreruperi în program pentru a modifica pragul de declanșare și modul de funcționare. Fotorezistorul este măsurat de pinul analog A3, de două ori în 0,5 secunde. Această secvență de timp poate fi modificată, deoarece, doar dacă valoarea fotorezistorului este constantă, se decide activarea sau nu a releului prin pinul D4.

În cazul în care veți folosi acest dispozitiv pentru a porni lumina într-o încăpere, lumina ce va fi activată nu trebuie să ajungă la fotorezistor. În caz contrar, releul va opri și va porni lumina la fiecare secundă. Lumina exterioară trebuie să ajungă la fotorezistor, iar releul trebuie să controleze o sursă de lumină de interior.

Codul sursă este următorul. Puteți obține o schiță care este actualizată de pe GitHub.
/*  
 *  Arduino powered light/dark activated switch
 *  Copyright (C) 2017 One Transistor <https://www.onetransistor.eu>
 *  Licensed under GNU General Public License v3
 */  

#include <EEPROM.h>

// Pins for photoresistor, relay and encoder
const int sensorPin = A3; // A3
const int relayPin = 4; // D4
const int encoderA = 2; // D2
const int encoderB = 5; // D5
const int modeSwitchPin = 3; // D3

// Change that will be considered significant in read value
const int valueThreshold = 20;
const int rotaryEncoderStep = 10;

int sensorValue = 0;
volatile unsigned int sensorThreshold = 512;
volatile byte modeSwitch = 0; // 0 = always off, 1 = always on, 2 and 3 = dark or light activated switch

void setup() {
  pinMode(sensorPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  pinMode(encoderA, INPUT);
  pinMode(encoderB, INPUT);
  pinMode(modeSwitchPin, INPUT_PULLUP);

  attachInterrupt(0, readEncoder, CHANGE);
  attachInterrupt(1, readMode, LOW);

  modeSwitch = EEPROM.read(1);
  if (modeSwitch > 3) modeSwitch = 2;

  sensorThreshold = (EEPROM.read(2) << 8) + EEPROM.read(3);
  if (sensorThreshold > 1023) sensorThreshold = 512;

  // uncomment these lines for debugging
  //Serial.begin(9600);
  //Serial.println("Light/dark activated switch");
}

void loop() {
  while (modeSwitch < 2) ;

  // sensor is read twice in 0.5 seconds
  // if there is no significant change in sensor value
  // it is decided whether to activate the relay or not
  int sensorValueInstant1;
  do {
    sensorValueInstant1 = analogRead(sensorPin); // read sensor
    delay(500); // wait 0.5 seconds
    int sensorValueInstant2 = analogRead(sensorPin); // read sensor again

    // if there is no significant change in read values
    // it means there is a constant change of light intensity
    if (max(sensorValueInstant1, sensorValueInstant2) - min(sensorValueInstant1, sensorValueInstant2) < valueThreshold)
      sensorValue = sensorValueInstant1; // store sensor value

    delay(500);
  } while (sensorValue != sensorValueInstant1);

  // uncomment these lines for debugging
  //Serial.print("Photoresistor: ");
  //Serial.print(sensorValue / 10.24, 1);
  //Serial.println(" %");

  // if value is over or below threshold
  // depending on mode setting, turn on or off the relay
  if ((sensorValue < sensorThreshold) && (modeSwitch > 1))
    digitalWrite(relayPin, (modeSwitch == 2) ? HIGH : LOW);
  else
    digitalWrite(relayPin, (modeSwitch == 3) ? HIGH : LOW);
}

// https://playground.arduino.cc/Main/RotaryEncoders
void readEncoder() {
  if (digitalRead(encoderA) == digitalRead(encoderB))
  {
    if (sensorThreshold < 1024) sensorThreshold += rotaryEncoderStep;
  }
  else {
    if (sensorThreshold > 0) sensorThreshold -= rotaryEncoderStep;
  }

  EEPROM.update(2, sensorThreshold >> 8);
  EEPROM.update(3, sensorThreshold & 0xFF);

  // uncomment these lines for debugging
  //Serial.print("New threshold: ");
  //Serial.print(sensorThreshold / 10.24, 1);
  //Serial.println(" %");
}

// "debouncing" procedure from
// http://forum.arduino.cc/index.php?topic=45000.0
void readMode() {
  static unsigned long lastPush = 0;
  unsigned long currentPush = millis();

  if (currentPush - lastPush > 200) {
    modeSwitch++;
    if (modeSwitch > 3)
      modeSwitch = 0;
  }
  lastPush = currentPush;

  if (modeSwitch < 2)
    digitalWrite(relayPin, (modeSwitch == 1) ? HIGH : LOW);

  EEPROM.update(1, modeSwitch);

  // uncomment these lines for debugging
  //Serial.print("Sensor mode: ");
  //Serial.println(modeSwitch, DEC);
}
În cazul în care veți folosi circuitul pentru a comanda dispozitive alimentate de la rețea, se recomandă construirea lui într-o cutie, cu atenție la firele ce conduc tensiunea de 220 V. Montajul propriu-zis se alimentează la 5 V (placa de dezvoltare trebuie să funcționeze la 5 V, ca și releul).

Niciun comentariu :

Trimiteți un comentariu

Vă recomandăm să citiți regulamentul comentariilor înainte de a scrie un comentariu.