Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Arduino如何存储最后的IR代码以检查是否需要重复?_C++_Arduino_Embedded - Fatal编程技术网

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

C++ Arduino如何存储最后的IR代码以检查是否需要重复?,c++,arduino,embedded,C++,Arduino,Embedded,我正在学习Arduino,我已经连接了一个直流电机和红外接收器。如果我按下一次按钮,它可以正常工作,但是如果我按下按钮,我就不知道如何保持马达旋转,因为重复命令是相同的数字 我想我会存储最后发送的代码,并检查repeat命令和最后一个代码是否匹配,但它似乎不起作用,也无法找出原因 #include <IRremote.h> int IRpin = 11; // pin for the IR sensor IRrecv irrecv(IRpin); decode_results r

我正在学习Arduino,我已经连接了一个直流电机和红外接收器。如果我按下一次按钮,它可以正常工作,但是如果我按下按钮,我就不知道如何保持马达旋转,因为重复命令是相同的数字

我想我会存储最后发送的代码,并检查repeat命令和最后一个代码是否匹配,但它似乎不起作用,也无法找出原因

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

  }
}


}

在松开按钮之前运行电机的更可靠方法是使用无代码超时。也就是说,如果无代码状态持续时间长于自动重复时间,则该状态已被释放

您的代码中不清楚1秒模拟脉冲的用途,但在环路功能中设置长延迟会使系统的响应性大大降低。最好是对系统进行投票,并在适当的时候做一些事情。另外,如果您希望任何人理解您的代码并避免维护中的错误,则应避免使用幻数

下面使用system tick轮询实现无代码超时。我省略了电机开/关代码,因为不清楚您在那里做什么,延迟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
            ...
        }
    }
}
我已经包括了对电机关闭代码的响应,但这可能不是必需的,因为在任何情况下,在打开按钮释放后,电机将在250ms或您选择的任何时间关闭。您可以改为使用前进/后退按钮,然后松开其中一个按钮以停止:

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

您应该避免使用32位算术。这是一个古老的8位MCU,不是PC。请您评论一下Thx,但您的确切意思是什么?Offopic:阅读有关神奇数字的内容当您让8位AVR处理32位数字时,它将不得不在机器代码中嵌入大量的软件库,使程序速度非常慢。在某些情况下,没有办法解决这个问题,但是在这里,你的传感器不可能有32位的精度,所以你只是让CPU无缘无故地空空如也。问题的根源在于编写irremote.h的爱好者,根据github判断,它看起来像一个新手PC程序员。他们每50秒也有一次中断发射。如果AVR能在50美元内自行处理ISR代码,我会感到惊讶。。。拆开@Lundin:但是,结果是:值是一个32位int,C++编译器将最佳地处理这个数字大小。通常,当以十六进制格式编写时,人们更容易阅读,但这是另一个主题;这肯定是一只虫子吗?因为它将在.data/default ctor初始化期间执行,而不是在执行此代码之前很久。您也可以将其初始化为停止\u TIME\u MS+1;//马达关闭。另外,我们不应该混合不同类型的十六进制文字。没有类型为unsigned long的\u代码,但MOTOR\u FWD\u代码等类型为long。因此,在开关中使用了冲突的类型——在这种情况下,不会发生任何事情,因为代码是无符号长的,所以您可以转换为无符号长的代码。但如果是int等,这里可能会发生微妙的bug。始终将十六进制常量作为预期类型的后缀,在本例中为ul.@Lundin。实际上,静态变量是在第一次调用函数时初始化的,但这可能是未定义的。不,静态变量在调用函数时从不初始化,而是在程序启动时初始化。@Lundin所有优点。我当然无法构建或测试此代码,它应该被视为一种设计模式,可能不完整甚至不正确。请随意解决这些问题。我现在正在打电话,而代码编辑不是直截了当的。谢谢