0
\$\begingroup\$

I am trying to save some values to memory, I have an array with 6 values like as shown below

Data[6] = {5045.567,4567.987,4.5,190.5, 70.5,500};

I have to save this kind of data into flash memory. I have memory which can store only 16 bit at each address and i am able to write 16 bit.I need to write two times to write a float value. I am multiplying 5045.567 with 1000 to make long integer 5047567 so that i can save float value(two address to write float value). My data will look like this.

long int Data[6]= {5047567, 4567987, 4500 190500,700500,500}

Is there any best method to save float value instead of multiplying with 1000 to make it as long integer?

To save this kind of data i need two address sometime and one address is enough some time.I will have this kind of data every 10 secs, I can't write to memory every 10 secs because of power saving features.

I am trying to collect values every mint and trying write to memory at once every mint.

For this I have initialized an array with size[36] and saving all values after one mint. Is there any best way other than this to collect values for certain time and save once?

I am collecting all 36 values in an array. for example first two values needs two address in memory then next four values need only one address in memory. How do i increment address in memory for certain values? or is it best to divide long values into two integers before storing into array?

\$\endgroup\$
  • \$\begingroup\$ You can serialize the float values as bytes and store them as is. Usually float is taking 4 bytes in memory. Unfortunately in C there is no good and portable way of doing so. See my question on SO \$\endgroup\$ – Eugene Sh. Oct 27 '15 at 16:04
  • \$\begingroup\$ What prevents you from storing the float value directly? They're just bits as everything else as well. In embedded environments you usually use 32-bit floats, so they will fit nicely in 2 "addresses". \$\endgroup\$ – Arsenal Oct 27 '15 at 16:04
  • \$\begingroup\$ I'm not quite sure why you are using float values in this case as you can store the time as a uint32 in milliseconds and not worry about any kind of conversion. \$\endgroup\$ – Dom Oct 27 '15 at 16:10
  • \$\begingroup\$ Possibly related: how to store array of long integer values to 16 bit memory \$\endgroup\$ – Arsenal Oct 27 '15 at 21:56
3
\$\begingroup\$

You are getting ahead of yourself.

First specify what exactly needs to be stored with what precision and range. Does it really need to be floating point? Very likely you don't need either the resolution or dynamic range, probably neither.

For example, if these are voltage measurements from 0-10 V measured with a 12 bit A/D, then you don't have more than 12 bits of real information. In this example, you could store the raw A/D readings directly, or use a common format like integer millivolts.

Added

You now say these values are derived from 24 bit A/D readings. If storage size is important, you can use a 24 bit representation (Are all 24 bits really meaningful? Probably not) and store two of them every 3 words. For more convenience but 1/3 more memory usage, use two whole words for each reading. I'd pick a convenient unit and zero offset and store the readings as 32 bit integers. Floating point is a bit silly in this case, but that's only 32 bits too.

Either way you have 32 bits, or two words, to write to the non-volatile memory for each reading. In any case, I fail to see a problem here. It doesn't matter whether you write the two words in high-low or low-high order as long as you are consistant and the reader follows the same scheme. Again, what exactly is the problem?

\$\endgroup\$
  • \$\begingroup\$ I need to store 3 decimals after point which is very important. These values are from 24 bit ADC. I have a readings from ADC like 184567 then i am converting it into this float value. \$\endgroup\$ – verendra Oct 28 '15 at 9:16
0
\$\begingroup\$

Assuming that float is 32 bits and int is 16 bits, then you might save directly the contents of the float variable into the memory like in the following code.

int *address;
int value1, value2;
float value=3.4321;
address=(int *) &value;
value1=*address;
value2=*(address+1);

Eugene Sh. warned me that the cast from (float *) to (int *) breaks the C standard, and some compilers might not accept it. Therefore I post an alternative, assuming char is 8 bits, int is 16 bits and float is 32 bits:

char *address;
int value1, value2;
float value=3.4221;
address=(char *) &value;
value1=(int) *adress+*(address+1)*256;
value2=(int) *(adress+2)+*(address+3)*256;

Actually, I think that the original code should also compile with any compiler with this small change:

int *address;
int value1, value2;
float value=3.4321;
address=(int *) (char *) &value;
value1=*address;
value2=*(address+1);
\$\endgroup\$
  • \$\begingroup\$ This is breaking the strict-aliasing rule. While most likely to work for now, it is violating the C standard. \$\endgroup\$ – Eugene Sh. Oct 27 '15 at 16:07
  • \$\begingroup\$ Yes, it is correct that this makes the code less portable, but actually if the code must be ported to another MCU many other changes will probably be necessary. \$\endgroup\$ – Roger C. Oct 27 '15 at 16:21
  • \$\begingroup\$ The specific strict-aliasing problem is not processor specific, but is C standard. Processor specific issues will begin when dealing with endiannes. \$\endgroup\$ – Eugene Sh. Oct 27 '15 at 16:24
  • \$\begingroup\$ @EugeneSh. Actually the fact that the code works or not only depends on float being 32 bits and int being 16 bits. And this might change depending on the compiler (that in turn generally depends on the processor that it is targetting). Do you suggest coding this particular piece of code in assembly language? \$\endgroup\$ – Roger C. Oct 27 '15 at 16:35
  • \$\begingroup\$ Exactly. It depends on many factors, and thus having undefined behavior in general. There are ways to work around this specific problem by, for example, wrapping the float together with int into a union. Or alias it as array of chars, which is allowed. \$\endgroup\$ – Eugene Sh. Oct 27 '15 at 16:39

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.