How to read a 1-wire sensor with C on a Raspberry Pi

Mel Wilson mwilson-Ja3L+HSX0kI at public.gmane.org
Fri Jan 17 15:17:50 UTC 2014


On Thu, 2014-01-16 at 21:25 -0500, Jamon Camisso wrote:
> On 16/01/14 08:43 PM, Mel Wilson wrote:
> [ ... ]
> I'm using a DS18B20 as well, hence that float rounding - it's supposed
> to be accurate to +/- 0.5C through most of it's range, but I've measured
> with other thermometers and it's close enough to 1/10th for my purposes.
> 
> I've used it with an Ardunino as well with the Dallas 1-wire scanning
> library. Is that what you used?

My apologies.  I'm way too shambolic in running these projects.  The
RHT03 temperature/humidity sensor (with its host of part-numbers) with
the Arduino is the setup I've got results from.  My DS18B20 project is
still only prototype code that will be run on an AVR.  Both of these
setups use bit-banged interfaces.

You're working farther up the food chain than I am.

Without actual results, just to post something, here's my initial
DS18B20 code (Some of those newlines are from the mail client.  Can't
get them out):


//=====================================
#ifndef DS18B20_H
#define DS19B20

#include <stdint.h>

typedef uint8_t romcode_t [8];

extern void delay_msec (int msec);
extern void delay_usec (int usec);


void bus_setup ();
uint16_t read_temperature (romcode_t device_rom);

#endif // DS18B20


//=====================================
#include <stdint.h>
#include "ds18b20.h"

#define bit_set(F,B)	(F |= (1<<(B)))
#define bit_clr(F,B)	(F &= ~(1<<(B)))
#define bit_tst(F,B)	(F & (1<<(B)))
#define bit_val(F,B)	(bit_tst(F,B) != 0)
#define pin_clr(P)	(bit_clr (P))
#define pin_set(P)	(bit_set (P))

#define BUS_OUTPUT_PIN	PORTB,2
#define BUS_INPUT_PIN	PINB,2
#define BUS_DDR_OUT	(bit_set (DDRB,2))
#define BUS_DDR_IN	(bit_clr (DDRB,2))


void bus_setup ()
{
	BUS_DDR_IN;
	pin_clr (BUS_OUTPUT_PIN);
} // bus_setup


static void bus_low ()
{
	BUS_DDR_OUT;
} // bus_low

static void bus_release ()
{
	BUS_DDR_IN;
} // bus_release

static uint8_t bus_pin ()
{
	return bit_val (BUS_INPUT_PIN);
} // bus_pin

static void master_write (uint8_t bit_val)
{
	bus_low();
	if (bit_val) {	// write "1" bit
		delay_usec (2);
		bus_release();
		delay_usec (58);
	}
	else {	// write "0" bit
		delay_usec (60);
		bus_release();
	}
} // master_write

static int master_read ()
{
	uint8_t val;
	bus_low();
	delay_usec (1);
	bus_release();
	delay_usec (14);
	val = bus_pin();
	if (!val)	// slave is driving bus pin low
		delay_usec (45);
	return val;
}// master_read

static uint8_t transaction_initialization()
{
	uint8_t delay_count;
	uint8_t slave_present;
	bus_low();
	delay_usec (480);	// reset pulse
	bus_release();
	while (!bus_pin()) ;
	delay_usec (14);
	slave_present = 0;
	for (delay_count=0; delay_count < 240; ++delay_count) {
		if (!bus_pin())
			slave_present = 1;
	}
	delay_usec (480 - 14 - delay_count);
	return slave_present;
} // transaction_initialization

static void transmit_uint8 (uint8_t data)
{
	uint8_t i;
	for (i=0; i < 8; ++i) {
		master_write (data & 1);
		data >>= 1;
	}
} // transmit_uint8

static uint8_t receive_uint8 ()
{
	uint8_t i, val;
	for (i=0; i < 8; ++i)
		val = val | (bus_pin() << i);
} // receive_uint8

uint8_t transaction (uint8_t rom_command, uint8_t function_command)
{
	if (!transaction_initialization())
		return 0;
	transmit_uint8 (rom_command);
	return 1;
} // transaction

uint16_t read_temperature (const romcode_t *device_rom)
{
	uint8_t scratchpad [9];
	if (!transaction_initialization())
		return 0xFFFF;
	transmit_uint8 (0x55);	// Match ROM
	for (i=0; i < 8; ++i)
		transmit_uint8 (device_rom [8-i]);
	transmit_uint8 (0x44);	// Convert T
	delay_msec (750);	// delay until conversion has been finished
	transaction_initialization();
	
	transmit_uint8 (0x55);	// match ROM
	for (i=0; i < 8; ++i)
		transmit_uint8 (device_rom [8-i]);
	
	transmit_uint8 (0xBE);	// read scratchpad
	for (i=0; i < 9; ++i)
		scratchpad [9-i] = receive_uint8();
	// ??? verify checksum
	return scratchpad[1] << 8 | scratchpad[0];
} // read_temperature


--
The Toronto Linux Users Group.      Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists





More information about the Legacy mailing list