Go Down

Topic: Problem saving data to SD (Read 2 times) previous topic - next topic

madepablo

Hi again, here is the void loop code that i have right now:
Code: [Select]
void loop() {
 byte data[2];
 float temp=readTemp();
 float Vcc=readVcc();
 data[0]=(temp);
 data[1]=(Vcc);
 unsigned long length = sizeof(data[2]);
 FileLogger::append("data.log", data, length);
}


I made automatic the calculation of the size of the data array.
I declare correctly the size of the array.

It compiles, but the stored result is this:
Quote
5555555555555


So, may be i should convert the sequence of data into a long string, with "," in between the different data (in this case, temp and Vcc). Any idea about how to do it?
Thanks!

PaulS

In your earlier post, you declared readTemp and readVcc as returning longs. Longs are 4 bytes.

Setting a variable of one type (byte) to the value of another variable of a different type can result in loss of data, if the types are not the same size.

Longs and bytes are not the same size, so there is data loss when you stuff temp and Vcc into data[0] and data[1].

Finally, the sizeof function returns the size of the specified argument. You specified the third member of a two member array as the argument. The sizeof function figured out that the argument was of type byte, so it returned the size of a byte, in bytes, or 1.

So, the FileLogger logged one byte.

If you are going to use sizeof, the argument is the whole array, not one member of the array.

In any case, I think you are going to get better results if you convert the values to strings, and save them. The sprintf function will do that.

char message[20];
sprintf(message,"%l,%l", temp, Vcc);

Then, use strlen to get the length of the string, and pass message and the length to FileLogger::append.

madepablo

#7
Nov 07, 2009, 01:37 am Last Edit: Nov 07, 2009, 01:39 am by madepablo Reason: 1
Great PaulS!

Thanks so much for all this help. And also for the information about the bytes.

I made some changes in the code, but now i have problems in compilation.

Firstly, i changed the temp and Vcc to long type for don´t loss information.

Later, i included your ideas in the code, but i have a problem... the FileLogger procedure require a byte sequence, so i converted the message to an array, following the same example than in FileLogger example. But it have problems to know the size of the message...

Here is the code:
Code: [Select]
void loop() {
 long temp=readTemp();
 long Vcc=readVcc();
 char message[20];
 sprintf(message,"%l,%l", temp, Vcc);
 unsigned long length = strlen(message);
 byte data[]=message;
 FileLogger::append("data.log", data, length);
}


The error in compilation is this:
Quote
In function 'void loop()':
error: initializer fails to determine size of 'data'


as i said, if i remove the declaration of the array and call to the message in the FileLogger procedure, the error is this:
Quote
In function 'void loop()':
error: invalid conversion from 'char*' to 'byte*'


Thanks!

PaulS

The char and byte types are the same size. The FileLogger::append function says it wants a byte array, but what it means is that it wants a byte-sized array.

You have a byte-sized array, message. You simply need to tell the function that. You do that with a cast:

Code: [Select]
FileLogger::append("data.log", (byte *)message, length);


The (byte *) part is called a cast. It tells the compiler to treat message as though it was a byte array.

There are implicit and explicit casts. This code uses an implicit cast:

Code: [Select]
long temp;
int i = 14;

temp = i;


The temp variable expects a long value, but you can supply an int, and the compiler will convert the value to a long, implicitly, before storing it.

Any time you try to store a smaller value type in a larger value type, an implicit cast is performed, as long as the types are the same (int, float, etc.).

When the types are not the same, but the sizes are, an explicit cast is required.

When the types are not the same, and the sizes are not the same, an explicit cast may result in loss of data, if the destination is smaller than the source.

madepablo

#9
Nov 07, 2009, 02:40 am Last Edit: Nov 07, 2009, 02:43 am by madepablo Reason: 1
Great lesson PaulS, i am learning a lot!

I made the changes that you proposed. Now it compiles, but it produce a sequence of symbols without sense...

This is the code:
Code: [Select]
void loop() {
 long temp=readTemp();
 long Vcc=readVcc();
 char message[20];
 sprintf(message,"%l,%l", temp, Vcc);
 unsigned long length = strlen(message);
 FileLogger::append("data2.log", (byte*)message, length);
delay(1000);
}


and this what it write in the SD card, repeated in a long sequence:
Quote
@  <[ch8221]



=l
ÿ
jå[ch8226]



Thanks for your interest, help, efforts and patience!

Go Up