简体   繁体   English

Arduino我如何存储最后的IR代码以检查是否需要重复?

[英]Arduino How can i store the last IR code to check if it needs repeating?

I'm just learning Arduino and i've got a DC Motor & IR Receiver connected. 我正在学习Arduino,并且连接了DC Motor和IR接收器。 It's working fine if i press the button once but i can't figure out how to keep the motor spinning if i hold the button down as the REPEAT command is the same numbers. 如果我按一下按钮,效果很好,但是如果我按住REPEAT命令是相同的数字,那么我想不出如何保持电机旋转。

I figured i would store the last code sent and check if the repeat command and last code match but it doesn't seem to be working and can't figure out why. 我以为我会存储发送的最后一个代码,并检查重复命令和最后一个代码是否匹配,但是它似乎无法正常工作并且无法弄清原因。

#include <IRremote.h>

int IRpin = 11;  // pin for the IR sensor
IRrecv irrecv(IRpin);
decode_results results;
int lastCode;

void setup() {
  // put your setup code here, to run once:
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Enable IR Receiver.
}

void loop() {
  // put your main code here, to run repeatedly:


if

 (irrecv.decode(&results)) {
  Serial.println(results.value);
  irrecv.resume(); 
  Serial.println("Last Code is set to: ");
  Serial.write(lastCode);


  if(results.value== 16748655 || (results.value== 4294967295 && lastCode== 16748655)) // Your ON button value                                       
  {
      digitalWrite(8, HIGH);
      digitalWrite(7, LOW);
      analogWrite(9, 255);
      delay(1000);
      analogWrite(9, 0);
      lastCode= 16748655;

  }


  else if(results.value == 16769055 || (results.value== 4294967295 && lastCode== 16769055)) // Your OFF button value 
  {
      digitalWrite(8, LOW);
      digitalWrite(7, HIGH);
      analogWrite(9, 255);
      delay(1000);
      analogWrite(9, 0);
      lastCode= 16769055;

  }
}


}

A more reliable approach to running the motor until the button is released is to use a "no-code" timeout. 在释放按钮之前运行电动机的一种更可靠的方法是使用“无代码”超时。 That is, if the "no code" state persists for a period longer than the auto-repeat period, then it has been released. 即,如果“无代码”状态持续的时间长于自动重复时间,则它已被释放。

It is not clear in your code what the 1 second analogue pulse is for, but placing long delays in your loop() function makes your system far less responsive. 您的代码中尚不清楚1秒模拟脉冲的用途,但是在loop()函数中放置较长的延迟会使系统的响应能力大大降低。 Better to poll the system tick and "do stuff" when it is time to do so. 最好在需要时轮询系统刻度线并“执行任务”。 Also magic numbers should be avoided if you want anyone to understand your code and avoid errors in maintenance. 如果您希望任何人理解您的代码并避免维护错误,也应避免使用幻数。

The following uses system tick polling to implement the "no-code" timeout. 以下使用系统刻度轮询来实现“无代码”超时。 I have omitted the motor on/off code because it is not clear what you are doing there with the 1 second delays. 我已经省略了电动机开/关代码,因为不清楚在1秒钟的延迟后您在做什么。

#define NO_CODE        0xFFFFFFFFul
#define MOTOR_ON_CODE  0xFF906Ful
#define MOTOR_OFF_CODE 0xFFE01Ful
#define STOP_TIME_MS   250ul  // stop after button release for 250ms

void loop( )
{
    static unsigned long last_on_time = 0 ; 

    if( irrecv.decode( &results ) )
    {
        irrecv.resume() ;

        unsigned long code = results.value ;

        // If motor off code or no code timeout...
        if( code == MOTOR_OFF_CODE ||
            (code == NO_CODE && millis() - last_on_time > STOP_TIME_MS) )
        {
            // Motor off
            ...
        }
        else if( code == MOTOR_ON_CODE )
        {
            // Continuously update last on time while button is held
            last_on_time = millis() ;

            // Motor on
            ...
        }
    }
}

I have included response to the motor-off code, but that may not be necessary, since the motor will be switched off 250ms (or whatever time you choose) after the ON button is released in any case. 我已经包含了对马达关闭代码的响应,但这可能不是必需的,因为在任何情况下释放ON按钮后,马达都会关闭250ms(或您选择的任何时间)。 You might instead have a forward/reverse button and release either to stop: 您可能改为有一个前进/后退按钮,然后松开以停止:

#define NO_CODE        0xFFFFFFFFul
#define MOTOR_FWD_CODE 0xFF906Ful
#define MOTOR_REV_CODE 0xFFE01Ful
#define STOP_TIME_MS   250ul  // stop after button release for 250ms

void loop( )
{
    static unsigned long last_on_time = 0 ; 

    if( irrecv.decode( &results ) )
    {
        irrecv.resume() ;

        unsigned long code = results.value ;
        switch( code )
        {
            case NO_CODE :
            {
                if( millis() - last_on_time > STOP_TIME_MS )
                {
                    // Motor off
                    ...          
                }
            }
            break ;

            case MOTOR_FWD_CODE :
            {
                // Continuously update last on time while button is held
                last_on_time = millis() ;

                // Motor forward
                ...
            }
            break ;

            case MOTOR_FWD_CODE :
            {
                // Continuously update last on time while button is held
                last_on_time = millis() ;

                // Motor reverse
                ...
            }
            break ;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM