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.

1-Wire Temperature Sensor Interface TM4C1294 launchpad

Hi, just a warning that this post will be somewhat long as I wanted to include as much details as possible for easier support.

The problem I'm having is that the sensors will only read in values once, and then it's stuck. Also, I'm not sure if it's reading in the right values or not.


I'm trying to interface with a 1-wire temperature sensor DS18B20+ from Maxim with the TM4C1294 launchpad. I'm following the instruction on how to do so at this link here from maxim, where it uses the UART module to interface with the 1-wire device. I connected everything based on Figure 2b.

Here is a picture of how it looks. I'm quite sure that it's correct, but then I could have overlooked something. The sensor (black device at bottom) has its GND and VCC pin both connected to ground (as the DQ line can be both data and power). The DQ line (middle) is pulled up by a 4.7k Ohm resistor (with a 5V power supply). It is also connected to both the TX and RX pin from the launchpad. The RX wire is the wire directly from the device to the launchpad. The TX wire is the wire going from the device to the open-drain buffer NC7WZ07, and then to the launchpad. And then I have the white and gray wire which are for GND and VCC for the NC7WZ07.

Below is my code for UART module initialization:

void InitUART(uint32_t g_ui32SysClock)
{
	//
	// Enable the peripherals to be used.
	//
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART7);
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);

	//
	// Waits for peripherals to be ready.
	//
	while (!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UART5) &&
			!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UART6) &&
			!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UART7) &&
			!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOC) &&
			!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOP));

    //
    // Configure GPIO Pins for UART mode.
    //
    MAP_GPIOPinConfigure(GPIO_PC6_U5RX);
    MAP_GPIOPinConfigure(GPIO_PC7_U5TX);
    MAP_GPIOPinConfigure(GPIO_PP0_U6RX);
    MAP_GPIOPinConfigure(GPIO_PP1_U6TX);
    MAP_GPIOPinConfigure(GPIO_PC4_U7RX);
    MAP_GPIOPinConfigure(GPIO_PC5_U7TX);
    MAP_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5 |
    		GPIO_PIN_6 |GPIO_PIN_7);
    MAP_GPIOPinTypeUART(GPIO_PORTP_BASE, GPIO_PIN_0 | GPIO_PIN_1);

	//
	// 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, 115200,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
	MAP_UARTConfigSetExpClk(UART6_BASE, g_ui32SysClock, 115200,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
	MAP_UARTConfigSetExpClk(UART7_BASE, g_ui32SysClock, 115200,
			UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
}

Below is the code for reading in values from the FIFO:

uint32_t checkTemperature()
{
	int32_t temperature_value_1 = 0;
	int32_t temperature_value_2 = 0;
	int32_t temperature_value_3 = 0;

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

	//
	// Get the values in the receive FIFO.
	//
	while ((temperature_value_1 =
			MAP_UARTCharGetNonBlocking(UART5_BASE)) == -1);
	while ((temperature_value_2 =
			MAP_UARTCharGetNonBlocking(UART6_BASE)) == -1);
	while ((temperature_value_3 =
			MAP_UARTCharGetNonBlocking(UART7_BASE)) == -1);

	//
	// Display temperature values
	//
	UARTprintf("temperature_value_1 = %i\ntemperature_value_2 = %i\n"
			"temperature_value_3 = %i\n", temperature_value_1,
			temperature_value_2, temperature_value_3);

	return STATUS_NORMAL;
}

Right now, the code is going into checkTemperature() once, and the the first time through it prints out the value 1280 for all three values. When it enters the function again the second time, it gets stuck at the "// Check for values. Loop until values are placed into the receive FIFO." loop. I'm not exactly sure how the control flow is supposed to be, and how to get it to continuously read in values. Also, the value 1280 seems incorrect, as I tried to hold the sensor with my fingers to warm it up, but the value read in was still 1280.

Any help would be greatly appreciated.

Thanks.

 

  • I have done one wire before but not with UART. I don't have time to read this appnote but a few notes
    All the appnotes I've seen use a single UART not three
    Your wiring shows only a single sensor but you are reading three?
    You need an electrical interface to the bus and that usually needs more than the passives apparent.
    Finally with the embarrassment of timers on these devices I'd skip the crude lashup of using a UART to emulate a timer and use the timers directly.

    Robert
  • Robert,

    Yes I'm reading in 3. I have 2 other sensors connected on the board in another spot closer to their respective UART module pins so that's why I don't have them in the picture, but they are also connected the same way as the one shown, and all 3 are separated from each other.

    Could you give me some more info on using timers for these? I've never worked with timers before, and I can't imagine how they can be used in this situation.

    Thomas
  • 1-Wire protocol uses the power line as a communication line.  It does this by sending pulses to the attached device and reading back the length of the pulse.

    With timers you:

    • Send a pulse of a specified width
    • Measure the width of the pulse
    • Convert the width to a bit

    There are different pulse widths involved depending on whether the pulse is for a reset, an address query, a read bit or a write 0 or a write 1. There are also weak and strong pull-ups needed.

    With a UART you emulate the time by setting the baud rate and sending a character to emulate the timer pulse and read a character to emulate the measuring. There are possible issues with this

    • IIRC to generate the full range of pulses and read back with sufficient resolution you need to change baud rate for some functions
    • The read-back resolution is coarse and while it is normally sufficient the noise margin is much reduced.
    • Depending on UART there may be interactions with FIFOs etc...

    Side note: Your code looks way too short to have the probe pulse/read length per bit in it.  You cannot read the value back directly via a UART you must assemble bit by bit.

    Giving the cumbersome nature on a 1-wire interface, unless you have a good reason to use it, simple analog sensors are easier to use and generally cheaper and muxes are inexpensive. And they have the advantage of being available from multiple sources.

    Robert

  • Robert,

    Sorry for this amateur question, but what is the difference between write 0 and write 1? And likewise for read 0 and read 1? I've been seeing those come up during my research.

    Thomas
  • Short answer pulse width

    A write 0 will be a different pulse width than a write 1. i.e. you have to hold the pulse for a different amount of time. Similarly on a read the length of the pulse will indicate if it's a 0 or a 1.

    Robert
  • Robert,

    So I've gotten the master to communicate with the slave successfully, but I'm now encountering a different problem. Should I post the problem on here as a comment since it's still related to working with 1-wire sensor, or should I create a new post for it?

    Thomas
  • I see you've started a new thread.

    One further note on the hardware. 1-wire is designed to have multiple devices on the bus, you would save UARTs and maybe wire by using a single bus rather than three. Indeed the biggest strength of the bus may be in long bus lengths with sometimes marginal connections, especially with the cans

    Robert