Help with sketch...



  • This is what I want to do:
    when motionsensor is triggered run distance-sensors for 10 seconds and then sleep.

    I think I have most of the parts working but I am struggeling with how to combine all the sketches. I have tried several times and think I managed to combine the first two at one time. But then everything just stoped working after trying to add the timer part.

    This is the distance-sensor-sketch which kind of works most of the time (And is just supposed to tell if I someone enters or leaves a room :

    #include <NewPing.h>
    #include <Bounce2.h>
    #include <SPI.h>
    
    #define SONAR_NUM     2 // Number of sensors.
    #define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
    #define PING_INTERVAL 40 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
    
    
    int ledPin = 4;
    //Bounce debouncer = Bounce(); 
    //int oldValue=-1;
    
    unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
    unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
    uint8_t currentSensor = 0;          // Keeps track of which sensor is active.
    int dirA = 0;
    int dirB = 0;
    
    int val = 0;
    #define BUTTON_PIN  3  // Arduino Digital I/O pin for button/reed switch
    int doorDistance = 65;
    
    boolean bigChange_0;  //SensorA
    boolean bigChange_1;  //SensorB
    
    NewPing sonar[SONAR_NUM] = {     // Sensor object array.
      NewPing(8, 7, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
      NewPing(6, 5, MAX_DISTANCE)
      
    };
    
    void setup() {
      Serial.begin(115200);
      pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
      for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
        pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
    
         // Setup the button
      pinMode(BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN,HIGH);
    
    
    
       pinMode(ledPin, OUTPUT);  // declare LED as output
    }
    
    void loop() {
      for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
        if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
          pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
          if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
          sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
          currentSensor = i;                          // Sensor being accessed.
          cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
          sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
        }
      }
      // Other code that *DOESN'T* analyze ping results can go here.
      val = digitalRead(BUTTON_PIN);  // read input value
      if (val == HIGH) {         // check if the input is HIGH (button released)
        digitalWrite(ledPin, LOW);  // turn LED OFF
      } else {
        digitalWrite(ledPin, HIGH);  // turn LED ON
        
        int measure = (int)cm[0];
        if(measure != doorDistance && measure != 0){
           Serial.print(measure);
           Serial.println();
           doorDistance = measure;
           
          }
       
      }
         
         // Send in the new value
        // send(msg.set(value==HIGH ? 1 : 0));
    }
    
    void echoCheck() { // If ping received, set the sensor distance to array.
      if (sonar[currentSensor].check_timer())
        cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
    }
    
    void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
      
      bigChange_0 = ((doorDistance-(int)cm[0]) > 10)?true:false;
      bigChange_1 = ((doorDistance-(int)cm[1]) > 10)?true:false;
    
      if(bigChange_0 && bigChange_1){
     
          if(dirA > dirB){
              Serial.print("Entering Room");
              Serial.println();
              dirA = 0;
              dirB = 0;
            }
            else if(dirA < dirB){
              Serial.print("Leaving Room");
              Serial.println();
              dirA = 0;
              dirB = 0;
              }
            else{
              dirA = 0;
              dirB = 0;
              }  
        }
      else if(bigChange_0){
          dirA=1;
      }
      else if(bigChange_1){
         dirB=1;
        }
      else {
        dirA = 0;
        dirB = 0;
        }
      }
    

    This is the standard motion-sensor-sketch:

    // Enable debug prints
    // #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    void loop()
    {
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    

    And this is the blink_without_delay-sketch from the arduino site which uses a timer:

    // Generally, you should use "unsigned long" for variables that hold time
    // The value will quickly become too large for an int to store
    unsigned long previousMillis = 0;        // will store last time LED was updated
    
    // constants won't change :
    const long interval = 10000;           // interval at which to blink (milliseconds)
    
    void setup() {
      // set the digital pin as output:
      pinMode(ledPin, OUTPUT);
    }
    
    void loop() {
      // here is where you'd put code that needs to be running all the time.
    
      // check to see if it's time to blink the LED; that is, if the
      // difference between the current time and last time you blinked
      // the LED is bigger than the interval at which you want to
      // blink the LED.
      unsigned long currentMillis = millis();
    
      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
    
        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }
    
        // set the LED with the ledState of the variable:
        digitalWrite(ledPin, ledState);
      }
    }
    

  • Contest Winner

    @Cliff-Karlsson

    You might try this piece of code
    It only contains the start and stop mechanism for the distance sensor based on the PIR status. The distance measurement code you need to add youself

    // Enable debug prints
    // #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    #include <Bounce2.h>
    
    #define DIGITAL_INPUT_SENSOR 3 
    #define CHILD_ID 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    // Instantiate a Bounce object
    Bounce debouncer = Bounce(); 
    unsigned long distanceTimer = 0;
    #define DISTANCEMEASURETIME (10 * 1000)
    
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        // After setting up the button, setup the Bounce instance :
        debouncer.attach(DIGITAL_INPUT_SENSOR);
        debouncer.interval(5); // interval in ms
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    void loop()
    {
        // Check if the PIR sensor has been changed
        if (debouncer.update()) {
           // Read digital motion value
           bool tripped = (debouncer.read() == HIGH);
    
           Serial.println(tripped);
           send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
           if (tripped) {
              distanceTimer = millis() + DISTANCEMEASURETIME;
           }
        }
    
        // Check if we need to measure distance
        if (distanceTimer > 0) {
           if (millis() > distanceTimer) {
               // No times up stop reset the timer
               distanceTimer = 0;
           }  else {
    
                // Loop through all the sensors.
                // add the distance measurement code here
    
    
                ///.....
           
           }
        }
    }
    


  • @BartE Thanks for the help but I can't get it to work. I Only get alot of radio errors:

    0 MCO:BGN:INIT NODE,CP=RNNNA--,VER=2.1.1
    3 TSM:INIT
    4 TSF:WUR:MS=0
    11 !TSM:INIT:TSP FAIL
    12 TSM:FAIL:CNT=1
    14 TSM:FAIL:PDT

    I also tried commenting out all mysensors stuff, but I got no reactions at al from leds or serial monitor.
    I am using a UNO with a separate 12v power supply attached so it can't be power related right?

    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    #include <Bounce2.h>
    #include <SPI.h>
    #include <NewPing.h>
    
    #define DIGITAL_INPUT_SENSOR 3 
    #define CHILD_ID 1   // Id of the sensor child
    
    #define SONAR_NUM     2 // Number of sensors.
    #define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
    #define PING_INTERVAL 40 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
    
    
    int ledPin = 4;
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    // Instantiate a Bounce object
    Bounce debouncer = Bounce(); 
    unsigned long distanceTimer = 0;
    #define DISTANCEMEASURETIME (10 * 1000)
    unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
    unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
    uint8_t currentSensor = 0;          // Keeps track of which sensor is active.
    int dirA = 0;
    int dirB = 0;
    
    int val = 0;
    #define BUTTON_PIN  1  // Arduino Digital I/O pin for button/reed switch
    int doorDistance = 65;
    
    boolean bigChange_0;  //SensorA
    boolean bigChange_1;  //SensorB
    
    NewPing sonar[SONAR_NUM] = {     // Sensor object array.
      NewPing(8, 7, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
      NewPing(6, 5, MAX_DISTANCE)
      
    };
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        // After setting up the button, setup the Bounce instance :
        debouncer.attach(DIGITAL_INPUT_SENSOR);
        debouncer.interval(5); // interval in ms
          Serial.begin(115200);
      pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
      for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
        pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
    
         // Setup the button
      pinMode(BUTTON_PIN,INPUT);
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN,HIGH);
    
    
    
       pinMode(ledPin, OUTPUT);  // declare LED as output
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    void loop()
    {
        // Check if the PIR sensor has been changed
        if (debouncer.update()) {
           // Read digital motion value
           bool tripped = (debouncer.read() == HIGH);
    
           Serial.println(tripped);
         //  send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
           if (tripped) {
              distanceTimer = millis() + DISTANCEMEASURETIME;
           }
        }
    
        // Check if we need to measure distance
        if (distanceTimer > 0) {
           if (millis() > distanceTimer) {
               // No times up stop reset the timer
               distanceTimer = 0;
           }  else {
    
                 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
        if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
          pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
          if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
          sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
          currentSensor = i;                          // Sensor being accessed.
          cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
          sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
        }
      }
      // Other code that *DOESN'T* analyze ping results can go here.
      val = digitalRead(BUTTON_PIN);  // read input value
      if (val == HIGH) {         // check if the input is HIGH (button released)
        digitalWrite(ledPin, LOW);  // turn LED OFF
      } else {
        digitalWrite(ledPin, HIGH);  // turn LED ON
        
        int measure = (int)cm[0];
        if(measure != doorDistance && measure != 0){
           Serial.print(measure);
           Serial.println();
           doorDistance = measure;
           
          }
       
      }
           
           }
        }
    }
    
    void echoCheck() { // If ping received, set the sensor distance to array.
      if (sonar[currentSensor].check_timer())
        cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
    }
    
    void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
      
      bigChange_0 = ((doorDistance-(int)cm[0]) > 10)?true:false;
      bigChange_1 = ((doorDistance-(int)cm[1]) > 10)?true:false;
    
      if(bigChange_0 && bigChange_1){
     
          if(dirA > dirB){
              Serial.print("Entering Room");
              Serial.println();
              dirA = 0;
              dirB = 0;
            }
            else if(dirA < dirB){
              Serial.print("Leaving Room");
              Serial.println();
              dirA = 0;
              dirB = 0;
              }
            else{
              dirA = 0;
              dirB = 0;
              }  
        }
      else if(bigChange_0){
          dirA=1;
      }
      else if(bigChange_1){
         dirB=1;
        }
      else {
        dirA = 0;
        dirB = 0;
        }
      }
    

  • Contest Winner

    @Cliff-Karlsson these radio errors normally are the result of no connection with the MySensors gateway.

    Please make sure you also remove the #include mysensors.h line when you want to comment out all MySensors stuff

    When you connect a Arduino board via USB to your PC no additional power supply is required, so to make sure the power is not causing the problems just disconnect te power.



  • Right BartE..
    On this forum i read about someone connecting both USB and a power supply at the same time, and blew up his Arduino.
    I do not know for sure what would happen, (never did that), but i'm not willing to test it out..



  • I did not know about the newPing.h library. (i can not find it when searching for it in the Arduino IDE).. so i googled it.
    The example (for 15 sensors) confuses me 🙂

    Can't you just do something like this?

    unsigned long pingTimer[SONAR_NUM];
    unsigned int cm[SONAR_NUM];
    boolean bigChange[SONAR_NUM];
    
    void setup() {
       pingTimer[0] = millis() + 75;
       pingTimer[1] = pingTimer[0] + PING_INTERVAL;
    }
    
    void loop() {
      // your rest code here..
             for (uint8_t i = 0; i < SONAR_NUM; i++)
               if (millis() >= pingTimer[i]) {
                 pingTimer[i] += PING_INTERVAL;
                 cm[i] = sonar.ping_cm();
                 bigChange[i] = ((doorDistance-(int)cm[i]) > 10)?true:false;
               }
             oneSensorCycle;
    

    And adjust oneSensorCycle() to use bigChange[0] & bigChange[1] instead of bigChange_0 & bigChange_1


Log in to reply
 

Suggested Topics

15
Online

11.4k
Users

11.1k
Topics

112.7k
Posts