Checking a reading is detected for a certain amount of time?

Hi,

Thank-you for your help before on the topic of making things for dogs, I am currently struggling with trying to only take the reading if it is detected for a certain amount of time (similar to debouncing in switches).

I have tried to code this in but it does not seem to be taking the time I set. Is there a way of checking that a code is within range for a certain period before taking the reading? Am I doing this totally wrong?

While I am aware sharp can mean the distance in the library fiddling with this too much seems to cause more false readings.

Thank-you for any guidance you can give,

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir A0
#define model 20150
#define LEDPin 13 // Onboard LED
#define ir1 A1

//unsigned long  minSample, maxSample;

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm

boolean shouldPress;

SharpIR sharp(ir, 5, 93, model);
SharpIR sharp1(ir1, 5, 93, model);


// new bit to average out
#define NBSAMPLES 100
unsigned long  lastMeasures[NBSAMPLES];
unsigned long  lastMeasures1[NBSAMPLES];
uint8_t currentSample;
uint8_t currentSample1;
uint8_t lastMinIndex, lastMaxIndex;
unsigned long  minSample, maxSample;

void setup()
{
    Serial.begin(9600);
    pinMode (ir, INPUT);
    pinMode (ir1, INPUT);
    pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
    currentSample = 0;
    currentSample1 = 0;
    minSample = 0xFFFFFFFF;
    maxSample = 0UL;
    lastMinIndex = 0;
    lastMaxIndex = 0;
}

void loop()
{
    unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    int dis1 = sharp1.distance(); // Returns the distance of the second sensor (pin A1)

    unsigned long pepe2 = millis() - pepe1; // the following gives you the time taken to get the measurement
    Serial.print("Time taken (ms): ");
    Serial.println(pepe2);
    
    Serial.print("Mean distance sensor 1: ");  // returns it to the serial monitor
    Serial.println(dis);

    Serial.print("Mean distance sensor 2: ");  // returns it to the serial monitor
    Serial.println(dis1);

  lastMeasures[currentSample] = dis;
  lastMeasures1[currentSample1] = dis1;
    

if ((dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange )){

    
        Serial.println("Dog detected in range");
        if(shouldPress == true)     // checks if keypress or LED needs to happen
        {
            digitalWrite(LEDPin, HIGH);
            Keyboard.press('d');
            shouldPress = false;    // sets to false so that it has happened
        }
    
}

else
    {
        Serial.println("out of range");
        digitalWrite(LEDPin, LOW);
        Keyboard.releaseAll();
        shouldPress = true;
    }
  
}

It looks like you are on the right track but not quite there yet! Note in your example, you take two samples (dis, dis1) immediately after each other so there is likely to be very little difference (in time or value) between them and you are only ensuring the signal is in range for a tiny fraction of time. You also never increment currentSample so I'm not sure the purpose of this. I

There are a few different ways you could tackle this problem.

  1. Average/Low pass filter the sensor data - this slows it down a little and removes high frequency noise. Using this method you could just wait until the low passed value dropped below a threshold
  2. Keep a history of the last n samples in an array and make sure all those samples are within range
  3. Use a loop to count for some length of time whilst the sensor data is in range

Each of these has various pros and cons ie.

  1. Low pass filtering us simple and robust to noise but you'll lose some response time
  2. Keeping a history of samples uses more memory and it can be a fiddle to move samples around in a buffer
  3. Using a loop to count up while the signal is in range is easy but it will hold up the CPU.

In my projects, i would almost always filter raw sensor data, even if only a little, as this makes the data much more usable and cleaner.

Here's a simple example using the loop method. It reads a sensor value and enters the while loop if it is in range after grabbing the time. It twill stay in the loop as long as dis is in range and checks how long this has been true by comparing millis() to t_start.

