0

I am new to Arduino Programming and I have bought an Arduino UNO , Ultrasonic Sensor (HC-SR04), A Piezo Buzzer, IR Receiver (VS1838B) and a RGB LED....

I wrote a program to Calculate Distance form the Ultrasonic Sensor to an object and a Processing Sketch to Display the results.

Now I want to use the IR Receiver to increase the Distance Threshold which makes the buzzer beep...I mean I want to press 1 in my remote to keep the distance about 5 cm after which the buzzer beeps, and when I press 2 the distance becomes 10 cm and so on...I want to stop everything when I press 0 in my remote...

I have already found out the hex codes of my remote buttons but the program makes the task harder... Please help me with the program that I have already written :-

#include <NewTone.h>
#include <IRremote.h>

const int rec = 9;
IRrecv irrecv(rec);
decode_results results;

#define BUTTON_0 0xFF6897
#define BUTTON_1 0xFF30CF
#define BUTTON_2 0xFF18E7
#define BUTTON_3 0xFF7A85
#define BUTTON_EQ 0xFF906F
#define BUTTON_4 0xFF10EF

const int redPin = 5;
const int greenPin = 6;
const int bluePin = 10;
const int trigPin = 12;
const int echoPin = 11;
const int buzPin = 3;
double duration;
double distanceCm, distanceInch;
double dur;

void setup() {

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(buzPin, OUTPUT);
  irrecv.enableIRIn();
  Serial.begin(9600);
}

void loop()
{
  if (irrecv.decode(&results))
  {
    if (results.value != BUTTON_0)
    {

      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      duration = pulseIn(echoPin, HIGH);
      distanceCm = duration * 0.034 / 2;
      distanceInch = duration * 0.0133 / 2;
      dur = duration / 10000;

      Serial.print(distanceCm);
      Serial.print("  cm ");
      Serial.print("                         ");
      Serial.print(distanceInch);
      Serial.print(" Inch ");
      Serial.print("                         ");
      Serial.print(dur);
      Serial.print(" Seconds");
      Serial.print("\n");
    }


    if (results.value == BUTTON_0)
    {

      noNewTone(buzPin);
      analogWrite(redPin, 0);
      analogWrite(greenPin, 0);
      analogWrite(bluePin, 0);
    }

    if (results.value == BUTTON_1)
    {


      if (distanceCm <= 5)
      {
        NewTone(buzPin, 2000);
        analogWrite(redPin, 255);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 0);
      }
      else if (distanceCm <= 10 && distanceCm > 5)
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 255);
      }
      else
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 255);
        analogWrite(bluePin, 0);
      }

    }

    if (results.value == BUTTON_2)
    {

      if (distanceCm <= 10)
      {
        NewTone(buzPin, 2000);
        analogWrite(redPin, 255);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 0);
      }
      else if (distanceCm <= 20 && distanceCm > 10)
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 255);
      }
      else
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 255);
        analogWrite(bluePin, 0);
      }

    }

    if (results.value == BUTTON_3)
    {

      if (distanceCm <= 30)
      {
        NewTone(buzPin, 2000);
        analogWrite(redPin, 255);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 0);
      }
      else if (distanceCm <= 50 && distanceCm > 30)
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 255);
      }
      else
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 255);
        analogWrite(bluePin, 0);
      }





    }

    if (results.value == BUTTON_4)
    {

      if (distanceCm <= 100)
      {
        NewTone(buzPin, 2000);
        analogWrite(redPin, 255);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 0);
      }
      else if (distanceCm <= 200 && distanceCm > 100)
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 255);
      }
      else
      {
        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 255);
        analogWrite(bluePin, 0);
      }


    }
    irrecv.resume();
  }
}

I am using the "IRremote.h" and "NewTone.h" Libraries....

The main problem is that the "irrecv.resume();" pauses the program and waits for the IR input but I want the program to run continuously till I give an IR Input...

I request you to help me with the program.


I edited my program to this and this worked:-

#include <NewTone.h>
#include <IRremote.h>

const int rec = 2;
IRrecv irrecv(rec);
decode_results results;

#define BUTTON_0 0xFF6897
#define BUTTON_1 0xFF30CF
#define BUTTON_2 0xFF18E7
#define BUTTON_3 0xFF7A85
#define BUTTON_EQ 0xFF906F
#define BUTTON_4 0xFF10EF

