Introducing Maxim DS2482 1-wire master library

Hi,

I created a library for controlling DS2482 with Arduino for my project and I thought it might be useful for others too.

Library can be found at http://code.google.com/p/arduino-ds2482/. Any feedback will be appreciated.

Cheers!

Hi sivu; I am very new in Arduino and C. I have tried to work with the library for the ds2482 without results. Can you send me a program to be used as example?. Thanks and good work.

Here is an quick example:

#include <Wire.h>
#include <DS2482.h>

DS2482 ds(0);

void setup()
{
   Wire.begin();
   ds.reset();
   //configure DS2482 to use active pull-up instead of pull-up resistor
   //if (!ds.configure(DS2482_CONFIG_APU))
   //{
   //       Serial.print("DS2482 not found\n");
   //}
}

void loop()
{
    byte addr[8];

    if ( !ds.wireSearch(addr)) 
    {
        //Serial.print("No more addresses.\n");
        ds.wireResetSearch();
        return;
    }

}

So I think the main thing is that Wire library needs to be initialized and this fact is not very clearly stated in the DS2482 library. I will update the library soon.

Hi, This is a great library and has saved me tons to time. I am adding arduino wireless sensor nodes to an existing ethernut based web-managed alarm system. The DS2482 is conveniently add on a proto-shield from adafruit which contains a 14-pin SOIC pad just perfect for the 2482. The xbee shield from RoboSavvy completes the node hardware. Based upon you library, I've built another class which handles the DS2406 switch which connects all my sensors and drives the notification devices. I have a nifty parasitic circuit which derives the sensor power from the 1-wire line so that a typical door sensor needs only the 1-wire connection with no power. My problem is with the wireSearch method of your class. Perhaps I'm doing something wrong, but it seems to not find all the devices, depending upon what they are. For example if I add an old sensor based upon the DS2405 it finds only one and stops. If I add some i-buttons it finds everything correctly. I've never used and don't understand the 1-wire triple case-b which you use. I've added some debug printing to try to discover what's going wrong but at this point all I see is searchExhausted: Any ideas about this? Thanks for this great work! Don Here it discovers the 2405 device but not a 2406 also attached. If I remove the 05 then the 06 is detected. If I add a couple of i-buttons, both of them and the 06 is detected. I also see failures if a DS18s20 is attached. Arduino debug output: DS2482 Example: Config=5

Config..Scanning for Sensors: wireSearch: i=0 direction=1 point 2 : one 5

wireSearch: i=1 direction=0 point 2 : zero

wireSearch: i=2 direction=0 point 2 : one

wireSearch: i=3 direction=0 point 2 : zero ...

wireSearch: i=60 direction=0 point 2 : zero 4

wireSearch: i=61 direction=0 point 2 : zero

wireSearch: i=62 direction=0 point 2 : one

wireSearch: i=63 direction=0 point 2 : zero

: searchExhausted: copyRom=05:E9:EF:05:00:00:00:42: at:1448wireSearch: searchExhausted

No more sensors. Found 1 devices wrote eeprom config:1

SENSOR:0:05E9EF0500000042

I've done some more testing with debug printouts and also studied ApNote 187 and 3684. I believe the problem is when the first bit of two devices is different, as in my case of a family 05 and family 12 as the two devices. This statement from wireSearch: if (!firstBit && !secondBit && !direction) last_zero = i; does not set last_zero on the first bit discrepancy since direction is 1. I also don't understand how last_zero =0 can work since it is initialized as zero. I'm sure I'm just missing some fundamental concept. I've also been comparing this to the c code in the app note and can't see any problems. DEBUG RUN: DS2482 Example: Config=1 Config..Scanning for Sensors: Search: searchLastDiscrepancy=0 wireSearch: i=0 FORWARD direction=1 firstBit=0 secondBit=0 direction=1 point 2 :one

--NOTE here we should have set last_zero since this is bit where two devices differ: From Table 1 of ApNote 187

0 0 There are both 0s and 1s in the current bit position of the participating ROM numbers. This is a discrepancy.

wireSearch: i=1 FORWARD direction=0 firstBit=0 secondBit=1 direction=0 point 2 :zero

DEBUG for working config (two devices same family): DS2482 Example: Config=1 Config..Scanning for Sensors: Search: searchLastDiscrepancy=0 wireSearch: i=0 FORWARD direction=1 firstBit=20 secondBit=0 direction=128 point 2 :one wireSearch: i=1 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=2 FORWARD direction=0 firstBit=20 secondBit=0 direction=128 point 2 :one wireSearch: i=3 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=4 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=5 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=6 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=7 FORWARD direction=0 firstBit=0 secondBit=40 direction=0 point 2 :zero wireSearch: i=8 FORWARD direction=0 firstBit=20 secondBit=0 direction=128 point 2 :one wireSearch: i=9 FORWARD direction=0 firstBit=0 secondBit=0 direction=0 point 2 set last_zero=9 :zero

NOTE here we set last_zero correctly. (devices are 0567.. and 05E9.. so they differ in 9th bit position).

Hi,
Here’s my debug print version of wireSearch. It has also had a couple of other changes: 1) changed some var names to match the c code version in the app note, and 2) changed var values to be 0/1.
Vars changed are id->firstBit, comp_id->secdondBit and value of direction. This was done just to simplify my study of the c code.
Don