void loop()
{
   
    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    
    int t_start = millis(); // get the time before sensor data is in range
    while ((dis <= maximumRange && dis >= minimumRange) {

        // if sensor data has been withing range for some time
        if ((millis()-t_start) > SOME_THRESHOLD) {
            Serial.println("Dog detected in range");
            if(shouldPress == true)     // checks if keypress or LED needs to happen
            {
                digitalWrite(LEDPin, HIGH);
                Keyboard.press('d');
                shouldPress = false;    // sets to false so that it has happened
            }
        }

        dis = sharp.distance(); //get new sensor value

    }

crazydoglady:
Is there a way of checking that a code is within range for a certain period before taking the reading?

const unsigned long CertainPeriod = 5000UL;  // Must be in range 5 seconds or more
void loop() {
    static unsigned long startOfCertainPeriod = millis();  // 'static' sticks around between calls
    boolean codeIsWithinRange = however you determine that;
    if (codeIsWithinRange) {
         if (millis() - startOfCertainPeriod >= CertainPeriod) {
            // Act on the code being within range for at least a certain period
         }
    } else { // code is NOT within range
        startOfCertainPeriod = millis();  // Re-start the timer for how long code has been in range
    }
}

Hey Johnwasser and CatsLoveJazz (excellent name btw)

Thank-you for replying, I tried both of your methods,

John, when I tried your method it didn't take the readings and then after 5 seconds just random blips as usual so I am not sure if the way I have done it, it is just delaying or if I need to reset it at the end?

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir A0
#define model 20150
#define LEDPin 13 // Onboard LED
#define ir1 A1

//unsigned long  minSample, maxSample;

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm
const unsigned long CertainPeriod = 5000UL;  // Must be in range 5 seconds or more


boolean shouldPress;


SharpIR sharp(ir, 25, 93, model);
SharpIR sharp1(ir1, 25, 93, model);

// ir: the pin where your sensor is attached
// 25: the number of readings the library will make before calculating a mean distance
// 93: the difference between two consecutive measurements to be taken as valid
// model: an int that determines your sensor:  1080 for GP2Y0A21Y
//                                            20150 for GP2Y0A02Y
//                                            (working distance range according to the datasheets)

void setup()
{
    Serial.begin(9600);
    pinMode (ir, INPUT);
    pinMode (ir1, INPUT);
    pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
   
}

void loop()
{
    int t_start = millis(); // get the time before sensor data is in range
    
    unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    int dis1 = sharp1.distance(); // Returns the distance of the second sensor (pin A1)

    Serial.print("Mean distance sensor 1: ");  // returns it to the serial monitor
    Serial.println(dis);

    Serial.print("Mean distance sensor 2: ");  // returns it to the serial monitor
    Serial.println(dis1);

    unsigned long pepe2 = millis() - pepe1; // the following gives you the time taken to get the measurement
    Serial.print("Time taken (ms): ");
    Serial.println(pepe2);

   
if ((dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange )){
 if ((millis()-t_start) > CertainPeriod){
        Serial.println("Dog detected in range");
        if(shouldPress == true)     // checks if keypress or LED needs to happen
        {
          
            digitalWrite(LEDPin, HIGH);
            Keyboard.press('d');
            shouldPress = false;    // sets to false so that it has happened
        } 
        }
}
else {
        Serial.println("out of range");
        digitalWrite(LEDPin, LOW);
        Keyboard.releaseAll();
        shouldPress = true;
      }
}

I also tried your way Cats, but I didn't get any readings at all (I realise I must have done something wrong but can not figure this one out). I agree with you on the need for editing the raw data I have always found blips and when you are relying on a signal this blips caused my system to crash as an overload of 'd' switching! :frowning:

I tried your loop method as I do not mind it so much holding up the CPU. Thank-you for your detailed explanation!

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir A0
#define model 20150
#define LEDPin 13 // Onboard LED
#define ir1 A1

//unsigned long  minSample, maxSample;

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm

static unsigned long startOfCertainPeriod;

const unsigned long CertainPeriod = 5000UL;  // Must be in range 2 seconds or more

boolean shouldPress;
boolean codeIsWithinRange;

SharpIR sharp(ir, 25, 93, model);
SharpIR sharp1(ir1, 25, 93, model);

// ir: the pin where your sensor is attached
// 25: the number of readings the library will make before calculating a mean distance
// 93: the difference between two consecutive measurements to be taken as valid
// model: an int that determines your sensor:  1080 for GP2Y0A21Y
//                                            20150 for GP2Y0A02Y
//                                            (working distance range according to the datasheets)

void setup()
{
    Serial.begin(9600);
    pinMode (ir, INPUT);
    pinMode (ir1, INPUT);
    pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
   
}

void loop()
{
    unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    int dis1 = sharp1.distance(); // Returns the distance of the second sensor (pin A1)

    Serial.print("Mean distance sensor 1: ");  // returns it to the serial monitor
    Serial.println(dis);

    Serial.print("Mean distance sensor 2: ");  // returns it to the serial monitor
    Serial.println(dis1);

    unsigned long pepe2 = millis() - pepe1; // the following gives you the time taken to get the measurement
    Serial.print("Time taken (ms): ");
    Serial.println(pepe2);

   
if ((dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange )){
  codeIsWithinRange = true;
}

if (codeIsWithinRange == true) {

    if (millis() - startOfCertainPeriod >= CertainPeriod) {
            // Act on the code being within range for at least a certain period
         Serial.println("Dog detected in range");
        if(shouldPress == true)     // checks if keypress or LED needs to happen
        {
          
            digitalWrite(LEDPin, HIGH);
            Keyboard.press('d');
            shouldPress = false;    // sets to false so that it has happened
        } 
        }
        }
if (codeIsWithinRange == false){
       startOfCertainPeriod = millis();  // Re-start the timer for how long code has been in range
        Serial.println("out of range");
        digitalWrite(LEDPin, LOW);
        Keyboard.releaseAll();
        shouldPress = true;
      }
}

Any help would be appreciated, thank-you again for replying.

  int t_start = millis(); // get the time before sensor data is in range

1: This should be 'unsigned long' if you are using it to store a millis() value.

2: This should be 'static' so it doesn't get re-created every time through loop().

  else {
    Serial.println("out of range");
    digitalWrite(LEDPin, LOW);
    Keyboard.releaseAll();
    shouldPress = true;
  }

3: You forgot to reset 't_start' when the dog went out of range.

    if ((millis() - t_start) > CertainPeriod) {
      Serial.println("Dog detected in range");

3: This should probably be:

      Serial.println("Dog detected in range");
    if ((millis() - t_start) > CertainPeriod) {
      Serial.println("Dog in range for CertainPeriod");

Happy to help, can you please explain clearly exactly what you are trying to do and I'll try to help you find a solution? I'm not entirely clear on what you're using both distance readings for.

Thanks

Reduce the output of the sensor to 2 values, either on or off for 'dog in range' or 'no doggie'

if doggie, mark timer
if no doggie, reset timer

so whatever variables you're using
if( sensor reading on && current time - mark time >= desired threshold)
do the print thing you want

just be mindful of your sensor's consistency of values, if it hops around any, any null reading will reset the timer.

And if it reads 0cm as its default, I wouldn't include that in the desired range to indicate a dog in range.

Hey All,

Thank-you again for your replies,

John I edited the code as you advised but now, while it is still taking accurate readings via serial monitor; it is no longer giving out any output.

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir A0
#define model 20150
#define LEDPin 13 // Onboard LED
#define ir1 A1

//unsigned long  minSample, maxSample;

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm

static unsigned long startOfCertainPeriod;

const unsigned long CertainPeriod = 5000UL;  // Must be in range 5 seconds or more


boolean shouldPress;

SharpIR sharp(ir, 25, 93, model);
SharpIR sharp1(ir1, 25, 93, model);
                                           (working distance range according to the datasheets)

void setup()
{
    Serial.begin(9600);
    pinMode (ir, INPUT);
    pinMode (ir1, INPUT);
    pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
   
}

void loop()
{
    unsigned long t_start = millis(); // get the time before sensor data is in range
    
    unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    int dis1 = sharp1.distance(); // Returns the distance of the second sensor (pin A1)

    Serial.print("Mean distance sensor 1: ");  // returns it to the serial monitor
    Serial.println(dis);

    Serial.print("Mean distance sensor 2: ");  // returns it to the serial monitor
    Serial.println(dis1);

    unsigned long pepe2 = millis() - pepe1; // the following gives you the time taken to get the measurement
    Serial.print("Time taken (ms): ");
    Serial.println(pepe2);

   
if ((dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange )){
 if ((millis()-t_start) > CertainPeriod){
        Serial.println("Dog in range for CertainPeriod");
        Serial.println("Dog detected in range");
        if(shouldPress == true)     // checks if keypress or LED needs to happen
        {
          
            digitalWrite(LEDPin, HIGH);
            Keyboard.press('d');
            shouldPress = false;    // sets to false so that it has happened
        } 
        }
}
if ((dis >= maximumRange && dis <= minimumRange) || (dis1 >= maximumRange && dis1 <= minimumRange )) {
        Serial.println("out of range");
        digitalWrite(LEDPin, LOW);
        Keyboard.releaseAll();
        shouldPress = true;
        startOfCertainPeriod = millis();  // Re-start the timer for how long code has been in range
      }
}

CatsLoveJazz,

What I am trying to do is get an IR sensor to detect when a dog is in front of it. However due to the small angle of the sensor I am using two. When the dog is there the keypress 'd' will occur which runs a program on my computer. The overall project will allow a dog to use through it being in close proximity.

I have tried other methods, but this is the only one where I can get consistent presences (IR Motion a dog will stop when interacting with the program turning it off, Ultrasound in higher than a dog frequency is just muffled by fur) and so it has lead me to this.

The problem with my original code is that it will flicker as IR sensors are not great at being accurate but run so fast (mines currently around 25 millis) that these accuracy, I hope, can be smoothed out so that if the dog is there for longer than X seconds, it will turn on. The problem with the flicker is it causes my program to turn on and off quickly giving me false readings and crashing my PC for my dog.

I hope this makes some more sense?

INTP,

I am not sure if the sensor has a default setting, it ranges up to 150cm (slightly under if I am honest) and so as a default normally sticks around 130-140cm if nothing is infront of it (see picture of serial monitor below).

Might be an idea to change the values into two readings.

Thank-you again all of you for your lovely replies, I realise I am not the best coder so I cant thank-you enough for the patience you have shown and the help you have given me.

Thanks crazydoglady, I hope this is closer to what you are looking for. Note it is completely untested!

This will still suffer from the problem of flicker but I believe the general logic to be correct. I'd be happy to help you with averaging or filtering of the sensor data if you're finding the noise in the readings is causing the system to be unreliable.

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir_1 A0
#define ir_2 A1
#define model 20150
#define LEDPin 13 // Onboard LED

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm
const int TimeInRange = 5000;     // the amount of time the sensors have to be in range before tiggering

SharpIR sharp_1(ir_1, 5, 93, model);
SharpIR sharp_2(ir_2, 5, 93, model);

bool programRunning = false;

void setup()
{
  Serial.begin(9600);
  pinMode(ir_1, INPUT);
  pinMode(ir_2, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop()
{

  // Read current sensor data
  int dis_1 = sharp_1.distance();
  int dis_2 = sharp_2.distance();

  int t_start = millis(); // get the time before sensor data is in range

  // Remain in this loop while either of the sensors are in range
  while ((dis_1 <= maximumRange && dis_1 >= minimumRange) || (dis_2 <= maximumRange && dis_2 >= minimumRange)) {

    // if sensor data has been within range for the threshold time then trigger
    // Only do this is the program is NOT already running!
    if ((millis() - t_start) > TimeInRange) && programRunning == false) {
      Serial.println("Dog detected in range for > 'TimeInRange' ms");
      digitalWrite(LEDPin, HIGH);
      Keyboard.press('d');
      programRunning = true;
    }

    int dis_1 = sharp_1.distance();
    int dis_2 = sharp_2.distance();
  }
  
  programRunning = false;
  
  Serial.println("out of range");
  digitalWrite(LEDPin, LOW);
  Keyboard.releaseAll();
}

crazydoglady:
John I edited the code as you advised but now, while it is still taking accurate readings via serial monitor; it is no longer giving out any output.

You forgot the 'static' keyword on t_start. That will make a LOT of difference.

You could try getting some sort of pressure plate to connect to your arduino to see if a dog is there. After a quick search I found this which might be a good option if you decide to go this route: http://www.trossenrobotics.com/store/p/3508-Switch-Floor-Mat-14-Inches-x-30-Inches.aspx

if ((dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange )){

if ((millis()-t_start) > CertainPeriod){
        Serial.println("Dog in range for CertainPeriod");
        Serial.println("Dog detected in range");
        ...
        }
}
if ((dis >= maximumRange && dis <= minimumRange) || (dis1 >= maximumRange && dis1 <= minimumRange )) {
        Serial.println("out of range");
        ...
      }
}

I believe that your logic here is in error. It does not take into account DeMorgan's Theorum, which states the following two equivalencies:

!A && !B = !(A || B)
!A || !B = !(A && B)

When you distribute the negation to the individual variables, you must also change the operator between them.

With your pair of if statements, you are testing if at least one sensor is "in range", and in the second you are testing if at least one sensor is "out of range". For the second, you most likely want both to be out of range. The way you currently have it, if you have one sensor reportin gin range and the other reporting out of range, you will get both an in range and out of range event triggered. The easiest way to handle this is:

bool in_range = (dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange );

if( in_range )
{
  // Dog in range
}
else
{
  // No dog in range.
}

Hi All,

Sorry for the slow reply work has been hetic, thank-you for your responses.

Jiggy-Ninja - I took your advice and changed it to an in range out of range concept. I had not heard of DeMorgans Theorum before thank-you so much for your advice and knowledge.

Michaelsm - I want to make this concept work ideally without the introduction of pressure plates, but equally that has already been done with dogs (Link encase you are interested: Interactive Digital Gameplay Can Lower Stress Hormone Levels in Home Alone Dogs — A Case for Animal Welfare Informatics | SpringerLink)

Johnwasser - I put static on the t_start within the loop, unfortunately I am still getting blips it does not seem to be paying attention to the 5 second CertainPeriod. Here is my code

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir A0
#define model 20150
#define LEDPin 13 // Onboard LED
#define ir1 A1

//unsigned long  minSample, maxSample;

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm

static unsigned long startOfCertainPeriod;

const unsigned long CertainPeriod = 5000UL;  // Must be in range 5 seconds or more


boolean shouldPress;

SharpIR sharp(ir, 25, 93, model);
SharpIR sharp1(ir1, 25, 93, model);

                                           //(working distance range according to the datasheets)

void setup()
{
    Serial.begin(9600);
    pinMode (ir, INPUT);
    pinMode (ir1, INPUT);
    pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
   
}

void loop()
{
    static unsigned long t_start = millis(); // get the time before sensor data is in range
    
    unsigned long pepe1 = millis(); // takes the time before the loop on the library begins

    int dis = sharp.distance(); // this returns the distance to the object you're measuring
    int dis1 = sharp1.distance(); // Returns the distance of the second sensor (pin A1)

    Serial.print("Mean distance sensor 1: ");  // returns it to the serial monitor
    Serial.println(dis);

    Serial.print("Mean distance sensor 2: ");  // returns it to the serial monitor
    Serial.println(dis1);

    unsigned long pepe2 = millis() - pepe1; // the following gives you the time taken to get the measurement
    Serial.print("Time taken (ms): ");
    Serial.println(pepe2);

bool in_range = (dis <= maximumRange && dis >= minimumRange) || (dis1 <= maximumRange && dis1 >= minimumRange );

if (in_range)
{
if ((millis()-t_start) > CertainPeriod){
        Serial.println("Dog in range for CertainPeriod");
        Serial.println("Dog detected in range");
        if(shouldPress == true)     // checks if keypress or LED needs to happen
        {
          
            digitalWrite(LEDPin, HIGH);
            Keyboard.press('d');
            shouldPress = false;    // sets to false so that it has happened
        } 
        }
}
else {
        Serial.println("out of range");
        digitalWrite(LEDPin, LOW);
        Keyboard.releaseAll();
        shouldPress = true;
        startOfCertainPeriod = millis();  // Re-start the timer for how long code has been in range
      }
}

Catslovejazz - Thank-you for your programming I have been looking at it most of this week trying to figure out where there is a wrong conception, it just takes one reading and then spits out 'd' from what I can tell but this is not dependant on anything being in range or out of range (I tested with nothing to see if it was just stopping the loop when something came into range initially). Only output I get is;

Dog detected in range for >
5000

I have edited your code slightly to print out correct timing I just think the code does not go off the within range in regards to the sensors but with 5 seconds since the program has been running if that makes any sense.

#include <SharpIR.h> // Sharp Libary
#include <Keyboard.h> // Keyboard

#define ir_1 A0
#define ir_2 A1
#define model 20150
#define LEDPin 13 // Onboard LED

const int maximumRange = 100; // Maximum range needed in cm
const int minimumRange = 0;   // Minimum range needed in cm
const int TimeInRange = 5000;     // the amount of time the sensors have to be in range before tiggering

SharpIR sharp_1(ir_1, 5, 93, model);
SharpIR sharp_2(ir_2, 5, 93, model);

bool programRunning = false;

void setup()
{
  Serial.begin(9600);
  pinMode(ir_1, INPUT);
  pinMode(ir_2, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop()
{

  // Read current sensor data
  int dis_1 = sharp_1.distance();
  int dis_2 = sharp_2.distance();

  int t_start = millis(); // get the time before sensor data is in range

  // Remain in this loop while either of the sensors are in range
  while ((dis_1 <= maximumRange && dis_1 >= minimumRange) || (dis_2 <= maximumRange && dis_2 >= minimumRange)) {

    // if sensor data has been within range for the threshold time then trigger
    // Only do this is the program is NOT already running!
  if (((millis() - t_start) > TimeInRange) && programRunning == false) {
      Serial.println("Dog detected in range for >");
      Serial.println(TimeInRange);
      digitalWrite(LEDPin, HIGH);
      Keyboard.press('d');
      programRunning = true;
    }

    int dis_1 = sharp_1.distance();
    int dis_2 = sharp_2.distance();
  }
  
  programRunning = false;
  
  Serial.println("out of range");
  digitalWrite(LEDPin, LOW);
  Keyboard.releaseAll();
}

One place you use 't_start' and another place you use 'startOfCertainPeriod'. Get rid of one of those.

I beg your pardon, I spotted a lazy bug in the code. Note the updated section below

if (((millis() - t_start) > TimeInRange) && programRunning == false) {
      Serial.println("Dog detected in range for >");
      Serial.println(TimeInRange);
      digitalWrite(LEDPin, HIGH);
      Keyboard.press('d');
      programRunning = true;
    }

    // *********************
    dis_1 = sharp_1.distance();
    dis_2 = sharp_2.distance();
    // *********************
  }