Stap 3: codering
Aanvankelijk leek de logica eenvoudig: als het is donker en er is beweging - zet het toestel (lamp in mijn geval), anders zwenking op vandoor. Wacht n seconden en controleer nogmaals.
Maar als ik was het testen van en het toevoegen van nieuwe modi naar mijn apparaat, geen van bovenstaande genoemde werkte zo eenvoudig.
U kunt als (donker == true & & verkeer == true) {draai op} anders dan {uitschakelen}; vertraging (n);
want je vervelende feedback effect krijgt: donker? -Ja, verkeer? -ja dan zet hem op; wachten; donkere? -geen (omdat we zojuist de lichten hebt ingeschakeld), verkeer? -ja dan zwenking op vandoor; donkere? -Ja... Dus knipperen met deze logica u constant krijgt.
Thats waarom in procedure light_on() we eerst als het is donker en ga dan in de lus, over te schakelen op licht en voortdurend te controleren of beweging aanwezig is. We controleren niet deze twee voorwaarden gelijktijdig.
Wat betreft de opdracht vertraging (n), die wordt onderbroken uitvoering voor n milliseconden, wij niet gebruiken omdat tijdens de vertraging, als u druk op permanente of handmatige modusknoppen, Arduino niet ziet, omdat het slaapt. Daarom gebruiken we in de dezelfde lus, welke controles voor bewegingen in light_on () procedure, functioneren van millis() en zijn waarde toewijzen aan variabele "nu". Millis() geeft als resultaat het aantal milliseconden dat is verstreken sinds de Arduino was ingeschakeld. Op deze manier zijn wij in staat om uit de lus wanneer nu + delay_time > millis().
Dus, alle voorwaarden om van lus in light_on() procedure:
- Er bestaat geen verkeer;
- delay_time is verstreken sinds de laatste keer dat beweging werd ontdekt;
- apparaat is gewijzigd door een van de knoppen in te drukken.
Andere opmerkingen die ik in de code zelf opgenomen.
Ik maakte twee klassen: fotocel en pir.
Voor de knop debouncing gebruik ik Bounce2-bibliotheek die u vanaf hier downloaden kunt. Library downloaden en uitpakken van de inhoud ervan in ~/Documents/Arduino/libraries (op een Mac) of mijn Documents\Arduino\libraries (op een Windows machine).
<p>//#define __DEBUG__ // uncomment this define for debugging information in serial monitor<br>#include "Bounce2.h" #include "photocell.h" #include "pir.h"</p><p>//SETUP const unsigned int PHOTOCELL_PIN = A0; const unsigned int RELAY_PIN = 10; const unsigned int PERMANENT_LED_PIN = 13; const unsigned int PERMANENT_MODE_PIN = 12; const unsigned int MANUAL_MODE_PIN = 11; const unsigned int PIR_INPUT_PIN = 2; const unsigned int BAUD_RATE = 9600; const unsigned int LIGHT_DELAY = 5000; const unsigned int DEBOUNCE_DELAY = 20; const int DEFAULT_THRESHOLD = 130; //SETUP</p><p>int threshold = 0; Bounce permanent_mode_button, manual_mode_button; boolean button_state = false; photocell p_cell(PHOTOCELL_PIN); PIR ir_sensor(PIR_INPUT_PIN); enum modes {default_, permanent, manual, threshold_changed}; // we also need to be able to determine, when during manual mode, manual mode button was pressed again int prev_mode = default_; int mode = default_;</p><p>//check state of button boolean button_pressed(Bounce& button, boolean& state) { if (button.update() && button.read() == 1) { state = !state; } return state; }</p><p>//determine current mode int check_mode() { if (button_pressed(permanent_mode_button, button_state)) mode = permanent; // permanent mode button pressed</p><p> else if (manual_mode_button.update() && manual_mode_button.read() == 1) { threshold = p_cell.value();</p><p>#ifdef __DEBUG__ Serial.println("threshold: " + String(threshold)); #endif</p><p> mode = threshold_changed; // threshold was changed }</p><p> else if (threshold > 0) { mode = manual; // manual mode }</p><p> else mode = default_; // default mode</p><p> return mode; }</p><p>//check, wheter mode was changed bool mode_changed() { if (prev_mode != check_mode()) { prev_mode = check_mode();</p><p>#ifdef __DEBUG__ Serial.println("true, previous mode: " + String(prev_mode)); #endif return true; } else { #ifdef __DEBUG__ Serial.println("false, previous mode: " + String(prev_mode)); #endif return false; } }</p><p>//turn on the light void light_on (int threshold, const unsigned int& pin, const unsigned int& delay_time) { digitalWrite (PERMANENT_LED_PIN, 0); if (p_cell.value() <= threshold) {</p><p> unsigned long now = 0; boolean mode_change = mode_changed();</p><p> for (; ((ir_sensor.motion_detected() && !mode_change) && (now = millis())) || ((millis() < (now + delay_time)) && !mode_change); mode_change = mode_changed()) { digitalWrite(pin, 1); // we get out of this loop when there is no movement or device mode was changed or delay time has passed #ifdef __DEBUG__ Serial.println("inside loop, motion: " + String(ir_sensor.motion_detected())); Serial.println("now: " + String(now)); #endif } digitalWrite(pin, 0); } digitalWrite(pin, 0); }</p><p>void setup() { #ifdef __DEBUG__ Serial.begin(BAUD_RATE); #endif permanent_mode_button.attach(PERMANENT_MODE_PIN); permanent_mode_button.interval(DEBOUNCE_DELAY); pinMode(PERMANENT_MODE_PIN, INPUT); manual_mode_button.attach(MANUAL_MODE_PIN); manual_mode_button.interval(DEBOUNCE_DELAY); pinMode(MANUAL_MODE_PIN, INPUT); pinMode(RELAY_PIN, OUTPUT); pinMode(PERMANENT_LED_PIN, OUTPUT); }</p><p>void loop() { if (mode == permanent) { digitalWrite(RELAY_PIN, 1); digitalWrite(PERMANENT_LED_PIN, 1); #ifdef __DEBUG__ Serial.println("permanent mode on"); #endif }</p><p> else if (mode == manual) { #ifdef __DEBUG__ Serial.println("manual mode on"); #endif light_on (threshold, RELAY_PIN, LIGHT_DELAY); }</p><p> else if (mode == default_) { #ifdef __DEBUG__ //Serial.println("default mode on"); Serial.println("value: " + String(p_cell.value())); #endif light_on (DEFAULT_THRESHOLD, RELAY_PIN, LIGHT_DELAY); } check_mode(); }</p>
photocell.h
<p>#include "arduino.h"</p><p>class photocell { private: unsigned int _pin; int buffer_size;</p><p> public: photocell(const unsigned int pin) { _pin = pin; buffer_size = 10; }</p><p> int value () { float sum = 0; for (int i = 1; i <= buffer_size; i++) { //we use buffer to get nice average value sum += analogRead(_pin); } return round(sum / buffer_size); } };</p>
PIR.h
<p>#ifndef __PIR__<br>#define __PIR__ #include "arduino.h"</p><p>class PIR { int _input_pin;</p><p> public: PIR(const unsigned int input_pin) { _input_pin = input_pin; pinMode(_input_pin, INPUT); }</p><p> bool motion_detected() { return digitalRead(_input_pin) == HIGH; } }; #endif</p>
Dat is alle code die u nodig hebt. Nu u naar uw Arduino en test, uploaden kan of alles werkt zoals het zou moeten, voordat die zich bezighouden met hoogspanning en montage geval voor uw apparaat.
Ook bijgevoegde ik bestanden met codes. Op mijn machine verzamelt alles zonder problemen.