I have a project which uses a DS18B20 temperature sensor and an LCD with an I2C interface on it. I have connected the sensor to my micro-controller (the DS18B20 has a 12-bit digital output) to the ATmega16 PD17, but as I try to print my values on the terminal the sensor output a really high value in decimal. Here is part of the code (and yes everything is working fine, this is a home-made Arduino):

DDRD &= 0x00;
PORTD |=  0x00;    
ds18b20_init(&PORTD, 20, 30, DS18B20_12BIT_RES); 
int temperature_sensor_output =  (float)ds18b20_temperature(&PORTD);
printf("Temperature: %d  ", temperature_sensor_output);

ds18b20_init is the Dallas function for initializing the module. ds18b20_temperature returns a float value of the temperature

From this code it just prints:

Temperature: 51603

If I change %d to %f it prints:

Temperature: without any value

I do not understand where I may have missed some things.

  • Should it be float temperature_sensor_output =? – Gerben Dec 9 '16 at 19:11
  • "printf"? Are you including the standard I/O C library? I would have thought that a bit much on a small embedded processor. But if it works, great! Still, floating point math too? – st2000 Dec 9 '16 at 19:17
  • The home arduino works, though the way I am using the sensor does not.I think I am using these functions wrong but I cannot see the mistake. – Diana Lc Dec 9 '16 at 20:54
  • @Gerben Yes you are right, but if I put a float into an int it should truncate it?like float 27.89 to int 27? – Diana Lc Dec 9 '16 at 20:56
  • @DianaLc, you are doing normal C programming on an embedded processor. A float is usually made up of a integer mantissa and an integer exponent. I am not sure how much supporting software is available (has been written) for this platform to support casting like you are doing. I am thinking, not sticking to integer arithmetic is probably causing your problems. Most professional embedded programs would stick to integer math. Most software only people just assume all hardware is abstracted to the same level. That's the different between software and firmware. – st2000 Dec 10 '16 at 0:54

Without more detail about the system, I won't understand what printf() does; in non-embedded systems, printf() writes to stdout by default, but Arduino systems typically don't use such a device.

That aside, %d is the proper format code for printing an integer value, and %f is proper for a float or double. If you attempt to print an integer value like temperature_sensor_output under a %f format code, either the compiler will complain or the integer pattern of bits (plus perhaps two additional random bytes) will be interpreted as if it is a float or double pattern of bits. No type cast occurs within printf(). If you want to use a %f format code, pair it up with a float-type variable.

If, as you say, ds18b20_temperature() returns a float, then the type cast (float)ds18b20_temperature(&PORTD) will have no effect. Generally, casts convert data from one form to another, or in some cases declare that data has a given form. Going from float to float doesn't change anything.

In a C statement like a=b, if b has a type that's different from that of a, the b value will be cast to the type of a. Thus, the float value on the right hand side of

int temperature_sensor_output =  (float)ds18b20_temperature(&PORTD);

will be converted to an integer value and stored into the integer variable temperature_sensor_output.

  • You can use printf(), if you define a FILE descriptor for stdout as: "static FILE uartout = { 0 }; // dbprintf file descriptor" and a declare and write a char-output function, e.g.: "static int uart_putchar (char c, FILE *stream);", where uart_putchar() Serial.write()s 'c' to the terminal (and ignores the "stream" arg). Note, however, the arduino library's printf() does not implement "%f", even if floating-point is loaded. – JRobert Dec 10 '16 at 0:48

Have you looked at the raw return value from ds18b20_temperature(), without casting it to float and then to int, perhaps in hex? It may not be your printing code that's causing trouble but the value returned from the function. If the function is returning something equivalent to 51603, it is already bogus. DS18b20s temperature values are in 16-ths of a degree (Celsius, assuming the routine didn't convert it). 51603/16 is still an unreasonable value, not to mention that viewed as as a 16-bit int, the sign bit is set. Is it truly negative? Did something overlow?

I think you need to look at what that function is doing.

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.