DS2408 onewire switch

hello there, I'm trying to control a DS2408 onewire switch but not having much luck.

My aim is to use the device to control solid state relays to enable me to measure the voltage of 6 lead acid batteries connected series - parallel to give a 24v dc supply on a sailing boat.

I've connected the device to a Uno R3 using the diagram as shown on page 31 of the attached pdf data sheet as a guide, I am trying to control individual led's at the moment and not using relays or push buttons.

The only sketch that seems to do anything is the onewire example > DS2408_Switch. When connected with a DS18B20 temp sensor this is the serial monitor output:-

2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11100
No more addresses.

Occasionally the data reading changes to 11101

At the moment nothing changes when I connect pin 10 (rstz) pulled up via 10k resistors or pulled down to ground.

What I have established is I can read the id address of the ds2408, I have two of them and I can see different values when using the Dallas-Temperature > Tester sketch found in examples folder, so fairly confident they work.

I have also tried the onewirehub sketch > DS2408_Switch which as the info states in the sketch is an emulator and runs regardless of weather or not I have a device connected.

So, can anyone show me a working sketch where I can control the I/O pins of the ds2408 to control led's on or off?

I ask this because from online searches I cannot find any example sketch which will either compile and or work. I am wondering if my IC chips are in fact damaged even though I can read the ID address's.

Regards A_T

DS2408.pdf (634 KB)

Why do you have the pull-down from the IO pin (4)? The circuitry on page 31 of the datasheet doesn't have such a pull-down.

The only sketch that seems to do anything is the onewire example > DS2408_Switch.

That example connects the IO pin to D10 of the Arduino. If you modified it, post your actual test code!

When connected with a DS18B20 temp sensor this is the serial monitor output:-

Does that mean you get no output if you connect a DS2408 actually? It doesn't make sense to test code for a DS2408 using a DS18b20.

What I have established is I can read the id address of the ds2408, I have two of them and I can see different values when using the Dallas-Temperature > Tester sketch found in examples folder, so fairly confident they work.

Again, you test code using the wrong hardware. Very strange.

So, can anyone show me a working sketch where I can control the I/O pins of the ds2408 to control led's on or off?

The example code usually works. So, either you die the code wrong or one of the components is not working correctly (where components include the wires).

Welcome to the forum…Thanks :slight_smile:

Why do you have the pull-down from the IO pin (4)? The circuitry on page 31 of the datasheet doesn’t have such a pull-down.

No that is correct it doesn’t. My diagram is also wrong, see updated one. The 4k7 resistor is connected to +5v and IO (4). Without the resistor the sketch returns:- “No more addresses”.

EDIT I don’t seem to be able to attach an updated schematic drawing **

That example connects the IO pin to D10 of the Arduino. If you modified it, post your actual test code!

#include <OneWire.h>

/*
 * DS2408 8-Channel Addressable Switch
 *
 * Writte by Glenn Trewitt, glenn at trewitt dot org
 *
 * Some notes about the DS2408:
 *   - Unlike most input/output ports, the DS2408 doesn't have mode bits to
 *       set whether the pins are input or output.  If you issue a read command,
 *       they're inputs.  If you write to them, they're outputs.
 *   - For reading from a switch, you should use 10K pull-up resisters.
 */

OneWire net(2);  // on pin 2


void PrintBytes(const uint8_t* addr, uint8_t count, bool newline=false) {
  for (uint8_t i = 0; i < count; i++) {
    Serial.print(addr[i]>>4, HEX);
    Serial.print(addr[i]&0x0f, HEX);
  }
  if (newline)
    Serial.println();
}


void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte addr[8];

  if (!net.search(addr)) {
    Serial.print("No more addresses.\n");
    net.reset_search();
    delay(1000);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.print("CRC is not valid!\n");
    return;
  }

  if (addr[0] != 0x29) {
    PrintBytes(addr, 8);
    Serial.print(" is not a DS2408.\n");
    return;
  }

  Serial.print("  Reading DS2408 ");
  PrintBytes(addr, 8);
  Serial.println();

  uint8_t buf[13];  // Put everything in the buffer so we can compute CRC easily.
  buf[0] = 0xF0;    // Read PIO Registers
  buf[1] = 0x88;    // LSB address
  buf[2] = 0x00;    // MSB address
  net.write_bytes(buf, 3);
  net.read_bytes(buf+3, 10);     // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16
  net.reset();

  if (!OneWire::check_crc16(buf, 11, &buf[11])) {
    Serial.print("CRC failure in DS2408 at ");
    PrintBytes(addr, 8, true);
    return;
  }
  Serial.print("  DS2408 data = ");
  // First 3 bytes contain command, register address.
  Serial.println(buf[3], BIN);
}

Serial monitor result, with 4k7 resistor, then with resistor removed:-

813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11100
No more addresses.
2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11101
No more addresses.
2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11101
No more addresses.
2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11111
No more addresses.
2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11111
No more addresses.
2813BE3D422001C5 is not a DS2408.
Reading DS2408 29D98D05000000D7
DS2408 data = 11111
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.

This would imply that I need the pullup resistor for the onewire devices to be found.

