Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- SammyDoor!
- Automatic door for my cat. This sketch unlocks and props open a door when my cat wants to enter or exit the house. There is an ultrasonic range finder on the
- inside of the house for when he wants to exit and an IR break beam sensor inside the box for when he wants to enter. There are three temp sensors on the
- OneWire box. There is also a magnetic door switch that senses when the door is fully closed. Photos will be posted soon.
- steve.a.mccluskey@gmail.com
- Revision history:
- V1.0: Prototype release.
- V1.1: Added 2nd and 3rd temp sensor on OneWire bus. There is now a sensor in the room, inside the insulated box and outside to get an idea of the
- temperature gradient and see how well the insulation is working. 11/12/15.
- Hardware used:
- Arduino Uno.
- Adafruit ProtoShield.
- Adafruit I2C MotorShield.
- Adafruit I2C LCD Backpack.
- 16x2 Standard LCD.
- DS18B20 OneWire digital waterproof temp sensor (3x).
- Magnetic door sensor.
- 5V voltage regulator.
- Micro servo to simulate door lock.
- Large servo to prop door open.
- Pin layout as follows:
- 0 : Hardware serial RX.
- 1 : Hardware serial TX.
- 2 :
- 3 ~:
- 4 : Magnetic door sensor.
- 5 ~: Break beem sensor.
- 6 ~: OneWire bus.
- 7 : Ultrasonic range finder trigger pin.
- 8 : Ultrasonic range finder echo pin.
- 9 ~: Door servo.
- 10~: Lock servo.
- 11~:
- 12 : Green LED on protoshield.
- 13 : Red LED on protoshield.
- A0 :
- A1 :
- A2 :
- A3 :
- A4 : I2C SDA.
- A5 : I2C SCL.
- Sketch outline:
- Libraries.
- Pin declarations.
- Global values.
- Timer values.
- Sensor variables.
- Boolean variables.
- Objects.
- setup().
- loop() {
- }
- openTheDoor().
- closeTheDoor().
- lockDoor().
- unlockDoor().
- printResults().
- cToF().
- getOneWireTemp().
- */
- #include <Wire.h>
- #include <Adafruit_MotorShield.h>
- #include "utility/Adafruit_PWMServoDriver.h"
- #include <NewPing.h>
- #include <Servo.h>
- #include <Wire.h>
- #include <OneWire.h>
- #include <LiquidTWI.h>
- //#define includeMotor // Comment out to remove all motor code.
- #define debug // Comment out to skip printResults().
- // Global values:
- #define doorSensor 4 // Magnetic sensor on door.
- #define beamSensor 5 // Break beam sensor.
- #define oneWireBus 6 // OneWire bus.
- #define TRIGGER_PIN 7 // Arduino pin tied to trigger pin on the ultrasonic sensor.
- #define ECHO_PIN 8 // Arduino pin tied to echo pin on the ultrasonic sensor.
- #define doorServoPin 9 // Door servo.
- #define lockServoPin 10 // Lock servo.
- #define greenLed 12 // Green LED on protoshield.
- #define redLed 13 // Red LED on protoshield.
- #define MAX_DISTANCE 150 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
- #define triggerDistance 75 // Distance threshold.
- #define readingInterval 500 // Interval between readings in ms.
- #define doorCloseTimeout 8000 // How long to keep the door open.
- #define lockTimeout 5000 // How long to keep the door unlocked after closing.
- #define doorClosedPos 130 // Closed position for door servo.
- #define doorOpenPos 70 // Open position for door servo.
- #define doorLockPos 0 // Locked position for lock servo.
- #define doorUnlockPos 170 // Unlocked posittion for lock servo.
- // Timer variables:
- unsigned long timeNow;
- unsigned long timeDoorOpen;
- unsigned long timeLast;
- //unsigned long detachDelay = 500;
- unsigned long lockDelay;
- // Sensor variables:
- uint8_t dists[8] = {150, 150, 150, 150, 150, 150, 150, 150}; // Array to store distances. Set to high value by default so a low average doesnt cause door to open upon startup.
- uint8_t beams[8] = {0}; // Array to store beam readings.
- uint8_t slot = 0;
- uint16_t avgDist = 0;
- uint8_t avgBeams = 0;
- // Booleans:
- bool doorOpen = false;
- bool doorLocked = false;
- bool doorClear = false;
- bool lockReset = false;
- bool beamClear = false;
- // Objects:
- NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
- Servo doorServo;
- Servo lockServo;
- OneWire oneWire(oneWireBus);
- byte sensor1 [8]; // Arrays to store OneWire device's address.
- byte sensor2 [8];
- byte sensor3 [8];
- int8_t tempOut = 0;
- int8_t tempBox = 0;
- int8_t tempIn = 0;
- #ifdef includeMotor
- Adafruit_MotorShield AFMS = Adafruit_MotorShield();
- Adafruit_StepperMotor *myStepper = AFMS.getStepper(513, 2);
- Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1);
- Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2);
- #endif
- LiquidTWI lcd(1); // LCD on I2C Backpack.
- void setup() {
- Serial.begin(19200);
- lcd.begin(16, 2);
- lcd.setCursor(0, 0);
- lcd.print(F("SammyDoor!"));
- lcd.setCursor(0, 1);
- lcd.print(F("V 1.1"));
- delay(1000);
- lcd.clear();
- doorServo.attach(doorServoPin);
- lockServo.attach(lockServoPin);
- doorServo.write (doorClosedPos);
- lockServo.write (doorUnlockPos);
- delay(500);
- doorServo.detach();
- //lockServo.detach();
- pinMode(doorSensor, INPUT_PULLUP);
- pinMode(beamSensor, INPUT_PULLUP);
- pinMode(greenLed, OUTPUT);
- pinMode(redLed, OUTPUT);
- oneWire.search(sensor1);
- oneWire.search(sensor2);
- oneWire.search(sensor3);
- #ifdef includeMotor
- AFMS.begin();
- myStepper->setSpeed(50);
- myMotor1->setSpeed(75);
- myMotor1->run(RELEASE);
- myMotor2->setSpeed(75);
- myMotor2->run(RELEASE);
- #endif
- } // end setup().
- void loop() {
- timeNow = millis();
- lcd.setCursor(0, 0);
- lcd.print(F("I:"));
- lcd.print(tempIn);
- lcd.print(F("F "));
- lcd.print(F("B:"));
- lcd.print(tempBox);
- lcd.print(F("F "));
- lcd.print(F("O:"));
- lcd.print(tempOut);
- lcd.print(F("F "));
- lcd.setCursor(0, 1);
- lcd.print(F("Door: "));
- if (!doorOpen && doorLocked) {
- lcd.print(F("Locked. "));
- }
- else if (!doorOpen && !doorLocked) {
- lcd.print(F("Unlocked. "));
- }
- else if (doorOpen) {
- lcd.print(F("Open! "));
- }
- if (digitalRead(doorSensor) == LOW) {
- // Read door sensor every time thru loop. Input is pulled low when door is closed.
- doorClear = true;
- digitalWrite(redLed, LOW);
- if (!lockReset) {
- lockDelay = timeNow;
- lockReset = true;
- } // end if.
- } // end if.
- else {
- doorClear = false;
- digitalWrite(redLed, HIGH);
- lockReset = false; // Reset lock timer if door is opened.
- } // end else.
- if (timeNow - timeLast > readingInterval) { // Wait 500ms between readings.
- tempOut = cToF(getOneWireTemp(sensor1)); // Get OneWire temp and convert to F.
- tempBox = cToF(getOneWireTemp(sensor2));
- tempIn = cToF(getOneWireTemp(sensor3));
- dists[slot] = sonar.ping_cm(); // Store distance to current array slot.
- if (dists[slot] < 15) { // Prevent erranious low pings.
- dists[slot] = 86;
- }
- if (digitalRead(beamSensor) == HIGH) {
- beams[slot] = 0; // Save zero value to array.
- digitalWrite(greenLed, LOW);
- beamClear = true;
- } // end if.
- else {
- beamClear = false;
- beams[slot] = 10; // Save value 10 to array.
- digitalWrite(greenLed, HIGH);
- } // end else.
- avgDist = 0;
- avgBeams = 0;
- for (uint8_t x = 0; x < 8; x ++) { // Add them up.
- avgDist += dists[x];
- avgBeams += beams[x];
- } // end for.
- avgDist /= 8; // Average them.
- avgBeams /= 8;
- #ifdef debug
- printResults(); // For debugging.
- #endif
- slot ++; // Increment slot.
- if (slot > 7) { // reset to zero if 8.
- slot = 0;
- } // end if.
- timeLast = timeNow; // Reset reading timer.
- } // end if.
- // Open door logic:
- if ((avgDist <= triggerDistance && avgDist > 0) || avgBeams >= 9) {
- unlockDoor ();
- openTheDoor();
- timeDoorOpen = timeNow; // Reset timer to hold door open.
- } // end if.
- // Close door logic:
- else if ((avgDist > triggerDistance || avgBeams < 2) && (timeNow - timeDoorOpen > doorCloseTimeout)) {
- closeTheDoor();
- if (doorClear) {
- lockDoor();
- } // end if.
- } // end else if.
- } // end loop().
- void openTheDoor() {
- if (!doorOpen) {
- doorServo.attach(doorServoPin);
- doorServo.write (doorOpenPos);
- delay(500);
- doorServo.detach();
- //delay(250);
- doorOpen = true;
- } // end if.
- } // end openTheDoor().
- void closeTheDoor() {
- if (doorOpen) {
- doorServo.attach(doorServoPin);
- doorServo.write(doorClosedPos);
- doorOpen = false;
- delay(500);
- doorServo.detach();
- } // end if.
- } // end closeTheDoor().
- void lockDoor() {
- if (!doorLocked && (timeNow - lockDelay > lockTimeout)) {
- #ifdef includeMotor
- myStepper->step(100, FORWARD, DOUBLE);
- myMotor1->setSpeed(75);
- myMotor2->setSpeed(75);
- myMotor1->run(FORWARD);
- myMotor2->run(FORWARD);
- #endif
- lockServo.attach(lockServoPin);
- lockServo.write(doorLockPos);
- delay(500);
- lockServo.detach();
- #ifdef includeMotor
- myMotor1->setSpeed(0);
- myMotor2->setSpeed(0);
- #endif
- lockServo.detach();
- doorLocked = true;
- } // end if.
- } // end lockDoor().
- void unlockDoor() {
- if (doorLocked) {
- #ifdef includeMotor
- myStepper->step(100, BACKWARD, DOUBLE);
- myMotor1->setSpeed(75);
- myMotor2->setSpeed(75);
- myMotor1->run(BACKWARD);
- myMotor2->run(BACKWARD);
- delay(500);
- #endif
- lockServo.attach(lockServoPin);
- lockServo.write (doorUnlockPos);
- delay(500);
- lockServo.detach();
- #ifdef includeMotor
- myMotor1->setSpeed(0);
- myMotor2->setSpeed(0);
- #endif
- doorLocked = false;
- } // end if.
- } // end unlockDoor().
- void printResults() { // For debugging.
- Serial.print(F("Current slot: "));
- Serial.println(slot);
- Serial.print(F("Distance: "));
- Serial.print(dists[slot]);
- Serial.println(F("cm"));
- for (uint8_t x = 0; x < 8; x ++) {
- Serial.print(dists[x]);
- Serial.print(" ");
- } // end for.
- Serial.println();
- Serial.print (F("Avg: "));
- Serial.println(avgDist);
- if (beamClear) {
- Serial.println(F("Sensor: Clear"));
- } // end if.
- else {
- Serial.println(F("Sensor: BLOCKED!"));
- } // end else.
- for (uint8_t x = 0; x < 8; x ++) {
- Serial.print(beams[x]);
- Serial.print(" ");
- } // end for.
- Serial.println();
- Serial.print (F("Beams: "));
- Serial.println(avgBeams);
- if (!doorLocked) {
- Serial.println(F("Door: Unlocked."));
- } // end if.
- else {
- Serial.println(F("Door: locked."));
- } // end else.
- if (doorOpen) {
- Serial.println(F("Door state: OPEN!"));
- } // end if.
- else {
- Serial.println(F("Door state: closed."));
- } // end else.
- if (doorClear) {
- Serial.println(F("Door: clear."));
- } // end if.
- else {
- Serial.println(F("Door: blocked"));
- } // end else.
- Serial.print(F("Current outside temp: "));
- Serial.print(tempOut);
- Serial.println(F(" F"));
- Serial.print(F("Current box temp : "));
- Serial.print(tempBox);
- Serial.println(F(" F"));
- Serial.print(F("Current inside temp : "));
- Serial.print(tempIn);
- Serial.println(F(" F"));
- Serial.println();
- } // end printResults().
- int8_t cToF(float c) { // Convert float C to int F.
- return round((1.8 * c) + 32.0);
- } // end cToF().
- int8_t getOneWireTemp(byte *str) { // Get OneWire temp.
- byte data[2]; // Array to store data retrieved from sensor.
- oneWire.reset ();
- oneWire.select(str);
- oneWire.write (0x44, 1); // start conversion.
- oneWire.reset ();
- oneWire.select(str);
- oneWire.write (0xBE); // Read scratchpad.
- for (byte i = 0; i < 2; i ++) {
- data[i] = oneWire.read(); // Collect data.
- } // end for.
- int16_t raw = (data[1] << 8) | data[0]; // Convert raw data to C.
- return round((float)raw / 16.0);
- } //end getOneWireTemp().
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement