This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DS18B20+ temperature sensor not returning valid temperature data

Other Parts Discussed in Thread: TM4C129XNCZAD, TM4C1294NCPDT

Hello, I'm using a TM4C1294 launchpad and is trying to communicate with the DS18B20+ temperature sensor (this is practically the same as the DS18B20). I'm using the UART modules that the microcontroller provides to interface with the 1-wire protocol that the sensor uses. The circuitry can be found in Figure 2b on this link:  

Here is the code:

//*****************************************************************************
//
// This functions checks the temperature inside the compost container.
//
//*****************************************************************************
uint32_t checkTemperature(uint32_t g_ui32SysClock)
{
	int32_t temperature_value_1 = 0;
	int32_t temperature_value_2 = 0;
	int32_t temperature_value_3 = 0;

	int32_t decimal_value_1 = 0;
	int32_t decimal_value_2 = 0;
	int32_t decimal_value_3 = 0;

	int32_t detect_1 = 0;
	int32_t detect_2 = 0;
	int32_t detect_3 = 0;

	int32_t i = 0;
	int32_t data = 0;

	char temp_var_1[4] = {};
	char temp_var_2[4] = {};
	char temp_var_3[4] = {};

	bool temp_1_is_negative = false;
	bool temp_2_is_negative = false;
	bool temp_3_is_negative = false;

	//
	// Initialize the UARTs for reset and presence detection.
	//
	configTempSensUART(g_ui32SysClock, 9600);

	//
	// Check if devices are present and ready.
	//
	while (1)
	{
		//
		// Transmit reset pulse to 1-wire devices.
		//
		transmitTempSensPulse(0xF0);

		//
		// Get the values in the receive FIFO.
		//
		while ((detect_1 = MAP_UARTCharGetNonBlocking(UART5_BASE)) == -1);
		while ((detect_2 = MAP_UARTCharGetNonBlocking(UART6_BASE)) == -1);
		while ((detect_3 = MAP_UARTCharGetNonBlocking(UART7_BASE)) == -1);

		//
		// If values are not equal to 0xF0, then devices are detected.
		//
		if ((detect_1 != 0xF0) && (detect_2 != 0xF0) && (detect_3 != 0xF0))
		{
			break;
		}

		//
		// Display message.
		//
		UARTprintf("Temperature sensors not detected. Make sure all three "
				"sensors are connected.\n");
	}

	//
	// Re-initialize the UARTs for sending commands and reading.
	//
	configTempSensUART(g_ui32SysClock, 115200);

	//
	// Transmit command 0xCC to skip ROM command.
	//
	transmitTempSensCommand(0xCC);

	//
	// Transmit command 0x44 to initiate temperature conversion.
	//
	transmitTempSensCommand(0x44);
	MAP_SysCtlDelay(g_ui32SysClock / 3 / 1000 * 750); // 750 ms delay

	//
	// Re-initialize device access.
	//
	configTempSensUART(g_ui32SysClock, 9600);
	transmitTempSensPulse(0xF0);
	configTempSensUART(g_ui32SysClock, 115200);
	transmitTempSensCommand(0xCC);

	//
	// Transmit command 0xBE to get temperature data.
	//
	transmitTempSensCommand(0xBE);

	//
	// Configuring the UART disables and enables the UART. Here it is being
	// used to clear the FIFO before reading.
	//
	configTempSensUART(g_ui32SysClock, 115200);

	//
	// Tell device to send value back. Total of 2 bytes, but stored over 4
	// indexes, with 4 bits per index.
	//
	for (i = 15; i >= 0; --i)
	{
		//
		// Send a read pulse to device, then clear the FIFO.
		//
		transmitTempSensPulse(0xFF);

		//
		// Get the temperature value from sensor 1.
		//
		while ((data = MAP_UARTCharGetNonBlocking(UART5_BASE)) == -1);
		if (data == 0xFF)
		{
			temp_var_1[i/4] >>= 1;
			temp_var_1[i/4] |= 0x08;
		}
		else
		{
			temp_var_1[i/4] >>= 1;
		}

		//
		// Get the temperature value from sensor 2.
		//
		while ((data = MAP_UARTCharGetNonBlocking(UART6_BASE)) == -1);
		if (data == 0xFF)
		{
			temp_var_2[i/4] >>= 1;
			temp_var_2[i/4] |= 0x08;
		}
		else
		{
			temp_var_2[i/4] >>= 1;
		}

		//
		// Get the temperature value from sensor 3.
		//
		while ((data = MAP_UARTCharGetNonBlocking(UART7_BASE)) == -1);
		if (data == 0xFF)
		{
			temp_var_3[i/4] >>= 1;
			temp_var_3[i/4] |= 0x08;
		}
		else
		{
			temp_var_3[i/4] >>= 1;
		}
	}

	//
	// Stop reading data.
	//
	configTempSensUART(g_ui32SysClock, 9600);
	transmitTempSensPulse(0xF0);

	//
	// Check if temperatures are in the negatives.
	//
	if (temp_var_1[0] == 0x0F)
	{
		temp_1_is_negative = true;
	}
	if (temp_var_2[0] == 0x0F)
	{
		temp_2_is_negative = true;
	}
	if (temp_var_3[0] == 0x0F)
	{
		temp_3_is_negative = true;
	}

	//
	// Convert data to Celsius.
	//
	temperature_value_1 = (temp_var_1[1] << 4) | temp_var_1[2];
	temperature_value_2 = (temp_var_2[1] << 4) | temp_var_2[2];
	temperature_value_3 = (temp_var_3[1] << 4) | temp_var_3[2];
	decimal_value_1 = temp_var_1[3] * 625;
	decimal_value_2 = temp_var_2[3] * 625;
	decimal_value_3 = temp_var_3[3] * 625;
	while (decimal_value_1 % 10 == 0)
	{
		decimal_value_1 /= 10;
	}
	while (decimal_value_2 % 10 == 0)
	{
		decimal_value_2 /= 10;
	}
	while (decimal_value_3 % 10 == 0)
	{
		decimal_value_3 /= 10;
	}

	//
	// Print temperature values.
	//
	if (temp_1_is_negative)
	{
		UARTprintf("temperature_value_1 = -%d.%d %cC\n", temperature_value_1,
				decimal_value_1, 248);
	}
	else
	{
		UARTprintf("temperature_value_1 = %d.%d %cC\n", temperature_value_1,
				decimal_value_1, 248);
	}
	if (temp_2_is_negative)
	{
		UARTprintf("temperature_value_2 = -%d.%d %cC\n", temperature_value_2,
				decimal_value_2, 248);
	}
	else
	{
		UARTprintf("temperature_value_2 = %d.%d %cC\n", temperature_value_2,
				decimal_value_2, 248);
	}
	if (temp_3_is_negative)
	{
		UARTprintf("temperature_value_3 = -%d.%d %cC\n\n", temperature_value_3,
				decimal_value_3, 248);
	}
	else
	{
		UARTprintf("temperature_value_3 = %d.%d %cC\n\n", temperature_value_3,
				decimal_value_3, 248);
	}

	return STATUS_NORMAL;
}

