Write string to SD card and send string via xbee

Hello, I am having trouble writing a RFID tag string to a SD card and also sending it to an xbee. Independently, I can successfully read/write to an SD card and read/send RFID tag string via xbees. Getting them to work together is my issue; more specifically, no data is written to the card. I think it is something with the serial configuration but i am not sure. Any and all help is appreciated. Thank you for your time.

Hardware: Arduino Due, wireless SD shield http://arduino.cc/en/Main/ArduinoWirelessShield, xbee series 1, and 1 GB microSD card.

#include <XBee.h>
#include <SD.h>
#include <SPI.h>

XBee xbee;

File dataFile;

void setup() {
  //initiate xbee and wait
  xbee.begin(9600);
  delay(6000);
  // RFID tag reader 
  Serial1.begin(9600);
  delay(400);
  
  pinMode(10, OUTPUT); 
  // see if the card is present and can be initialized:
  if (!SD.begin(4)) {
    // don't do anything more:
    return;
  }

}

void loop() {
    // get RFID tag string
    String string_RFID_tag = Serial1.readStringUntil('$0d');
 
    // if there is a string write to SD and send
    if (string_RFID_tag.length() > 0){
      
      // open the file. note that only one file can be open at a time,
      // so you have to close this one before opening another.
      dataFile = SD.open("data.txt", FILE_WRITE);   
      
      // if the file is available, write to it:
      if (dataFile) {
          dataFile.println(string_RFID_tag);
          dataFile.close();
      }
      // convert string to char array
      char array_RFID_tag[string_RFID_tag.length()]; 
      string_RFID_tag.toCharArray(array_RFID_tag, string_RFID_tag.length());

      // form packet to transmit (DL - destination address (HEX), payload, size of payload)  
      Tx16Request tx16 = Tx16Request(0x0100, (uint8_t*)array_RFID_tag, sizeof(array_RFID_tag));
      // transmit packet
      xbee.send(tx16);
}

}//loop() end
    String string_RFID_tag = Serial1.readStringUntil('$0d');

What the heck is this supposed to be doing? Which ONE key did you press to get the ONE character in the single quotes? Why are you stuffing the char pointer that is returned into a String? Did you get the 2 terrabyte version of the Arduino?

      string_RFID_tag.toCharArray(array_RFID_tag, string_RFID_tag.length());

This is crap. The 2nd argument to toCharArray() is the size of the array being written to. The method KNOWS how much data is in the instance that it is called for. It REALLY doesn’t need you to tell it that.

What the heck is this supposed to be doing?

The RFID reader terminates with a CR, so the bytes are read until a CR is found, and stored as a string

Why are you stuffing the char pointer that is returned into a String?

not sure, it works this way

This is crap. The 2nd argument to toCharArray() is the size of the array being written to. The method KNOWS how much data is in the instance that it is called for. It REALLY doesn't need you to tell it that.

Maybe so. I did this because you cannot cast a string to unit8_t so i converted the string to char array. If I change how read the RFID tag by using a Serial.read and read byte by byte into are char array and then cast to unit8_t for sending.

The RFID reader terminates with a CR, so the bytes are read until a CR is found, and stored as a string

But '$0d' is NOT how to define that terminating character. '\r' or 0x0D or 10 are all suitable ways.

not sure, it works this way

Actually, I was wrong. readBytesUntil() expects three arguments. The first is the character that defines when to stop reading. The second defines where to put the data. The third defines how big the array is that it is to write to (the second argument). The return value is the number of bytes read. That is, in general, useless information. Storing THAT in a String is beyond dumb.

It does NOT work, for any reasonable definition of work.

I did this because you cannot cast a string to unit8_t

Of course not. But, you CAN cast a string to a uint8_t *. You can't cast a String to anything. Get used to the distinction between a string and a String, and use the correct terms.

Thank you for your help thus far. I have changed my code to no longer read the RFID tag into a string; however, i still cannot write the RFID tag to the SD card.

#include <XBee.h>
#include <SD.h>
#include <SPI.h>

XBee xbee;

File dataFile;

char RFID_tag[17];

void setup() {
  //initiate xbee and wait
  xbee.begin(9600);
  delay(6000);
  // RFID tag reader 
  Serial1.begin(9600);
  delay(400);
  
  Serial.begin(9600);
  delay(400);
  
  pinMode(10, OUTPUT); 
  // see if the card is present and can be initialized:
  if (!SD.begin(4)) {
    // don't do anything more:
    return;
  }
}

void loop() {
    // get RFID tag string
    Serial1.readBytesUntil('/r',RFID_tag,17);
    // if there is a string write to SD and send
    if (sizeof(RFID_tag) > 0){  
      // open the file. note that only one file can be open at a time,
      // so you have to close this one before opening another.
      dataFile = SD.open("data.txt", FILE_WRITE);   
      
      // if the file is available, write to it:
      if (dataFile) {
          dataFile.println(RFID_tag);
          dataFile.close();
      }
      // form packet to transmit (DL - destination address (HEX), payload, size of payload)  
      Tx16Request tx16 = Tx16Request(0x0100, (uint8_t*)RFID_tag, sizeof(RFID_tag));
      // transmit packet
      xbee.send(tx16);
}
}//loop() end
    Serial1.readBytesUntil('/r',RFID_tag,17);

