使用SoftwareSerial作为私有成员变量

时间:2013-11-12 18:46:11

标签: arduino

我正在尝试将Sparkfun的SM130 RFID阅读器的示例代码转换为一个很好地封装的类/库,可用于多个arduino草图。

Sparkfun示例代码:https://github.com/sparkfun/RFID_Evaluation_Shield/blob/master/Firmware/RFID_Eval_13_56MHz.ino

大部分内容都非常顺利,直到我尝试将软件串行通信作为成员变量 - 我一直遇到如下错误:

/Users/scottnla/Dropbox/arduino/libraries/SM130/SM130.cpp: In constructor 'SM130::SM130()':
/Users/scottnla/Dropbox/arduino/libraries/SM130/SM130.cpp:8: error: no matching function for call to 'SoftwareSerial::SoftwareSerial()'
/Applications/Arduino.app/Contents/Resources/Java/libraries/SoftwareSerial/SoftwareSerial.h:83: note: candidates are: SoftwareSerial::SoftwareSerial(uint8_t, uint8_t, bool)
/Applications/Arduino.app/Contents/Resources/Java/libraries/SoftwareSerial/SoftwareSerial.h:48: note:                 SoftwareSerial::SoftwareSerial(const SoftwareSerial&)

我发现了一个似乎解决了这个问题的堆栈溢出帖子(Creating a Library for an Arduino),但他们的解决方案对我来说似乎不起作用。 IDE的错误消息似乎表明我只能在构造函数中使用“基本初始值设定项”;但这不是我想要的。解决我在代码中遇到的问题的最佳方法是什么?

谢谢!

以下代码:

SM130.h

#ifndef SM130_h
#define SM130_h

#include<Arduino.h>
#include <WConstants.h>

class SM130 {
  public:
    SM130();
    void connect(int RX, int TX);
    void check_for_notag();
    void halt_tag();
    void parse_tag();
    void print_serial();
    void seek_tag();
    void set_flag();

  private:
    int rfid_flag;
    int data[11];
    SoftwareSerial rfid;
};

#endif

SM130.cpp

#include <WProgram.h>
#include <SoftwareSerial.h>
#include "SM130.h"

SM130::SM130() {
  rfid_flag = 0;
}

void SM130::connect(int RX, int TX) : rfid(RX, TX) {
 if(!Serial.available()) {
    Serial.begin(9600);
  }
  Serial.println("Connecting to SM130 RFID Reader...");
  //rfid = SoftwareSerial(RX, TX);
  rfid.begin(19200);
  if(rfid.available()) {
    rfid.println("Connected to SM130 RFID Reader!");
  }
  delay(10);
}

void SM130::check_for_notag() {
  seek_tag();
  delay(10);
  parse_tag();
  set_flag();

  if(rfid_flag == 1) {
    seek_tag();
    delay(10);
    parse_tag();
  }
}

void SM130::halt_tag() {
  rfid.write(0xFF);
  rfid.write((byte)0x00);   //manual typecasting needed for 0x00 to differentiate it from null pointer -- silly c compilers!
  rfid.write(0x01);
  rfid.write(0x93);
  rfid.write(0x94);
}

void SM130::parse_tag() {
 while(rfid.available()) {
   if(rfid.read() == 0xFF) {
     for(int i = 1; i < 11; i++) {
       data[i] = rfid.read();
     }
   }
 }
}

void SM130::print_serial() {
  if(rfid_flag == 1) {
      Serial.print(data[5],HEX);
      Serial.print(data[6],HEX);
      Serial.print(data[7],HEX);
      Serial.print(data[8],HEX);
      Serial.println();
  }
}

void SM130::seek_tag() {
  //insert hex tags here
  rfid.write(0xFF);
  rfid.write((byte)0x00); //manual typecasting needed for 0x00 to differentiate it from null pointer -- silly c compilers!
  rfid.write(0x01);
  rfid.write(0x82);
  rfid.write(0x83);
}

void SM130::set_flag() {
  if(data[2] == 6) {
    rfid_flag++;
  }
  if(data[2] == 2) {
    rfid_flag = 0;
  }
}

我的arduino草图:

#include <SM130.h>

void read_serial();
SM130 rfidReader;

void setup() {
  //Connect to computer
  Serial.begin(9600);

  //connect to SM130
  rfidReader.connect(7,8);
}

void loop() {
  read_serial();
}

void read_serial() {
  rfidReader.seek_tag();
  delay(10);
  rfidReader.parse_tag();
  rfidReader.set_flag();
  rfidReader.print_serial();
  delay(100);
}

1 个答案:

答案 0 :(得分:1)

  

/Users/scottnla/Dropbox/arduino/libraries/SM130/SM130.cpp:In   构造函数'SM130 :: SM130()':   /Users/scottnla/Dropbox/arduino/libraries/SM130/SM130.cpp:8:错误:否   调用'SoftwareSerial :: SoftwareSerial()'

的匹配函数

这部分告诉你一切。 SoftwareSerial没有没有参数列表的构造函数,因此您尝试调用不存在的函数。 如果未在构造函数的初始化列表中指定类成员,则编译器默认调用()构造函数。它相当于:

SoftwareSerial ss;

如果我们不是在谈论课程。

http://www.cprogramming.com/tutorial/initialization-lists-c++.html

不幸的是,SoftwareSerial没有Set方法。

http://arduino.cc/de/Reference/SoftwareSerial

但是不用担心,动态内存分配来救援!例如:

SM130.h

#ifndef SM130_h
#define SM130_h

#include<Arduino.h>
#include <WConstants.h>

class SM130 {
  public:
    SM130();
    ~SM130();
    void connect(int RX, int TX);
    void check_for_notag();
    void halt_tag();
    void parse_tag();
    void print_serial();
    void seek_tag();
    void set_flag();

  private:
    int rfid_flag;
    int data[11];
    SoftwareSerial* rfid;
};

#endif

SM130.cpp(仅限某些方法)

SM130::SM130() : rfid(NULL)  {
  rfid_flag = 0;
}

void SM130::connect(int RX, int TX) {

    if(!Serial.available()) 
    {
        Serial.begin(9600);
    }

    Serial.println("Connecting to SM130 RFID Reader...");
    if (NULL != rfid)
    {
        delete rfid;
    }
    rfid = new SoftwareSerial(RX, TX)
    rfid->begin(19200);
    if(rfid->available())
    {
       rfid->println("Connected to SM130 RFID Reader!");
    }
    delay(10);
 }


 ~SM130::SM130() 
 {
     if (NULL != rfid)
     {
         delete rfid;
     }
 }

我只发布了构造函数,连接和析构函数的版本(很好地避免了内存泄漏)。

不要忘记:

  1. 检查rfid是否为NULL(更好地使用NULL != rfid而不是rfid != NULL,因为编译器会告诉您if (rfid = NULL))等错误
  2. rfid.更改为rfid->
  3. 您甚至可以添加disconnect方法,删除旧的rfid并将指针设置为NULL:

         void SM130::disconnect() {
             delete rfid;
             rfid = NULL;
         }