多个文件中的多个类 - C ++ / Arduino

时间:2016-05-24 20:28:14

标签: c++ class c++11 arduino

我必须编写库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) ;
}

// (...)

爱德华

2 个答案:

答案 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);
     }
}