'/r' is NOT equal to '\r'.

My mistake. Fixed.

bram50:
My mistake. Fixed.

And?

... and nothing is being recorded to the SD card. Other thoughts?

also, its not creating the data.txt file.

    if (sizeof(RFID_tag) > 0){

Why does the size of the array matter? Shouldn't you be concerned with the amount of data IN the array?

What data IS in the array? Put the XBee away until you KNOW that the RFID is being read correctly.

Which pins are the XBee connected to, anyway? You seem to be using pins 0 and 1 for the XBee AND the RFID. You can't do that.

Why does the size of the array matter? Shouldn't you be concerned with the amount of data IN the array?

You are correct, it does not matter. I changed it to this:

if (RFID_tag[0] != ' ')

The elements of RFID_tag are initialized as ' ' after each read.

What data IS in the array?

The correct RFID tag number of 982_000109842725 is in the array.

Which pins are the XBee connected to, anyway?

I have the RFID tag read connected to RX1 (19) and TX1 (18) while the xbee is on the wireless shield which i believe is connected to RX (0) and TX (1).

What problem are we trying to solve? Writing to the SD card? That doesn’t involve the XBee, so take it off. Use Serial for debugging.

When writing to the SD card without the XBee in place, we can then deal with sending data via the XBee, if there is (still) a problem with that.

The correct RFID tag number of 982_000109842725 is in the array.

There is no known universe where 982_000109842725 is a number.

With this code, i am successfully able to write the RFID tag to the SD card:

//#include <XBee.h>
#include <SD.h>
#include <SPI.h>

//XBee xbee;

File dataFile;

char RFID_tag[17];

void setup() {
  //initiate xbee and wait
  //xbee.begin(9600);
  //delay(6000);
  // RFID tag reader 
  Serial1.begin(9600);
  delay(400);
  RFID_tag[0] = ' ';
  
  pinMode(10, OUTPUT); 
  // see if the card is present and can be initialized:
  if (!SD.begin(4)) {
    // don't do anything more:
    return;
  }

}

void loop() {
    // get RFID tag string
    Serial1.readBytesUntil('\r',RFID_tag,17);
    // if there is a string write to SD and send
    if (RFID_tag[0] != ' '){  
      
      // form packet to transmit (DL - destination address (HEX), payload, size of payload)  
      //Tx16Request tx16 = Tx16Request(0x0100, (uint8_t*)RFID_tag, sizeof(RFID_tag));
      // transmit packet
      //xbee.send(tx16);
      //delay(300);
      // open the file. note that only one file can be open at a time,
      // so you have to close this one before opening another.
      dataFile = SD.open("data.txt", FILE_WRITE);   
      delay(500);
      // if the file is available, write to it:
      if (dataFile) {
          dataFile.println(RFID_tag);
          dataFile.print('\n');
          delay(300);
          dataFile.close();
          delay(300);
      }
      for (int i = 0; i < sizeof(RFID_tag); i++){
        RFID_tag[i] = ' ';
      }
}

}//loop() end

Note, the xbee is not connected and all the xbee stuff is commented out. So my thought is to next incorporate the xbee stuff back in with the xbee disconnected. Writing to SD was fine, also I did that I have no issues transmitting the correct array from xbee to xbee. When the xbee is connected, the write to SD card ability is lost.

When the xbee is connected, the write to SD card ability is lost.

I find that incredibly hard to believe. Unless the process for connecting the XBee is not what you have described.

Are you uncommenting the XBee code at the same time?

The usual reason for using the XBee library is to be able to receive messages from an XBee that is not connected to an Arduino and that has external sensors attached. Another reason is to set up bi-directional communication between two series 2 XBees that do not need to involve the coordinator.

Neither scenario applies to you, does it?

Since the XBee is connected to the Serial pins, just use Serial to send data, without using the XBee library. Forget about whether or not the receiver is able to understand the data. I just want to know if the physical attachment of the shield with XBee mounted is what is causing the problem.

If so, then the next test would be to mount the shield without the XBee aboard, to see what that does.

Are you uncommenting the XBee code at the same time?

No, i did it systematically, trying all the combinations

Neither scenario applies to you, does it?

I have 12 endpoints that need to send a read RFID tags to one xbee/arduino connected to a computer. Logging RFID tag information to the SD is for data backup. The xbee/arduino at the computer will control when each endpoint sends its data.

So just using the serial to send the data to the computer worked fine. I agree i find it hard to believe the physical attachment of the shield with XBee mounted is what is causing the problem. I havent tried sending it over the serial to another xbee. Maybe I should reconsider not using the xbee library.