我必须编写库motorIR,它使用NECIRrcv从传感器中提取IR代码。 最初我尝试使用两个库来实现它,但是在我阅读时似乎并不容易,所以我决定在我的Arduino库motorIR中包含NECIRrcv的头文件和源文件。
我在motorIR中定义NECIRrcv sensor
时遇到了一些麻烦。
如果我把它放在代码中的位置,则没有信号可用(永远不会输入while(sensor.available())
)。
我能理解这是合乎逻辑的,因为每当我拨打motorIR::control()
时它都会重新定义传感器。
我真正的问题是我不知道我应该在motorIR 中声明sensor
,即NECIRrcv类的对象。
我做了一些关于它的研究,由于我之前没有和外语课一起工作过,所以如果使用它是必要的话,我会更加困惑。
如果有人可以投入几分钟帮助我完成这个课程,我将非常感激。希望你能理解我的解释。
您在这里是不同的文件:
文件motorIR.h
#ifndef motorIR_h
#define motorIR_h
#include "Arduino.h"
#include "NECIRrcv.h"
#define STANDBY 999
#define inputIR 2
#define PWM_1 3
#define MI_1 4
#define MD_1 5
#define PWM_2 6
#define MI_2 7
#define MD_2 8
#define FORWARD
#define BACKWARD
class motorIR
{
public: // Funciones públicas
motorIR(int pPWM_1, int pMI_1, int pMD_1, int pPWM_2, int pMI_2, int pMD_2);
void setMotor(int PWM, int MI, int MD);
void begin();
void control();
void translate();
void serialPrint();
private: // Variables privadas
int _PWM= STANDBY;
int _MI;
int _MD;
unsigned long _IRcode;
// static NECIRrcv & getSensor() // <--- getSensor() added
// {
// static NECIRrcv sensor(4);
// return sensor;
// }
// static NECIRrcv & getSensor()
// {
// static NECIRrcv sensor(4);
// static bool firstRun(true);
// if ( firstRun )
// {
// sensor.begin();
// firstRun = false;
// }
// return sensor;
// }
};
#endif
文件motorIR.cpp
#include "Arduino.h"
#include "motorIR.h"
#include <string.h>
motorIR::motorIR(int PWM, int MI, int MD) // Constructor
{
_MI= MI +A0;
_PWM= PWM +A0;
_MD= MD +A0;
}
void motorIR::beginner()
{
Serial.begin(9600);
Serial.print("Begin");
}
void motorIR::control(int i)
{
NECIRrcv sensor(4) ; // I doesn't work as expected if placed here
sensor.begin();
Serial.println("Checkpoint");
while (sensor.available())
{
Serial.print("Detection");
IRcode= sensor.read();
Serial.print(IRcode, DEC);
Serial.print(IRcode, HEX);
Serial.print(IRcode, BIN);
}
}
文件NECIRrcv.h(给定)
#ifndef NECIRrcv_h
#define NECIRrcv_h
#include <Arduino.h>
#include "motorIR.h"
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define CLKFUDGE 5 // fudge factor for clock interrupt overhead
#define CLKMAX 256 // max value for clock (timer 2)
#define PRESCALE 8 // timer2 clock prescale
#define SYSCLOCK 16000000 // main Arduino clock
#define CLKSPERUSEC (SYSCLOCK/PRESCALE/1000000) // timer clocks per microsecond
#define MAXBUF 8 // IR command code buffer length (circular buffer)
// IR detector output is active low
#define MARK 0
#define SPACE 1
#define NBITS 32 // bits in IR code
#define BLINKLED 13
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// clock timer reset value
#define INIT_TIMER_COUNT2 (CLKMAX - USECPERTICK*CLKSPERUSEC + CLKFUDGE)
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT2
// pulse parameters -- nominal usec
#define STARTNOM 9000
#define SPACENOM 4500
#define BITMARKNOM 620
#define ONESPACENOM 1600
#define ZEROSPACENOM 480
#define RPTSPACENOM 2180
#define TOLERANCE 20 // percent
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)
// pulse parameters (tick counts)
#define STARTMIN (int)((STARTNOM/USECPERTICK)*LTOL) // start MARK
#define STARTMAX (int)((STARTNOM/USECPERTICK)*UTOL)
#define SPACEMIN (int)((SPACENOM/USECPERTICK)*LTOL)
#define SPACEMAX (int)((SPACENOM/USECPERTICK)*UTOL)
#define BITMARKMIN (int)((BITMARKNOM/USECPERTICK)*LTOL-2) // extra tolerance for low counts
#define BITMARKMAX (int)((BITMARKNOM/USECPERTICK)*UTOL+2)
#define ONESPACEMIN (int)((ONESPACENOM/USECPERTICK)*LTOL)
#define ONESPACEMAX (int)((ONESPACENOM/USECPERTICK)*UTOL)
#define ZEROSPACEMIN (int)((ZEROSPACENOM/USECPERTICK)*LTOL-2)
#define ZEROSPACEMAX (int)((ZEROSPACENOM/USECPERTICK)*UTOL+2)
#define RPTSPACEMIN (int)((RPTSPACENOM/USECPERTICK)*LTOL)
#define RPTSPACEMAX (int)((RPTSPACENOM/USECPERTICK)*UTOL)
// receiver states
#define IDLE 1
#define STARTH 2
#define STARTL 3
#define BIT 4
#define ONE 5
#define ZERO 6
#define STOP 7
#define BITMARK 8
#define RPTMARK 9
// macros
#define GETIR(X) ((byte)digitalRead(X)) // used to read IR pin
#define nextstate(X) (irparams.rcvstate = X)
// state machine variables irparams
static volatile struct {
byte rcvstate ; // IR receiver state
byte bitcounter ; // bit counter
byte irdata ; // MARK or SPACE read from IR input pin
byte fptr ; // irbuf front pointer
byte rptr ; // irbuf rear pointer
byte irpin ; // pin for IR data from detector
byte blinkflag ; // TRUE to enable blinking of pin 13 on IR processing
unsigned int timer ; // state timer
unsigned long irmask ; // one-bit mask for constructing IR code
unsigned long ircode ; // IR code
unsigned long irbuf[MAXBUF] ; // circular buffer for IR codes
} irparams ;
// main class
class NECIRrcv
{
public:
NECIRrcv(int irpin);
unsigned long read();
void begin();
int available() ;
void flush() ;
void blink13(int blinkflag) ;
private:
} ;
extern NECIRrcv sensor; // <-------- declaring object as extern
#endif
文件NECIRrcv.cpp(给定)
#include <Arduino.h>
#include "NECIRrcv.h"
#include "motorIR.h"
NECIRrcv::NECIRrcv(int irpin)
{
irparams.irpin = irpin ;
}
void NECIRrcv::begin() {
//(...)
}
unsigned long NECIRrcv::read()
{
unsigned long ircode ;
//(...)
return((unsigned long)-1) ;
}
// (...)
爱德华
答案 0 :(得分:1)
如果sensor
的所有实例只需motorIR
,我想它可能是该类的静态成员。
静态方法中的静态变量;像这样
class motorIR
{
public: // Funciones públicas
motorIR(int PWM, int MI, int MD);
void beginner();
void control(int i);
private: // Variables privadas
int _PWM= STANDBY;
int _MI;
int _MD;
int pin_IR;
unsigned long IRcode;
static NECIRrcv & getSensor() // <--- getSensor() added
{ static NECIRrsv sensor(4); return sensor; }
};
你可以这样使用它
void motorIR::control(int i)
{
// NECIRrcv sensor(4) ; no more here
getSensor().begin();
Serial.println("Checkpoint");
while (getSensor().available())
{
Serial.print("Detection");
IRcode= getSensor().read();
Serial.print(IRcode, DEC);
Serial.print(IRcode, HEX);
Serial.print(IRcode, BIN);
}
}
p.s。:警告:未经测试
p.s.2:抱歉我的英语不好
---编辑---
错误是“'NECIRrcv'没有命名类型”或“'NECIRrcs'没有命名类型”?
在我的例子中,我写错了“NECIRrcs”而不是“NECIRrcv”;遗憾。
关于您只需要begin()
一次传感器,您可以通过这种方式修改getSensor()
方法
static NECIRrcv & getSensor()
{
static NECIRrsv sensor(4);
static bool firstRun(true);
if ( firstRun )
{
sensor.begin();
firstRun = false;
}
return sensor;
}
警告:未经测试。
答案 1 :(得分:0)
我喜欢将对象NECIRrcv::sensor
声明为类motorIR
的一部分的想法,但尝试在motorIR.h中的任何位置定义NECIRrcv sensor(4)
会导致错误:'NECIRrcv '没有命名类型;所以解决这个问题会很有意思,以便能够实现@ max66的想法(或者只是为了找出为什么motorIR.h无法正确识别NECIRrcv
)。
尽管如此,我认为我遇到了另一种解决方案:使用外部对象(如here所述)。
可以按照以下方式实施:
在NECIRrcv标题中:
#ifndef NECIRrcv_h
#define NECIRrcv_h
#include <Arduino.h>
// (...)
class NECIRrcv
{
public:
NECIRrcv(int irpin);
// (...)
private:
} ;
extern NECIRrcv sensor; // <-------- declaring object as extern
#endif
在motorIR源文件中:
#include "Arduino.h"
#include "motorIR.h"
#include <string.h>
NECIRrcv sensor(4); // <--------- defining object
motorIR::motorIR(int PWM, int MI, int MD)
{
_MI= MI +A0;
_PWM= PWM +A0;
_MD= MD +A0;
}
void motorIR::beginner()
{
Serial.begin(9600);
Serial.print("Begin");
sensor.begin(); // <-------- now I can initialize sensor here
}
void motorIR::control(int i)
{
// NECIRrcv sensor(4) ;
// sensor.begin();
Serial.println("Checkpoint");
while (sensor.available()) // <-- method 1
{
Serial.print("Detection");
IRcode= sensor.read(); // <-- method 2
Serial.print(IRcode, DEC);
Serial.print(IRcode, HEX);
Serial.print(IRcode, BIN);
}
}