Releu acționat de lumină sau întuneric comandat de microcontroller ATmega328 și reglat folosind un encoder rotativ.
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.
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 |
Î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.