Parking Sensor Node


  • Hero Member

    Working on the bench will install soon

    Build a MySensors node to indicate when a vehicle is clear of the roller door when parking. As well as providing a visual aid for parking node will send door open/close data to the gateway. This can be used for security checks etc. by your controller. The LED strip will show three different colours

    Red for when the car is in the danger area under the door
    Green for when the car has cleared the door
    White for a courtesy light to allow you to exit the vehicle

    Sensor will be powered by 12v from the house auxiliary supply.

    An infrared beam will be used across the door to determine when vehicle has cleared the door area. I am using a pre built IR door minder, as these can be bought for less than $8 and are in nice cases as well. Just not worth the hassle of building them from scratch

    A 5v WS2811 RGB LED strip will be used to indicate vehicle position. I have used this type as they are simple to wire in, no need for driver transistors etc. I have used the fastled library to control the strip.

    A N/O reed switch will be used for the garage door switch. I will mount a magnet on the door which will activate the reed switch when the door is closed

    sketch

    /**
     *******************************
     *
     * DESCRIPTION
     * A node to indicate correct parking position to allow closing of garage door.
     * uses a pre built IR beam "door minder" to detect car position
     *
     * Connect N/O contacts of Infrared device between 
     *  pin 3  and GND.
     * 
     * Connect a N/O reed switch between GND and pin 2
     * 
     * Connect RGB Led strip data terminal to pin 4
     * 
     */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #define FASTLED_FORCE_SOFTWARE_SPI
    #include "FastLED.h"
    
    #define NUM_LEDS 18                                        // How many leds are in the strip? change this to the number of LEDs in your strip
    #define DATA_PIN 4                                         // Data pin that led data will be written out over
    #define CHILD_ID 0                                         // door switch MySensors id number
    #define IR_PIN  3                                          // Arduino Digital I/O pin for infrared device 
    #define DOOR_PIN 2                                         // pin garage door switch is connected to
    #define COLOR_ORDER  GRB                                   // if your not getting the right colours change the oder of GRB
    #define CHIPSET  WS2811                                    // select the led type
    
    int marker = 0;                           // used to decide if LEDs are allowed to turn white
    int irValue ;                             // holder for ir state
    int doorValue ;                           // holder for garage door state
    int oldDoorValue=-1;                      //set to -1 to ensure current door switch status is sent at startup
    unsigned long startMillis = 0;            // holder for the time when garage door first opens
    unsigned long millisNow = 0;              // holder for the current time
    const long activeTime = 120000;           // Time the sensor will stay active after garage door is opened in milliseconds. change this to suit your situation  
    
     CRGB leds[NUM_LEDS];                              // This is an array of leds.  One item for each led in your strip.
     MySensor gw;
     Bounce debouncerA = Bounce();                    // Instantiate  Bounce object 1.... iR switch
     Bounce debouncerB = Bounce();                    // Instantiate  Bounce object 2.... Garage Door switch
     MyMessage msg(CHILD_ID,V_TRIPPED);
    
    
    
    void setup() {
     
      gw.begin();
      gw.sendSketchInfo("Park Sensor", "1");    // Send the sketch version information to the gateway and Controller
      
      FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);       //Setup fastleds
     
        /* ----Setup the buttons as inputs and activate their internal pull-up resistor----  */
      pinMode(IR_PIN,INPUT_PULLUP);               //set pin as input and activate internal pull-up resistor
      pinMode(DOOR_PIN,INPUT_PULLUP);             //set pin as input and activate internal pull-up resistor
    
        /* ---After setting up the buttons, setup debouncers---- */
      debouncerA.attach(IR_PIN);
      debouncerA.interval(5);
      debouncerB.attach(DOOR_PIN);
      debouncerB.interval(5);
      gw.present(CHILD_ID, S_DOOR);            // Register binary input sensor to gw
      ledChange (0,0,0) ;                      //  Make sure LEDs are off at statup, set to black  
     
    }
    
    void loop() {
     
     updateSwitches();               // call function to check switches status
     millisNow = millis();           // get the current time  
     
     if (millisNow - startMillis < activeTime){    // check to see if timeout has been reached
      if (doorValue == HIGH ) {                    // garage door is open
       if (irValue == LOW ) {                      // car is in ir beam 
        ledChange(255,0,0);                        // turn LEDs red
       }
       else{
        ledChange(0,128,0);                       // car is out of ir beam, turn LEDs green
       }
      }
      else{
       if (marker == 1){
        ledChange(255,255,255);                  // door down but timer not finished. turn leds white for entry mode
       }
      }
     }
     else {                                     // Timeout has been reached. Turn off LEDs
      if (marker == 1){                          // check marker to only turn off if needed
       ledChange (0,0,0) ;                     //    turn off leds (black)
       marker = 0; 
      }
     }
    }
    
    
    /* --------------start of functions-------------- */
    
    /* --Update the switches status, send door state change if required -- */
     void updateSwitches (){
      debouncerA.update();                          // IR switch
      debouncerB.update();                          // Door switch
      irValue = debouncerA.read();                  // get the state of the IR switch
      doorValue = debouncerB.read();                // get the state of the Door switch
      if (doorValue != oldDoorValue) {             // Check if digital input has changed and send in new value if it has
       gw.send(msg.set(doorValue==HIGH ? 1 : 0));  // Send in the new value
        if (doorValue == HIGH){                    // door is open       
         startMillis = millis();                   // store start time of door opening  for timeout check
         marker = 1;                               
        }
       oldDoorValue = doorValue;
      }
     }
     
    /* ----------function to change LED color------------*/
     void ledChange (int r, int g, int b) {
      for(int ledStrip =0; ledStrip < NUM_LEDS; ledStrip++) {
       leds[ledStrip] = CRGB( r, g, b);
      }
      FastLED.show();
     }
    
    

    Wiring

    0_1463902428600_parking hookup.jpg


  • Hero Member

    Made a small change to the sketch. LEDs used to go off instantly when timer expired, now they fade out slowly.

    /**
     *******************************
     *
     * DESCRIPTION
     * A node to indicate correct parking position to allow closing of garage door.
     * uses a pre built IR beam "door minder" to detect car position
     *
     * Connect N/O contacts of Infrared device between 
     *  pin 3  and GND.
     * 
     * Connect a N/O reed switch between GND and pin 2
     * 
     * Connect RGB Led strip data terminal to pin 4
     * 
     */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #define FASTLED_FORCE_SOFTWARE_SPI
    #include "FastLED.h"
    
    #define NUM_LEDS 18                                        // How many leds are in the strip? change this to the number of LEDs in your strip
    #define DATA_PIN 4                                         // Data pin that led data will be written out over
    #define CHILD_ID 0                                         // door switch MySensors id number
    #define IR_PIN  3                                          // Arduino Digital I/O pin for infrared device 
    #define DOOR_PIN 2                                         // pin garage door switch is connected to
    #define COLOR_ORDER  GRB                                   // if your not getting the right colours change the oder of GRB
    #define CHIPSET  WS2811                                    // select the led type
    
    int marker = 0;                           // used to decide if LEDs are allowed to turn white
    int irValue ;                             // holder for ir state
    int doorValue ;                           // holder for garage door state
    int oldDoorValue=-1;                      //set to -1 to ensure current door switch status is sent at startup
    unsigned long startMillis = 0;            // holder for the time when garage door first opens
    unsigned long millisNow = 0;              // holder for the current time
    const long activeTime = 120000;           // Time the sensor will stay active after garage door is opened in milliseconds. change this to suit your situation  
    
     CRGB leds[NUM_LEDS];                              // This is an array of leds.  One item for each led in your strip.
     MySensor gw;
     Bounce debouncerA = Bounce();                    // Instantiate  Bounce object 1.... iR switch
     Bounce debouncerB = Bounce();                    // Instantiate  Bounce object 2.... Garage Door switch
     MyMessage msg(CHILD_ID,V_TRIPPED);
    
    
    
    void setup() {
     
      gw.begin();
      gw.sendSketchInfo("Park Sensor", "1");    // Send the sketch version information to the gateway and Controller
      
      FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);       //Setup fastleds
     
        /* ----Setup the buttons as inputs and activate their internal pull-up resistor----  */
      pinMode(IR_PIN,INPUT_PULLUP);               //set pin as input and activate internal pull-up resistor
      pinMode(DOOR_PIN,INPUT_PULLUP);             //set pin as input and activate internal pull-up resistor
    
        /* ---After setting up the buttons, setup debouncers---- */
      debouncerA.attach(IR_PIN);
      debouncerA.interval(5);
      debouncerB.attach(DOOR_PIN);
      debouncerB.interval(5);
      gw.present(CHILD_ID, S_DOOR);            // Register binary input sensor to gw
      ledChange (0,0,0) ;                      //  Make sure LEDs are off at statup, set to black  
     
    }
    
    void loop() {
     
     updateSwitches();               // call function to check switches status
     millisNow = millis();           // get the current time  
     
     if (millisNow - startMillis < activeTime){    // check to see if timeout has been reached
      if (doorValue == HIGH ) {                    // garage door is open
       if (irValue == LOW ) {                      // car is in ir beam 
        ledChange(255,0,0);                        // turn LEDs red
       }
       else{
        ledChange(0,255,0);                       // car is out of ir beam, turn LEDs green
       }
      }
      else{
       if (marker == 1){
        ledChange(255,255,255);                  // door down but timer not finished. turn leds white for entry mode
       }
      }
     }
     else {                                             // Timeout has been reached. Turn off LEDs
      if (marker == 1){                                 // check marker to only turn off if needed
    //ledChange (0,0,0) ;                              //    turn off leds (black)
       for(int ledStrip =0; ledStrip < NUM_LEDS; ledStrip++) {
       leds[ledStrip].fadeToBlackBy( 1 );                // fade leds off
       FastLED.delay(1);
      }
     FastLED.show();
       marker = 0; 
      }
     }
    }
    
    
    /* --------------start of functions-------------- */
    
    /* --Update the switches status, send door state change if required -- */
     void updateSwitches (){
      debouncerA.update();                          // IR switch
      debouncerB.update();                          // Door switch
      irValue = debouncerA.read();                  // get the state of the IR switch
      doorValue = debouncerB.read();                // get the state of the Door switch
      if (doorValue != oldDoorValue) {             // Check if digital input has changed and send in new value if it has
       gw.send(msg.set(doorValue==HIGH ? 1 : 0));  // Send in the new value
        if (doorValue == HIGH){                    // door is open       
         startMillis = millis();                   // store start time of door opening  for timeout check
         marker = 1;                               
        }
       oldDoorValue = doorValue;
      }
     }
     
    /* ----------function to change LED color------------*/
     void ledChange (int r, int g, int b) {
      for(int ledStrip =0; ledStrip < NUM_LEDS; ledStrip++) {
       leds[ledStrip] = CRGB( r, g, b);
      }
      FastLED.show();
     }
    
    

  • Hero Member

    Set this all up last week and ran in to a problem with the code. The arduino would lock up after running for around 30 hours, it would seem there may be some form of conflict between the fastled and mysensors libraries when it comes to spi use.

    Anyway I seem to have it working by forcing fastled to use software spi with

    #define FASTLED_FORCE_SOFTWARE_SPI
    

    I have changed both sketches to include this line and so far all seems good, it has been running ok for 3 days now so hopefully that has it sorted.


  • Hero Member

    This has been running without trouble for a couple of weeks now so it looks to be ok. just posting a couple of pics

    I have used the Easy pcb https://www.openhardware.io/view/4/EasyNewbie-PCB-for-MySensors by @sundberg84 . here it is in the case, the mounting pillars even lined up to the boards screw holes!

    0_1466827297676_box1.jpg

    Here is the case all closed and ready to mount

    0_1466827461603_box2.jpg

    To hold the magnet I cut the spindle of of an old dvd holder and glued the magnet inside. For the reed switch I used an old pen case, the reed switch was a neat fit inside.

    0_1466827790349_switches.jpg


  • Hero Member

    Updated the sketch for MySensors V2 and am now using the Adafruit Neopixel library

    /**
     *******************************
     *
     * DESCRIPTION
     * A node to indicate correct parking position to allow closing of garage door.
     * uses a pre built IR beam "door minder" to detect car position
     *MySensors V2 and using Adafruit neopixel library and bounce2 library
     * Connect N/O contacts of Infrared device between 
     *  pin 3  and GND.
     * 
     * Connect a N/O reed switch between GND and pin 2
     * 
     * Connect RGB Led strip data terminal to pin 4
     * 
     */
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #include "MySensors.h"  
    
    #include <SPI.h>
    #include <Bounce2.h>
    #include <Adafruit_NeoPixel.h>
    
    #define NUM_LEDS 18                                        // How many leds are in the strip? change this to the number of LEDs in your strip
    #define PIN 4                                         // Data pin that led data will be written out over
    #define CHILD_ID 0                                         // door switch MySensors id number
    #define IR_PIN  3                                          // Arduino Digital I/O pin for infrared device 
    #define DOOR_PIN 2                                         // pin garage door switch is connected to
    
    
    int marker = 0;                           // used to decide if LEDs are allowed to turn white
    int irValue ;                             // holder for ir state
    int doorValue ;                           // holder for garage door state
    int oldDoorValue=-1;                      //set to -1 to ensure current door switch status is sent at startup
    unsigned long startMillis = 0;            // holder for the time when garage door first opens
    unsigned long millisNow = 0;              // holder for the current time
    const long activeTime = 120000;           // Time the sensor will stay active after garage door is opened in milliseconds. change this to suit your situation  
    
    
     Bounce debouncerA = Bounce();                    // Instantiate  Bounce object 1.... iR switch
     Bounce debouncerB = Bounce();                    // Instantiate  Bounce object 2.... Garage Door switch
     MyMessage msg(CHILD_ID,V_TRIPPED);
    
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = Arduino pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
    
    
    void setup() {
     
    
        /* ----Setup the buttons as inputs and activate their internal pull-up resistor----  */
      pinMode(IR_PIN,INPUT_PULLUP);               //set pin as input and activate internal pull-up resistor
      pinMode(DOOR_PIN,INPUT_PULLUP);             //set pin as input and activate internal pull-up resistor
    
        /* ---After setting up the buttons, setup debouncers---- */
      debouncerA.attach(IR_PIN);
      debouncerA.interval(5);
      debouncerB.attach(DOOR_PIN);
      debouncerB.interval(5);
      strip.begin();
      strip.show();        // Initialize all pixels to 'off'
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Park Sensor", "2.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID, S_DOOR);            // Register binary input sensor to gw
     }
    
    
    
    void loop() {
     
     updateSwitches();               // call function to check switches status
     millisNow = millis();           // get the current time  
     
     if (millisNow - startMillis < activeTime){    // check to see if timeout has been reached
      if (doorValue == HIGH ) {                    // garage door is open
       if (irValue == LOW ) {                      // car is in ir beam 
         ledChange(strip.Color(255, 0, 0));       // car is blocking ir beam,turn LEDs red
       }
       else{
          ledChange(strip.Color(0, 255, 0));      // car is out of ir beam, turn LEDs green
       }
      }
      else{
       if (marker == 1){
          ledChange(strip.Color(127, 127, 127));  // door down but timer not finished. turn leds white for entry mode
       }
      }
     }
     else {                                             // Timeout has been reached. Turn off LEDs
      if (marker == 1){                                 // check marker to only turn off if needed
      ledChange(strip.Color(0, 0, 0));                  // turn off leds (black)
      marker = 0; 
      }
     }
    }
    
    
    /* --------------start of functions-------------- */
    
    /* --Update the switches status, send door state change if required -- */
     void updateSwitches (){
      debouncerA.update();                          // IR switch
      debouncerB.update();                          // Door switch
      irValue = debouncerA.read();                  // get the state of the IR switch
      doorValue = debouncerB.read();                // get the state of the Door switch
      if (doorValue != oldDoorValue) {             // Check if digital input has changed and send in new value if it has
       send(msg.set(doorValue==HIGH ? 1 : 0));     // Send in the new value
        if (doorValue == HIGH){                    // door is open       
         startMillis = millis();                   // store start time of door opening  for timeout check
         marker = 1;                               
        }
       oldDoorValue = doorValue;
      }
     }
     
    
    
     /* ----------function to change LED color------------*/
    void ledChange(uint32_t c) {
      for(uint16_t i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, c);   
      }
      strip.show();
    }
    

Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.