Skip to main content
replaced http://arduino.stackexchange.com/ with https://arduino.stackexchange.com/
Source Link

Alternatively, you could use a kind of tee to duplicate the data to both streams. See for example this implementationthis implementation.

Edit: A more elegant way to achieve the same would be to wrap all the IMU data into a struct (or a class), and then make the whole thing printableprintable:

Alternatively, you could use a kind of tee to duplicate the data to both streams. See for example this implementation.

Edit: A more elegant way to achieve the same would be to wrap all the IMU data into a struct (or a class), and then make the whole thing printable:

Alternatively, you could use a kind of tee to duplicate the data to both streams. See for example this implementation.

Edit: A more elegant way to achieve the same would be to wrap all the IMU data into a struct (or a class), and then make the whole thing printable:

+ solution subclassing Printable.
Source Link
Edgar Bonet
  • 44.3k
  • 4
  • 41
  • 79

Edit: A more elegant way to achieve the same would be to wrap all the IMU data into a struct (or a class), and then make the whole thing printable:

struct ImuData : public Printable
{
    uint16_t Time0, AcX, AcY, AcZ, GyX, GyY, GyZ;
    size_t printTo(Print& p) const;
};

size_t ImuData::printTo(Print& p) const
{
    size_t bytes = 0;
    bytes += p.print(Time0); bytes += p.write(',');
    [...]
    bytes += p.print(GyZ);
    return bytes;
}

The you can print the struct like you would print the string:

ImuData imu;
imu.Time0 = ...;
imu.AcX   = Wire.read() << 8;
imu.AcX  |= Wire.read();
[...]

dataFile.println(imu);
if (Serial_plus_SD)
    Serial.println(imu);

Edit: A more elegant way to achieve the same would be to wrap all the IMU data into a struct (or a class), and then make the whole thing printable:

struct ImuData : public Printable
{
    uint16_t Time0, AcX, AcY, AcZ, GyX, GyY, GyZ;
    size_t printTo(Print& p) const;
};

size_t ImuData::printTo(Print& p) const
{
    size_t bytes = 0;
    bytes += p.print(Time0); bytes += p.write(',');
    [...]
    bytes += p.print(GyZ);
    return bytes;
}

The you can print the struct like you would print the string:

ImuData imu;
imu.Time0 = ...;
imu.AcX   = Wire.read() << 8;
imu.AcX  |= Wire.read();
[...]

dataFile.println(imu);
if (Serial_plus_SD)
    Serial.println(imu);
Source Link
Edgar Bonet
  • 44.3k
  • 4
  • 41
  • 79

First, let me point out a problem in your code, completely unrelated to your question:

AcX = Wire.read()<<8|Wire.read();

The C++ standard does not specify in which order the two reads will be performed. This may work well with the particular version of the particular compiler you are using, but it can break the day you (or an update to the Arduino IDE) changes the compiler version or a compiler flag. You should instead do a single read per statement, e.g.:

AcX  = Wire.read() << 8;
AcX |= Wire.read();

Next, I would like to say that the simplest Arduino way of doing what you are trying to do is to use neither a String nor a character array. Instead, open the file first, then format and send the data on the fly using print() or println():

dataFile.print(Time0); dataFile.print(",");
dataFile.print(AcX);   dataFile.print(",");
[...]

This way you never need to store the whole string in memory. It is then a very memory-friendly solution.

Now, I realize this seems inconvenient if you want to print the data to both the SD file and the serial port. In such a case you could put the printing code inside a function that can print to any Print object (for instance the data file and Serial), and you can then call the function twice:

static void printImuData(Print &printer, int16_t Time0,
        int16_t AcX, int16_t AcY, int16_t AcZ,
        int16_t GyX, int16_t GyY, int16_t GyZ)
{
    printer.print(Time0); printer.print(",");
    printer.print(AcX);   printer.print(",");
    [...]
}

[...]

printImuData(dataFile, Time0, AcX, AcY, AcZ, GyX, GyY, GyZ);
if (Serial_plus_SD)
    printImuData(Serial, Time0, AcX, AcY, AcZ, GyX, GyY, GyZ);

Alternatively, you could use a kind of tee to duplicate the data to both streams. See for example this implementation.