Застрял в петле, используя ИК-приемник
Я новичок в программировании 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();
и ждет другого ИК-ввода и Мне нужно снова нажать кнопку.
Можно ли это решить (одним нажатием)?
@Ankan Pal, 👍0
Обсуждение2 ответа
Лучший ответ:
Ваш код становится более читабельным, если вы используете функции с возвращаемыми значениями.
Например, что-то вроде этой структуры
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() и создания других вспомогательных функций.
- Вам действительно следует использовать регистр-переключатель.
- irrecv.resume() не останавливает код.
Ваша программа работает нормально. Похоже, вы хотите постоянно снимать показания датчиков и действовать только при нажатии кнопки. Я прав?
Да, вы правы... Я хочу сделать цикл, пока не будет нажата другая кнопка, и когда она нажата, она должна перейти в другой цикл., @Ankan Pal
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Вызов irrecv.resume() не должен блокироваться. ИК-обнаружение выполняется по прерыванию таймера. Возможно, у вас есть две части кода, которые пытаются использовать один таймер. Можете ли вы попробовать, если ИК-код работает, когда вы закомментируете весь код NewTone или весь код AnalogWrite? (Оба также используют таймеры), @chrisl