Again, you test code using the wrong hardware. Very strange.

Extract from Tester sketch found in Dallas Temperature example folder:-

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9 // Lower resolution

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

I used this to to find the address of my DS2408 devices and prove (to me) that they might work.

So reading the notes: -

 * Some notes about the DS2408:
 *   - Unlike most input/output ports, the DS2408 doesn't have mode bits to
 *       set whether the pins are input or output.  If you issue a read command,
 *       they're inputs.  If you write to them, they're outputs.
 *   - For reading from a switch, you should use 10K pull-up resisters.

Do I actually need the 10k pullup as shown in data sheet or not, bearing in mind I want to switch the IO pins “on” or “off”.

Many thanks for your time, I really do appreciate any help.
I’m starting to go bald and that’s not a good look for me!

No that is correct it doesn't. My diagram is also wrong, see updated one. The 4k7 resistor is connected to +5v and IO (4). Without the resistor the sketch returns:- "No more addresses".

Yes, it needs a pull-up resistor, as the datasheet explicitly says:

4 I/O 1-Wire Interface. Open-drain, requires external pullup resistor.

This would imply that I need the pullup resistor for the onewire devices to be found.

It seems you still use the DS2408 code to test DS18b20 devices. I don't see the logic behind that...

Do I actually need the 10k pullup as shown in data sheet or not, bearing in mind I want to switch the IO pins "on" or "off".

Did you actually read that note? "For reading from a switch" implies that the pin is a input!

I used this to to find the address of my DS2408 devices and prove (to me) that they might work.

Does that mean above output was created with DS2408 connected? That would be rather bad because it wasn't recognized as such a device.

Hi Pylon, thanks for taking the time to reply.

Yes, it needs a pull-up resistor, as the datasheet explicitly says:

Yes that is true, however Figs 17, 20, 21 and 22 do not show any pullup resistors.
That is why I asked the question.

It seems you still use the DS2408 code to test DS18b20 devices. I don't see the logic behind that...

Actually the exact opposite. I used the Dallas Temperature > Tester sketch because it searches for all devices and reports back the internal lasered ID address. Because I can see the device ID of my DS2408 I think they are working.

Did you actually read that note? "For reading from a switch" implies that the pin is a input!

Yes, Fig 22 of the data sheet shows P7 I/O pin connected to a LED, with a 10k pullup resistor.
Is a LED switch? I would have expected to write to the I/O pin to turn the LED on.

The schematic diagrams are slightly confusing (for me at least).

So using Fig 22 as a starting point, I want to connect LED's to each I/O pin of the DS2408 and switch them independently, should I use 10k pullup resistors or not?

Using example 1 from the data sheet, connecting to one DS2408 device,
This seems to be the steps I need to take. Only I'm not sure how to write to the I/O pins.

//  Step 1  Config RSTZ to STRB

device.reset();
device.select(addr);  //Read selected device
device.write(0xcc);   //command to write to registers
device.write(0x8d);   //select the control status register
device.write(0x00);   // Not sure what this does !
device.write(0x04);   //set RSTZ mode to STRB

//  Step 2 Verify setting

device.reset();
device.select(addr);
device.write(0xf0);
device.write(0x8d);
device.write(0x00);

byte reg0x8d = device.read();
if (!(reg0x8d & 0b100)) {
 Serial.println("Writing to status register went wrong");
 }

 
//  STEP 3 Write PIO

device.write(0xcc);    //    Skip rom command  
//device.write(0x5a);    //    WRITE PIO byte, only I don't know how to do this bit
//device.write(0x5a);    //    WRITE Inverted PIO byte, only I don't know how to do this bit

Regards A_T

Yes, Fig 22 of the data sheet shows P7 I/O pin connected to a LED, with a 10k pullup resistor.
Is a LED switch? I would have expected to write to the I/O pin to turn the LED on.

An LED actually isn't a switch. In that context a switch means a physical switch that switches an input on or off. This is only meant as an input and that's what I pointed out. Of course you can use the device as outputs too but you have to differentiate between the two functionalities.

So using Fig 22 as a starting point, I want to connect LED's to each I/O pin of the DS2408 and switch them independently, should I use 10k pullup resistors or not?

No, the pull-ups are used if the pins are configured as inputs.

BTW, your LED current limiting resistors are too small. Even if you ensure programmatically that only one LED is on at a time the current will be near the maximum sinking current of the whole chip (20mA), depends a bit on the used LED but use at least 470Ω better 680Ω.

Using example 1 from the data sheet, connecting to one DS2408 device,
This seems to be the steps I need to take. Only I'm not sure how to write to the I/O pins.

Example 1 has two 0xCC bytes.

As your code is not complete I don't comment on it.

The output in your previous post is rather strange.

In this part of the code:

  if (addr[0] != 0x29) {
    PrintBytes(addr, 8);
    Serial.print(" is not a DS2408.\n");
    return;
  }

  Serial.print("  Reading DS2408 ");
  PrintBytes(addr, 8);
  Serial.println();

the 8 bytes of the "addr" array are printed twice without being changed in between but in your output there are two different addresses. Is that output actually what you got? In that case I must assume your board is damaged.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.