Застрял в петле, используя ИК-приемник

Я новичок в программировании Arduino и купил Arduino UNO, ультразвуковой датчик (HC-SR04), пьезозуммер, ИК-приемник (VS1838B) и светодиод RGB...

Я написал программу для расчета расстояния от ультразвукового датчика до объекта и скетч обработки для отображения результатов.

Теперь я хочу использовать ИК-приемник, чтобы увеличить пороговое значение расстояния, которое издает звуковой сигнал... Я имею в виду, что хочу нажать 1 на своем пульте дистанционного управления, чтобы сохранить расстояние около 5 см, после которого подается звуковой сигнал, и когда я нажмите 2, расстояние станет 10 см и так далее... Я хочу остановить все, когда нажму 0 на пульте...

Я уже узнал шестнадцатеричные коды кнопок пульта, но программа усложняет задачу... Помогите, пожалуйста, с программой, которую я уже написал :-

#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();
  }
}

Я использую библиотеки "IRremote.h" и "NewTone.h"....

Основная проблема заключается в том, что "irrecv.resume();" приостанавливает программу и ожидает ИК-ввода, но я хочу, чтобы программа работала непрерывно, пока я не дам ИК-ввод...

Я прошу вас помочь мне с программой.


Я отредактировал свою программу, и это сработало: -

#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);
}

Но теперь проблема в том, что мне нужно нажать кнопку ИК-пульта два раза, потому что, когда я нажимаю один раз, программа переходит к команде irrecv.resume(); и ждет другого ИК-ввода и Мне нужно снова нажать кнопку.

Можно ли это решить (одним нажатием)?

, 👍0

Обсуждение

Вызов irrecv.resume() не должен блокироваться. ИК-обнаружение выполняется по прерыванию таймера. Возможно, у вас есть две части кода, которые пытаются использовать один таймер. Можете ли вы попробовать, если ИК-код работает, когда вы закомментируете весь код NewTone или весь код AnalogWrite? (Оба также используют таймеры), @chrisl


2 ответа


Лучший ответ:

0

Ваш код становится более читабельным, если вы используете функции с возвращаемыми значениями.

Например, что-то вроде этой структуры

unsigned int limit; // 0 = выключено, иначе ограничение в см ...
void loop() {
  if (irrecv.decode(&results)) {
      byte key = getIRKey(results.value); // 0, 1, 2 и т. д., 0xFF для неизвестных
      irrecv.resume();
      switch (key) {
         case 0: limit = 0; break;
         case 1: limit = 5; break;
         ... 
         default: break; // неверный ключ не меняет лимит
      }   
  } 
  if (limit) {
     unsigned int dist = sonic(); // возвращает измеренное расстояние или 0
     if (dist && dist < limit) NewTone(buzPin, 2000);
     else noNewTone(buzPin); // выключено: слишком далеко
  } else noNewTone(buzPin); // выключено: нет проверки
}

Этот код не должен блокироваться. Получайте удовольствие от модификации sonic() и создания других вспомогательных функций.

,

0
  1. Вам действительно следует использовать регистр-переключатель.
  2. irrecv.resume() не останавливает код.

Ваша программа работает нормально. Похоже, вы хотите постоянно снимать показания датчиков и действовать только при нажатии кнопки. Я прав?

,

Да, вы правы... Я хочу сделать цикл, пока не будет нажата другая кнопка, и когда она нажата, она должна перейти в другой цикл., @Ankan Pal