const int redPin = 5;
const int greenPin = 6;
const int bluePin = 10;
const int trigPin = 12;
const int echoPin = 11;
const int buzPin = 3;
double duration;
double distanceCm, distanceInch;
double dur;

void setup() {

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(buzPin, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn();
}

void loop()
{
  if (irrecv.decode(&results))
  {

    do
    {
      if (results.value == BUTTON_0)

      {

        noNewTone(buzPin);
        analogWrite(redPin, 0);
        analogWrite(greenPin, 0);
        analogWrite(bluePin, 0);
      }

      if (results.value == BUTTON_1)
      {
        sonic();

        if (distanceCm <= 5)
        {
          red();
        }
        else if (distanceCm <= 10 && distanceCm > 5)
        {
          blue();
        }
        else
        {
          green();
        }

      }

      if (results.value == BUTTON_2)
      {
        sonic();
        if (distanceCm <= 10)
        {
          red();
        }
        else if (distanceCm <= 20 && distanceCm > 10)
        {
          blue();
        }
        else
        {
          green();
        }
      }

      if (results.value == BUTTON_3)
      {
        sonic();
        if (distanceCm <= 30)
        {
          red();
        }
        else if (distanceCm <= 50 && distanceCm > 30)
        {
          blue();
        }
        else
        {
          green();
        }
      }

      if (results.value == BUTTON_4)
      {
        sonic();
        if (distanceCm <= 100)
        {
          red();
        }
        else if (distanceCm <= 200 && distanceCm > 100)
        {
          blue();
        }
        else
        {
          green();
        }


      }
    }
    while (digitalRead(rec) == 1);

    irrecv.resume();
  }
}

void sonic()
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distanceCm = duration * 0.034 / 2;
  distanceInch = duration * 0.0133 / 2;
  dur = duration / 10000;

  Serial.print(distanceCm);
  Serial.print("  cm ");
  Serial.print("                         ");
  Serial.print(distanceInch);
  Serial.print(" Inch ");
  Serial.print("                         ");
  Serial.print(dur);
  Serial.print(" Seconds");
  Serial.print("\n");
}

void green()
{
  noNewTone(buzPin);
  analogWrite(redPin, 0);
  analogWrite(greenPin, 255);
  analogWrite(bluePin, 0);
}

void blue()
{
  noNewTone(buzPin);
  analogWrite(redPin, 0);
  analogWrite(greenPin, 0);
  analogWrite(bluePin, 255);
}


void red()
{
  NewTone(buzPin, 2000);
  analogWrite(redPin, 255);
  analogWrite(greenPin, 0);
  analogWrite(bluePin, 0);
}

But now the problem is I need to press the IR Remote button two times because when I press once the program moves to the irrecv.resume(); command and waits for another IR Input and I need to press the button again.

Can this be solved (with only one press)?

  • The call to irrecv.resume() should not block. The IR detection runs on a timer interrupt. Maybe you have 2 parts of code, that both try to use one timer. Can you try, if the IR code is working, when you comment out all NewTone code or all analogWrite code? (Both also use timers) – chrisl Dec 16 '19 at 23:15
0

Your code becomes more readable, if you use functions with return values.

For example, something like this structure

unsigned int limit; // 0 = off, else limit in cm  ...
void loop() {
  if (irrecv.decode(&results)) {
      byte key = getIRKey(results.value); // 0 , 1, 2, etc.,  0xFF for unknown 
      irrecv.resume();
      switch (key) {
         case 0: limit = 0; break;
         case 1: limit = 5; break;
         ... 
         default: break; // wrong key does not change limit
      }   
  } 
  if (limit) {
     unsigned int dist = sonic(); // returns the measured distance or 0 
     if (dist && dist < limit) NewTone(buzPin, 2000);
     else noNewTone(buzPin); // off: too far
  } else noNewTone(buzPin); // off: no check
}

This code should not block. Have fun modifying sonic() and creating the other helper function.

| improve this answer | |
0
  1. You really should use switch-case.
  2. irrecv.resume() does not halt the code.

Your program is running fine. It seems like you want to make sensor readings continuously and act only when you press the button. Am I right?

| improve this answer | |
  • Yes, You are Right... I want to do a loop till another button is pressed and when it is pressed it should go into another loop. – Ankan Pal Dec 17 '19 at 2:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.