C++ Arduino如何存储最后的IR代码以检查是否需要重复?
我正在学习Arduino,我已经连接了一个直流电机和红外接收器。如果我按下一次按钮,它可以正常工作,但是如果我按下按钮,我就不知道如何保持马达旋转,因为重复命令是相同的数字 我想我会存储最后发送的代码,并检查repeat命令和最后一个代码是否匹配,但它似乎不起作用,也无法找出原因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
#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所有优点。我当然无法构建或测试此代码,它应该被视为一种设计模式,可能不完整甚至不正确。请随意解决这些问题。我现在正在打电话,而代码编辑不是直截了当的。谢谢