1Wire code

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been trying to get the Dallas/maxim I wire code to work.
This is what I am working with:

#define	OWirePort	PORTA
#define OWirePinNo	3
#define OWireDDR	DDRA
#define OWirePIN	PINA

#define OWireOut	(OWireDDR |= _BV(OWirePinNo));
#define OWireIn		(OWireDDR &= ~_BV(OWirePinNo));
#define OWireHigh		(OWirePort |= _BV(OWirePinNo));
#define OWireLow		(OWirePort &= ~_BV(OWirePinNo));
#define OWireR		(OWirePIN & _BV(OWirePinNo));   

// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise
uint8_t OWireReset (void)
{
	uint8_t present;

	OWireOut;				// Set OWire to O/P
	OWireLow;					// Drive OneWirePin low
	_delay_us(480);
	OWireIn;				// Releases the bus & set to I/P
	_delay_us(70);
	present=OWireR;			// Sample for presence pulse from slave
	_delay_us(410);

	// 1 for no device & 0 for 1 or more devices present
	return present;			// Return sample presence pulse result
}

My problem as soon as the OWireReset is call, I always get a 1-Wire error.
I have a 4k7 resistor between Data Line and Vcc.

If I remove the DS18S20 and short PA3 to ground, then it mimics a device is connected.

Can anyone suggest what I am doing wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at https://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_type=project&item_id=1240. I did a small 1-wire library in C for that project.

The timing seems to be fairly critical for 1-Wire. A logic analyzer was very useful in checking the pulse train.

Cheers,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tom,
That's cool. I saw your project in a search but must admit thought man that is way too complicated. looking at it again I can see how your owire routine work, so I will try them.
I notice you have a 15k pull up. I thought Dallas requires a 4k7 pull up. I am wondering if that may contribute to my problem.
Cheers
Matt

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Matt,

For the 1-wire routines, look at owi_defs, owi_lowlevel, owi_highlevel, and the device specific implementations in ds18x20 and ds2415. You'll also want to look at crc for the checksum calculations.

I hope I've done a pretty good job decomposing the functions, and my coding style is pretty pedantic so it should be easy to follow.

The low level routines are all the port bit-banging for sending and receiving bits over the 1-wire bus - pretty much what you are working on right now.

The high level routines are the functions for sending and receiving bytes (both command and data) to the bus as well as device searching and enummeration.

The device specific code contains the routines for asking for and receiving device specific data. This is where you will need the crc routines to check the validity of the data packets. This is also where the concept of device IDs comes into play as commands are sent to a single device, or broadcast to all devices.

As for the pullup, I've tried a variety of values. The a smaller resistor is needed when supplying parasite power - something I had very little luck with. I was able to use a larger pull-up since I was supplying power directly to the 1-Wire bus. This larger pull-up reduced the power drain on the device's battery.

If you have any specific questions, fire away!

Cheers,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still no joy. I have used Tom's routines as written and I still can't detect a sensor.

I know it is a big ask, but I have included the whole project. Can I ask someone to review?

To recap. I have checked each port for connectivity and approximate timing using a 500ms delay toggling LEDs.
I am pretty sure I have not got a hardware issue.
I have also tried 3 new devices, just in case I stuffed one.

I also dug out an old BASCOM temp controller I worked on 6 years ago. It detects and reads all the sensors.

Matt

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Matt,

Are you sure you are using the right pin for OWI? OWI_defs.h has PD6 at the pin for the 1-Wire bus. I can't tell from your code exactly what your hardware connections are.

Cheers,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tom
Thanx for your continued assistance.

// 1-Wire Hardware connection - change depending on setup
#define OWI_PIN PB4
#define OWI_IN PINB
#define OWI_OUT PORTB
#define OWI_DDR DDRB

I am utilising the spare port on the LCD port.

#define LCD_PORT         PORTB        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    3            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    2            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    1            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    0           /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       7            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       6            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        5            /**< pin  for Enable line     */
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have tested your project with a 18S20. I had to change two things to get it to detect. In owi_bit_io() (owi_lolewel.c) this delay

    // response wait
    //delay_us( OWI_DELAY_E);
    delay_us( 1);

was too short for my sensor. Changing it to delay_us(2); or using this

        delay_us(OWI_DELAY_E);

fixed that.

In 18S20Therm.c I had to

 #include "crc.h"

The crc check will always fail if you don't. This is beacuse the check

else if( ! crc8( id, OWI_ROMCODE_SIZE))

will be for a 16 bit int while only 8 bits are actually returned. There is a compiler warning about this:

Quote:
warning: implicit declaration of function 'crc8'

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lars
Thanx for putting me straight.
I will let every one know how I succeed. with the rest.
Matt

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is cool. I can read Temperature of multiple sensors.
Tom and Lars, I couldn't have done this with out you help.
Cheers
Matt

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Matt_edwards wrote:
This is cool. I can read Temperature of multiple sensors.
Tom and Lars, I couldn't have done this with out you help.
Cheers
Matt

Then be sure to give my Multitherm project a good rating ;-)

It looks like both of you guys are using faster processors than I was, and I was guilty of a little over-optimization. On my board, the overhead of the delay_us routine was giving about 14us minimum pulse width and since OWI_DELAY_E is 9us, I modified it to get "my" timings as close as possible. Should have just left it well enough along.

Thanks for the help, Lars, and congratulations Matt on getting it working

Cheers,

Tom