0

I'm having a hard time trying to convert a float into a char array so it's stored like '7.125' just like the float looks.

I'm trying to communicate with an ATtiny85 (slave) and a program on a Raspberry Pi (master) over I2C.

The master expects 31 bytes from the slave when data is sent to it.

When I use this code on the ATtiny85 everything works as it should, the Pi gets the data correctly.

    char computerdata[35]; 
    computerdata[0] = '3';
    computerdata[1] = '.';
    computerdata[2] = '8';
    computerdata[3] = '7';
    computerdata[4] = '7';

    TinyWire.send(1);
    TinyWire.send(computerdata,30);

Of course I need to put a float variable in the array and not define numbers like I have for testing and this is where it breaks.

When I do something like this, it doesn't work, the Pi reports parsing error yet when I do this on the Due with Serial prints the char array looks good but something is different about it.

  sprintf(computerdata, "%2.32f", pH);

OR

  snprintf (computerdata, 35, "%f", pH);

What am I missing? Any ideas?

Thanks

0

Just to complement Michel Keijzers’ answer: sprintf() or snprintf() are normally the right solution. On the AVR platform, however, float conversions are left out of their default implementation, because they take quite a lot of flash space, even when not used. On the other hand, the avr-libc provides the non-standard function dtostrf() for doing this conversion. The program

void setup() {
    float f = 3.877;
    char str[35];
    dtostrf(f, 0, 3, str);
    Serial.begin(9600);
    Serial.println(str);
}

void loop(){}

outputs

3.877
| improve this answer | |
0

The reason is that the library which implements snprintf and sprintf can be dependent on the compiler used for your MCU, so in your case it's not supported.

If you always need the form %2.32f why not put it in directly, like:

int i = int(3.877 * 1000.0); // Assuming f of form a.bcd, i will be 3877
char str[6];
str[0] = (i / 1000) % 10; 
str[1] = '.';
str[2] = (i / 100) % 10;
str[3] = (i /  10) % 10;
str[4] = (i      ) % 10;
str[5] = '0';

It will be much faster too.

| improve this answer | |
  • Thanks for the answer but that wouldn't compile, got this error. Edgar's worked good. sketch_feb28b.ino: In function 'void setup()': sketch_feb28b:21: error: invalid operands of types 'double' and 'int' to binary 'operator%' sketch_feb28b:22: error: invalid operands of types 'double' and 'int' to binary 'operator%' invalid operands of types 'double' and 'int' to binary 'operator%' – robsworld78 Mar 6 at 0:01
  • True, I changed it, now it compiles (did not check it on an Arduino). I will keep it despite dtostrfis better in most cases. – Michel Keijzers Mar 6 at 0:10
  • works good now. :) – robsworld78 Mar 6 at 0:33
  • Thanks for the confirmation – Michel Keijzers Mar 6 at 0:51
  • 1
    @DataFiddler that's for the op to answer I guess. – Michel Keijzers Mar 6 at 11:57

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.