uint8_t DS2482::wireSearch(uint8_t *newAddr)
{
uint8_t i;
uint8_t direction = 0;
uint8_t last_zero=0xff;

if (searchExhausted)
{
serial->println(“wireSearch: searchExhausted”);
return 0;
}

if (!wireReset())
{
serial->println(“wireSearch no wireReset”);
return 0;
}

busyWait(true);
wireWriteByte(0xf0);

serial->print(“Search: searchLastDiscrepancy=”);
serial->println(searchLastDiscrepancy,DEC);
for(i=0;i<64;i++)
{
int romByte = i/8;
int romBit = 1<<(i&7);

serial->print(“wireSearch: i=”);
serial->print(i,DEC);
if (i < searchLastDiscrepancy)
{
serial->print(“searchAddress byte:”);
serial->print(searchAddress[romByte],BIN);
serial->print(" bit=");
serial->println(romBit, DEC);
// direction = searchAddress[romByte] & romBit;
if(searchAddress[romByte] & romBit)
direction = 1;
else
direction = 0;
}
else
{
serial->print(" FORWARD");
// direction = i == searchLastDiscrepancy;
if(i == searchLastDiscrepancy)
direction = 1;
else
direction = 0;
}
serial->print(" direction=");
serial->print(direction,DEC);
busyWait();
begin();
Wire.send(0x78);
Wire.send(direction ? 0x80 : 0);
end();
uint8_t status = busyWait();

// uint8_t firstBit = status & DS2482_STATUS_SBR;
uint8_t firstBit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR) ? (byte)1 : (byte)0;
// uint8_t secondBit = status & DS2482_STATUS_TSB;
uint8_t secondBit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB) ? (byte)1 : (byte)0;
// direction = status & DS2482_STATUS_DIR;
direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? (byte)1 : (byte)0;
serial->print(" firstBit=");
serial->print(firstBit, HEX);
serial->print(" secondBit=");
serial->print(secondBit, HEX);
serial->print(" direction=");
serial->print(direction,DEC);

if (firstBit && secondBit)
{
serial->print(" point 1");
return 0;
}
else
{
serial->print(" point 2");
// if 0 was picked then record its position in LastZero
// if (firstBit==0 && secondBit==0 && dir == 0)
if (!firstBit && !secondBit && !direction)
{
serial->print(" set last_zero=");
serial->print(i,DEC);
last_zero = i;
}
}

if (direction)
{
searchAddress[romByte] |= romBit;
serial->println(" :one");
}
else
{
searchAddress[romByte] &= (uint8_t)~romBit;
serial->println(" :zero");
}
}

searchLastDiscrepancy = last_zero;

if (last_zero == 0xff)
{
serial->print(": searchExhausted");
searchExhausted = 1;
}

serial->print(": copyRom=");
for (i=0;i<8;i++)
{
serial->print(searchAddress*,HEX);*

  • serial->print(":");*
    newAddr = searchAddress*;*
    * }*
    * serial->print("\n");*
    * return 1; *
    }

I believe this is the fix. I think this problem also exists in the example code in App Note 3684.
In class declaration: (DS2482.h)
// Change to signed int so value can be negative
// uint8_t searchLastDiscrepancy;
int8_t searchLastDiscrepancy;

In wireResetSearch: (DS2482.cpp)
// Initialize to negative value
searchLastDiscrepancy = -1;
This lets the search work properly on first bit by making the statement
if (i < searchLastDiscrepancy)
work correctly in the case of i = 0 and thereby sets initial direction to 0.

Here’s the successful debug run with a DS2405 and DS2413 on the bus:
DS2482 Example:
Config=1

Config…Scanning for Sensors:
Search: searchLastDiscrepancy=-1
wireSearch: i=0 FORWARD direction=0 firstBit=0 secondBit=0 direction=0 point 2 set last_zero=0 :zero
wireSearch: i=1 FORWARD direction=0 firstBit=1 secondBit=0 direction=1 point 2 :one
wireSearch: i=2 FORWARD direction=0 firstBit=0 secondBit=1 direction=0 point 2 :zero

wireSearch: i=62 FORWARD direction=0 firstBit=1 secondBit=0 direction=1 point 2 :one
wireSearch: i=63 FORWARD direction=0 firstBit=1 secondBit=0 direction=1 point 2 :one
: copyRom=12:0D:80:46:00:00:00:E9:
at:1552
Search: searchLastDiscrepancy=0
wireSearch: i=0 FORWARD direction=1 firstBit=0 secondBit=0 direction=1 point 2 :one
wireSearch: i=1 FORWARD direction=0 firstBit=0 secondBit=1 direction=0 point 2 :zero
wireSearch: i=2 FORWARD direction=0 firstBit=1 secondBit=0 direction=1 point 2 :one

wireSearch: i=62 FORWARD direction=0 firstBit=1 secondBit=0 direction=1 point 2 :one
wireSearch: i=63 FORWARD direction=0 firstBit=0 secondBit=1 direction=0 point 2 :zero
: searchExhausted: copyRom=05:E9:EF:05:00:00:00:42:
at:1581wireSearch: searchExhausted

No more sensors.
Found 2 devices
wrote eeprom config:2

SENSOR:1:05E9EF0500000042
Family:5
PIO=1 NAME=TESTING
SENSOR:0:120D8046000000E9
Family:12
2406
Status=FF:FF:FF:FF:FF:0:0:7F:ED:C1:
Channel Info:33

Hi,

Thank you for your comments about the library :) I think you did found the problem indeed, I used the appnote as the basis of the search function and did not encounter the problem you described in the earlier posts.

I've updated the library to include your fix. Thanks!