0

I'm new to Arduino, but I'm a C/C++ veteran (not to mention some other languages).

Now I was under the impression that the code I'm typing into the Arduino IDE was a C or C++ dialect. However, just now I ended up puzzled because the compiler wouldn't swallow either of the following:

#define RFID_SIZE 5
#define CSUM_SIZE 1
typedef unsigned char rfidbuf_t[RFID_SIZE+CSUM_SIZE];

or my first attempt:

#define RFID_SIZE 5
#define CSUM_SIZE 1
typedef byte rfidbuf_t[RFID_SIZE+CSUM_SIZE];

Now I figure that a #define ought to be cheaper than a constant, so that's why I went for defines. The fact that #include is supported suggested to me there'd be a cpp in the Arduino development environment as well.

What struck me as odd was the fact that I get to see the error only on the next code line (not on the line with the typedef):

rfid_serial.ino:6:18: error: ‘rfidbuf_t’ was not declared in this scope
rfid_serial.ino:6:29: error: ‘code’ was not declared in this scope
rfid_serial.ino: In function ‘bool ReadRFIDTag(byte (&)[6])’:
rfid_serial.ino:15:33: error: ‘bool ReadRFIDTag(byte (&)[6])’ redeclared as different kind of symbol
rfid_serial.ino:6:6: note: previous declaration ‘bool ReadRFIDTag’
rfid_serial.ino: In function ‘void loop()’:
rfid_serial.ino:96:21: error: ‘ReadRFIDTag’ cannot be used as a function

The code I came up with was an attempt at optimizing the way this works. In particular I noticed that String (a class, it seems?!) Increases the size of my code quite a lot. So I thought a reference to the buffer would be a sensible choice here.

Here's the complete code:

#include <SoftwareSerial.h>
#define RFID_SIZE 5 // the code size (digits) of the RFID tag.
#define CSUM_SIZE 1  // the csum size (digits) of the RFID tag.
typedef byte rfidbuf_t[RFID_SIZE+CSUM_SIZE];

SoftwareSerial RFID(2, 3); // RX and TX

void setup()
{
  RFID.begin(9600); // start serial to RFID reader
  Serial.begin(115200); // start serial to PC 
}

/* From: https://efxa.org/2013/05/23/simple-function-implementation-for-parsing-rfid-tags-in-arduino/ and adjusted. */
bool ReadRFIDTag(rfidbuf_t& code)
{
  byte value = 0;       // temporary data received from RFID reader.
  byte checksum = 0;    // checksum data of RFID tag received.
  byte bytesRead = 0;   // number of received data from RFID reader.
  byte tempByte = 0;    // temporary value used for checksum calculation.

  bool handled = false; // flag indicating if an RFID tag was handled.

  // if there are any data coming from the RFID reader.
  if (RFID.available () > 0)
  {
    // check for the STX header (0x02 ASCII value).
    if (0x02 == (value = RFID.read ()))
    {
      // read the RFID digits & the checksum digits.
      while (bytesRead < (RFID_SIZE + CSUM_SIZE))
      {
        // if there are any data coming from the RFID reader.
        if (RFID.available () > 0)
        {
          // get a byte from the RFID reader.
          value = RFID.read ();

          // check for ETX | STX | CR | LF.
          if ((0x0D == value) || (0x0A == value) || (0x03 == value) || (0x02 == value))
          {
            // stop reading - there is an error.
            break;
          }

          // convert hex tag ID.
          if ((value >= '0') && (value <= '9'))
          {
            value = value - '0';
          }
          else if ((value >= 'A') && (value <= 'F'))
          {
            value = 10 + value - 'A';
          }

          // every two hex-digits, add byte to code.
          if (bytesRead & 1 == 1)
          {
            // make some space for this hex-digit by shifting
            // the previous hex-digit with 4 bits to the left.
            code[bytesRead >> 1] = (value | (tempByte << 4));

            if (bytesRead >> 1 != 5)
            {
              // if this is checksum byte, calculate the checksum (XOR).
              checksum ^= code[bytesRead >> 1];
            }
          }
          else
            tempByte = value;

          // ready to read next digit.
          bytesRead++;
        }
      }

      // handle the RFID digits & the checksum digits.
      if (bytesRead == (RFID_SIZE + CSUM_SIZE))
      {
        // check if the RFID code is correct.
        if (code[5] == checksum)
        {
          // set that the tag was handled.
          handled = true;
        }
      }
    }
  }

  return handled;
}

void loop()
{
  rfidbuf_t buf = {0};
  if(ReadRFIDTag(buf))
  {
    Serial.println(buf[0]); // TODO
  }
}

Is it impossible to use typedef the same I'm used to from C and C++? Because what I am attempting isn't all too unusual in C or C++ code, but of course references only exist in C++.

Does it mean I should rather into working with avr-gcc directly? I was under the impression that the Arduino IDE is basically built atop avr-gcc and avrdude (and possibly other backend programs).

  • Side-note: I do know that there are still some issues in the code and it's not a faithful conversion of the linked code, yet. Problem is that I got stuck with the typedef, a seemingly trivial thing. – 0xC0000022L Nov 5 '17 at 19:49
  • 1
    Compiles fine for me. What version of the IDE / compiler are you using? – Majenko Nov 5 '17 at 19:50
  • @Majenko: 2:1.0.5+dfsg2-4 (latest version on latest Linux Mint). – 0xC0000022L Nov 5 '17 at 19:54
  • 1.0.5 is preancient. Please consider using something modern, even if you have to download it yourself. – Ignacio Vazquez-Abrams Nov 5 '17 at 19:55
  • Latest... that'a s a laugh... You mean the ancient version that got left in APT a decade ago... – Majenko Nov 5 '17 at 19:55
2

Your version of the IDE (1.0.5) is incredibly ancient (just because it's in APT doesn't mean it's up to date - only that at some point within the last 20 years someone submitted it).

That version suffers from the problems that Ignacio describes in his answer. More modern versions (we're up to version 1.8.5 now...!) use a different build system which is far more intelligent about how it lays out its function prototypes.

Go to the Arduino website and download the latest version and you won't have these kind of problems and have to work around them with strange things like unnamed namespaces.

1

The Arduino IDE (un)helpfully copies function declarations towards the top, but fails to handle custom types properly. The solution is to hide the declarations in an unnamed namespace.

 ...
typedef byte rfidbuf_t[RFID_SIZE+CSUM_SIZE];

namespace {
  bool ReadRFIDTag(rfidbuf_t& code);
}
 ...
  • Wow, thanks a bunch. So that also explains why the line numbers in the error output were skewed. Brilliant. – 0xC0000022L Nov 5 '17 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.