//*****************************************************************************
//
// Configure UART modules used by temperature sensors to specified baud rate.
//
//*****************************************************************************
void configTempSensUART(uint32_t g_ui32SysClock, uint32_t ui32Baud)
{
	//
	// Initialize the UARTs. Set the baud rate, number of data bits, turn off
	// parity, number of stop bits, and stick mode.
	//
	MAP_UARTConfigSetExpClk(UART5_BASE, g_ui32SysClock, ui32Baud,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
	MAP_UARTConfigSetExpClk(UART6_BASE, g_ui32SysClock, ui32Baud,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
	MAP_UARTConfigSetExpClk(UART7_BASE, g_ui32SysClock, ui32Baud,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
}

//*****************************************************************************
//
// Send specified command to UART modules used by temperature sensors.
//
//*****************************************************************************
void transmitTempSensCommand(char command)
{
	uint32_t i = 0;

	//
	// Transmit command LSB first.
	//
	for (i = 0; i < 8; ++i)
	{
		if ((command >> i) & 0x01)
		{
			while (!MAP_UARTCharPutNonBlocking(UART5_BASE, 0xFF));
			while (!MAP_UARTCharPutNonBlocking(UART6_BASE, 0xFF));
			while (!MAP_UARTCharPutNonBlocking(UART7_BASE, 0xFF));
		}
		else
		{
			while (!MAP_UARTCharPutNonBlocking(UART5_BASE, 0x00));
			while (!MAP_UARTCharPutNonBlocking(UART6_BASE, 0x00));
			while (!MAP_UARTCharPutNonBlocking(UART7_BASE, 0x00));
		}
	}
}

//*****************************************************************************
//
// Send specified pulse to UART modules used by temperature sensors.
//
//*****************************************************************************
void transmitTempSensPulse(char pulse)
{
	while (!MAP_UARTCharPutNonBlocking(UART5_BASE, pulse));
	while (!MAP_UARTCharPutNonBlocking(UART6_BASE, pulse));
	while (!MAP_UARTCharPutNonBlocking(UART7_BASE, pulse));

	//
	// Check for values. Loop until values are placed in the receive FIFO.
	//
	while (!MAP_UARTCharsAvail(UART5_BASE) &&
			!MAP_UARTCharsAvail(UART6_BASE) &&
			!MAP_UARTCharsAvail(UART7_BASE));
}

Right now, the 3 sensors are returning the same 2 bytes 07FF every time, which translate to +127.9365 degree Celsius based on the datasheet. I'm not sure where it is getting this number, or why it's the same number every time. 


Here is the link to the datasheet for reference: 

 

  • Let the record show that poster has (nearly) an exact duplicate posting:

    e2e.ti.com/.../536423

    Duplication will NOT speed response - instead disturbs & confuses responders - while making post classifications harder...
  • Hi,

    Do not know if you really checked TI's docs - there are micros with built-in dedicated one-wire modules, like TM4C129xNCZAD, and even more, there is an one-wire library file for these modules, in Tiva driverlib.  ( and this module is for Dallas devices designated..). Otherwise, (for me), your work looks like an undeserved self-punishment. Why do not use what is really available? Also, your doc, (Maxim's) has last lines indicating some software application notes for other processors - did you looked at?

  • cb1_mobile,

    I apologize. I did someone on the previous post if I should create a new post for my problem, but I didn't get an answer so I just went ahead with it, since the two problems weren't really the same problem, just related. The answer to the other post (which I have already found) is not the same answer as the one for this.

    Thomas

  • Petrei,

    Yes I did check, and I do know that. But, the microcontroller on the TM4c1294 launchpad is a TM4C1294NCPDT, which does not have 1-wire modules, and does not support 1-wire APIs. I also know that there exists a sensor library specifically for this sensor, but all the examples I see are used with Arduinos.

    Thomas
  • Hi,

    I can see something else:

    Related Application Notes

    The following application notes can be applied to the DS18B20 and are available at www.maximintegrated.com.

    Application Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products

    Application Note 122: Using Dallas’ 1-Wire ICs in 1-Cell Li-Ion Battery Packs with Low-Side N-Channel Safety FETs Master

    Application Note 126: 1-Wire Communication Through Software

    Application Note 162: Interfacing the DS18x20/DS1822 1-Wire Temperature Sensor in a Microcontroller Environment

    Application Note 208: Curve Fitting the Error of a Bandgap-Based Digital Temperature Sensor

    Application Note 2420: 1-Wire Communication with a Microchip PICmicro Microcontroller

    Application Note 3754: Single-Wire Serial Bus Carries Isolated Power and Data

    Sample 1-Wire subroutines that can be used in conjunc- tion with Application Note 74: Reading and Writing iBut- tons via Serial Interfaces can be downloaded from the Maxim website.

    This is the last page in your posted document. AN 162,  AN 2420  should be read; possible some C routines, as usual, and you may need to write/modify some low level routines.

    Do not forgot what Robert advised you - and I second one - maybe analog transducers could be more easy/efficient to use - depend on your project - this 1-w may use the processor more than needed; analog can be last priority in a project.

  • Petrei,

    But there isn't anything you could tell me about my code now and the reason why it's producing the problem? I don't see why there is a need to go to other routes when this one is actually functioning (communication is already established, just not valid responses from slave device). I've taken a look through the appnotes that seems related to what I need:

    - Application Note 126: 1-Wire Communication Through Software
    - Application Note 162: Interfacing the DS18x20/DS1822 1-Wire Temperature Sensor in a Microcontroller Environment

    And all the codes mentioned in there are all ones that I can figure out from reading the datasheet, and ones that I already have implemented in my code posted above. Also, they're used with the pins acting as GPIOs, where you'd have to manually drive the pin high or low for a specific amount of time, whereas mine (also follows one of the appnote from Maxim) uses the UART modules, which works the same way anyways.

    Thomas
  • Hi,

    Maybe your code is not yet what the chip needs to emit a good result. At least this is the result of some rapid comparation with what others have done. Look also to this link:

     which has conditional compilation  for Tiva. Check also the timings realized by this implementation and compare with yours. Keep in mind there could be other solutions to a problem, do not insist too much with a single one if that does not give good results.

  • I agree with Petrei, there's a lot to be said for using a known good library.

    That said, if you are going to continue on this now is the time to hook up your oscilloscope and verify the waveforms against the Dallas/Maxim datasheets.

    Mind you from what I've so far I'd be tempted to use discrete temperature sensors, maybe even RTD or thermocouple.

    Robert
  • Speaking of libraries, www.maximintegrated.com/.../public-domain-kit.html is I think the library I have used in the past. You just need to provide some low level driver functions, it deals with the higher level support.

    Robert
  • And - as so many GPIO stand "ready/waiting" - was the "One Wire" device (really) so necessary? (especially so - as it's NOT natively supported by your MCU)

    You're encountered TWO delaying issues already - there's no guarantee that (still more) do not await... You state that "communication is already established" - but don't convincingly detail that claim. Clearly - communication is your first order of business - and only when that's (really) mastered - are you ready to attempt sensor, "command/control."
  • All,

    Sorry, it seems that I did not include enough details about why I believe that "communication is already established". Based on the datasheet, to access the sensor every time, the code has to go through 3 routines. The first is the initialization where the master sends a reset pulse to the slave, and the slave reply with a presence pulse to let the master knows that it's there. The second routine then consists of the master sending a ROM command (1 byte, or 8 bits, with each bit at a time and the LSB first). Then afterward, in the final routine, the master can then send the actual sensor function to the slave.

    The reason why I was sure that communication between the master and the slaves was okay is because (and this is not within the code I posted) the first thing I did was sending the slave a ROM command of 0x33, which is the "Read Rom" command. This tells the slave to return its unique 64-bit ROM code, or address. I checked the code for all 3 of my devices to be valid, as they all end in the byte 0x28, which is the unique identifier byte for the DS18B20 sensor family. I've also tried issuing the command "Write Scratchpad" and "Read Scratchpad", both of which also functioned correctly, as the values read from the scratchpad are the same ones that I wrote in. This is why I was confident that there is communication between the master and the slaves.

    I did not include the "Read Rom" command in my code because it isn't necessary when there is only a single slave device on the bus. That is also the reason why I kept it one slave per bus, as it simplifies the code. Also, there was extra room to do so. I will transition to multiple devices per bus if there is a need to make room for other peripherals. I chose this sensor because I got them as free samples from Maxim, which helps to lower total cost. I could try to search for other sensors, but that costs extra time and money. Though if I can't resolve the problem with this sensor, then I will do so.

    I don't have an oscilloscope at home, but I will get my hands on one when I go on campus Monday, and verify the waveforms. Thanks for all of the suggestions.

    Thomas
  • Sometimes, as you may be finding, free devices are worth less than you pay monetarily.

    Discrete analog temperature sensors are about 0.25 in small quantities in a to92 case like the device you are using. That case is rather fragile and will require careful mounting and wiring and protection. But they are cheap and cheerful sensors.

    What would push you to RTD or thermocouple is the need for robustness or accuracy. Neither are inherently robust but they do come packaged in robust arrangements. I'm working with an RTD now that is packaged in a sealed metal cylinder.

    Given your description so far I'd want to evaluate whether the sensor is going to be in a harsh environment. I. e. moist with outside forces on it. If not then cheap and cheerful may be sufficient, otherwise the more industrial type may be needed.

    Robert
  • Robert Adsett72 said:
    Sometimes, as you may be finding, free devices are worth less than you pay monetarily.

    Bravo Robert, methinks that SO needed to be said.

    While you (may) consider the many "lost hours" (both yours - and those aiding you, here) "free" - when you enter the "real world" (i.e. for pay work) you will learn (rather quickly) to avoid blind/dark alleys!   (i.e. little supported, extremely minority usage application devices)

    "One Wire" sprang to life when 8-bit MCUs ruled the earth - and GPIOs were in short supply.   (MCU pins then were devoted (primarily) to address (16) & data (8)  - leaving few for GPIO.)   Clearly that time - and those days - have passed.   The complexity & rarity of "One Wire" remove it from, "optimal choice device!"   Even if - and especially if - it is free!

    As poster Robert has outlined - device choice must first, "Satisfy the application" - cost should rise in concern only later - as & if needed.  (often it is not...)

    Premature "cost-management" efforts - most ALWAYS - yield (only) serious COST OVER-RUNS!   (due to the delay introduced by complexity - just as occurred right here - right now...)

  • cb1,

    Thank you for yours and Robert's suggestion, even though your reply does sounds a bit hostile or frustrated because of my "poor" decision and reasoning for using this specific device. I will look into others if I cannot get this to work. I don't believe that the solution to any problem, or at least to this problem, is to simply take the easy way out and choose a different device rather than trying to figure out what the problem is with the current one. I understand that this sensor isn't the most optimal, or the most simple, but I currently do not see a reason to upgrade to a better one unless there is actually a known issue with this specific sensor that prevents it from working with the setup that I have.

    As I said, I do think that I am very close to getting this to work, as I already have communication established between the master and slave, and proofs to back that claim up. But yes, for future reference, I will pay more attention to compatibility and other factors. It doesn't seems like this is a problem that can be resolved simply based on the details that I provided, since we're now moving toward other recommendations rather than focusing on the problem in the OP, but thank you for taking your time to look at it. I will perform a more thorough verification with the oscilloscope, run some more tests, and if I am able to figure out what the problem is, I will post it on here for anyone else who might have the same problem with this sensor, as it is, as you said, not well-supported.

    Thomas

  • Not meant to be hostile Thomas, just providing a different perspective.

    Speaking of which, I've a different perspective on the rise and purpose of 1-Wire than cb1 presented.

    As I remember the original 1-Wire devices came only in the F5 cans, there were no PCB mountable devices. The PCB mountable devices came later and I think the only problems they solved were to provide a method for putting 1-wire devices on a PCB where you already had an external 1-wire network and providing a unique ID (the IC for the latter was, I think, the first PCB mountable 1-wire device but I could be easily mistaken on that)

    One wire devices do not use fewer IC pins than other interfaces (You need a pin to provide a controlled pulse and another to read the resulting width1 and, in some cases at least, a third to modulate the pull-up strength. Compare that to IIC (2 pins) and SPI (3-4 pins), both busses were widespread at the time 1-wire was around and 2 wire rs-232 was also very common. Current loop and other analog inputs use only a single IC pin with a reference line (ground) shared among all A/Ds on an IC

    So what did 1-wire provide to make it worthwhile

    • Reduced wiring
      • The multiple pins reduced to a single wire and the return line could use the chassis.
      • Multiple devices could run on a single bus
      • The bus could tolerate poor and even somewhat intermittent connections
    • Environmental protection, that F5 can since re-named as i-buttons. Note that SPI/IIC are generally not suited for running off of the PCB
    • Low power. Current Loop and voltage devices require power in addition to the signal wiring. The 1-wire runs off of power gathered from the signal wire (or signals run on the power wire depending on your perspective).

    Wireless can now take care of a number of the wiring advantages of 1-wire but they still require power and generally have a price premium compared with the 1-wire devices. I haven't used wireless or 1-wire in some time myself simply because I haven't had the need to reduce wiring that couldn't be handled in another fashion (such as CAN with local sensors).

    Robert

    1 - It may be possible to combine those with care but I've not seen an example or an application note where anyone has done so. It may be a chancy thing to do.

  • Hello ;

    Can you please explain to me how i can use the one wire Library to read the temperature from the Ds18b20 by TM4C1294NCPDT,

    and do i need Dallas temperature Library also which i can not finde to the Texas instruments ?

    Thank You

  • Anwar,

    To my knowledge, the 1-wire APIs that are mentioned in the Tiva Peripheral Driver Library cannot be used with the TM4C1294NCPDT, as this specific microcontroller does not have a 1-wire module. As for the existing library out there (the one that Petrei post a link to), which I've taken a look through, it seems to have been created for usage with Arduino boards. You could copy the formatting and try to make it work for the TM4C1294NCPDT, but there isn't any specific library for this microcontroller to interface with 1-wire devices. This is a reason why I went with interfacing using UART modules based on the appnote from Maxim.

    Thomas
  • Check the link I provided Thomas, that's for any microcontroller.

    Robert
  • All,

    I was able to resolve the issue after moving from using parasitic power to using external power. Since the slave device is only powered when data is being sent over from the master device, after sending the command "Convert T", I did not pull the bus high so that the slave device could be supplied with the necessary current to perform the command. So I will either have the device externally powered, or keep it parasite-powered and just make sure that the bus is pulled high for the appropriate amount of time during temperature conversion.

    Thomas
  • Thank you Thomas .
  • Robert,
    Can you please send the link again , I can't find it. So I can use the one wire to TM4C1294NCPDT ?

    Thank you
    Anwar.
  • Just look at the earlier reply. It's only a few messages earlier in the thread.

    Robert
  • Hello Robert;
    Can i use this Library to TM4C1294NCPDT whith DS18B29 temp sensor ?? Did you try it ?
    I can not prgramming so can you please explain how it can be used ?

    Thank you !
  • Hello Thomas!
    Can you please send to me Your code that i can use it to measure the temperature by thDS18B20 . I am very new in MUC world and It is not matter which code I use the important for me is to read the correct temperature by this sensor.
    I see that you use some functions which i don't know where they come from so which headers are u using ?

    Thank you :)
  • Hi M_A,

    The only 3 functions that I implemented myself are the one listed above. The other functions that are called within these 3 functions are all from either the Tiva C driver library, which can be found here www.ti.com/.../spmu298d.pdf, or from the sensor datasheet that I provided in the OP.

    I would just like to note that my implementation is using the UART module to communicate with the 1-wire module on the sensor. If you look at the sensor datasheet, it mentions the procedure that you have to go through (3 steps in total), which you can see in my code as well. If you are using a different microcontroller or launchpad, one that does support 1-wire API, I would suggest using that instead.

    Thomas

  • M_A said:
    Can i use this Library to TM4C1294NCPDT whith DS18B29 temp sensor ??

    It's a very generic library in terms of h/w requirements. I'd be shocked if any TM4C didn't have sufficient H/W support.

    M_A said:
    Did you try it ?

    No. So far I've used standard analog sensors with TM4Cs. No long runs with bad connections so not much need for 1-Wire

    M_A said:
    I can not prgramming so can you please explain how it can be used ?

    As I recall the documentation that comes with the library was fairly self explanatory.

    Robert

  • Thank you fro the answer .
    Which header files did you use ?
  • Thank you very much :)
  • Hi M_A,

    I used the following:

    #include <stdint.h>
    #include <stdbool.h>
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/uart.h"
    #include "inc/hw_memmap.h"
    #include "utils/uartstdio.h"

    Thomas