0

I am using three DS2413 1-Wire GPIO Breakouts from Adafruit connected to an ESP8266. I tested the DS2413 breakouts using their example sketch and it works fine for just one DS2413. But I cannot get it to work when 2 or more DS2413s are connected.

Adafruit DS2413 Example Sketch https://github.com/adafruit/Adafruit_DS2413/blob/master/DS2413.pde

Adafruit DS2413 Overview
https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413?view=all

When I connect 2 or more DS2413s, it only blinks the LEDs connected to the 1st breakout and doesn't read the other addresses.

I made some changes to the void setup section and now I am getting the following in the serial monitor. It sees all the addresses, but it is duplicating them and the first set have "No device found on the bus!" at the end. How can I get the sketch to read all the addresses without these errors?

Serial monitor

Looking for a DS2413 on the bus
3A B2 C2 39 00 00 00 8C No device found on the bus!
3A 8E AE 39 00 00 00 2C No device found on the bus!
3A E5 B6 39 00 00 00 55 No device found on the bus!
Found a DS2413: 3A B2 C2 39 00 00 00 8C 
Found a DS2413: 3A 8E AE 39 00 00 00 2C 
Found a DS2413: 3A E5 B6 39 00 00 00 55

Here is what the code with my changes.

#include <OneWire.h>

#define DS2413_ONEWIRE_PIN  (4)

#define DS2413_FAMILY_ID    0x3A
#define DS2413_ACCESS_READ  0xF5
#define DS2413_ACCESS_WRITE 0x5A
#define DS2413_ACK_SUCCESS  0xAA
#define DS2413_ACK_ERROR    0xFF

OneWire oneWire(DS2413_ONEWIRE_PIN);
uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

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

byte read(void)
{      
  bool ok = false;
  uint8_t results;

  oneWire.reset();
  oneWire.select(address);
  oneWire.write(DS2413_ACCESS_READ);

  results = oneWire.read();                 /* Get the register results   */
  ok = (!results & 0x0F) == (results >> 4); /* Compare nibbles            */
  results &= 0x0F;                          /* Clear inverted values      */

  oneWire.reset();

  // return ok ? results : -1;
  return results;
}

bool write(uint8_t state)
{
  uint8_t ack = 0;

  /* Top six bits must '1' */
  state |= 0xFC;

  oneWire.reset();
  oneWire.select(address);
  oneWire.write(DS2413_ACCESS_WRITE);
  oneWire.write(state);
  oneWire.write(~state);                    /* Invert data and resend     */    
  ack = oneWire.read();                     /* 0xAA=success, 0xFF=failure */  
  if (ack == DS2413_ACK_SUCCESS)
  {
    oneWire.read();                          /* Read the status byte      */
  }
  oneWire.reset();

  return (ack == DS2413_ACK_SUCCESS ? true : false);
}

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

  Serial.println(F("Looking for a DS2413 on the bus"));

  /* Try to find a device on the bus */
  oneWire.reset_search();
  delay(250);
  while (oneWire.search(address)) {
       printBytes(address, 8);
       Serial.println(F("No device found on the bus!"));
} 
  /* Check the CRC in the device address */
  if (OneWire::crc8(address, 7) != address[7]) 
  {
    Serial.println(F("Invalid CRC!"));
    return;
  }

  /* Make sure we have a DS2413 */
  if (address[0] != DS2413_FAMILY_ID) 
  {
    printBytes(address, 8);
    Serial.println(F(" is not a DS2413!"));
    return;
  }

  while (oneWire.search(address)) {
  Serial.print(F("Found a DS2413: "));
  printBytes(address, 8);
  Serial.println(F(""));
}
}

void loop(void) 
{
  /* Read */
  /*
  uint8_t state = read();
  if (state == -1)
    Serial.println(F("Failed reading the DS2413"));
  else
    Serial.println(state, BIN);
  */

  /* Write */
  bool ok = false;
  ok = write(0x3);
  if (!ok) Serial.println(F("Wire failed"));
  delay(1000);
  ok = write(0x0);
  if (!ok) Serial.println(F("Wire failed"));
  delay(1000);
}

2 Answers 2

0

You have two detection loop in your setup function. This one can be safely deleted as for each detected device it will print the error message

while (oneWire.search(address)) {
   printBytes(address, 8);
   Serial.println(F("No device found on the bus!"));

}

0

I was able to get the ESP8266 to read all DS2413 devices without errors as well as blink each LED connected to the DS2413, individually, down the chain.

Here are animations of it working. multiple_DS2413_blink multiple_DS2413_read

I owe all the credit to mortonkopf on Github. His sketch DS2413_button_array_test, was exactly what I needed to be able to read the addresses on all DS2413 devices connected and blink each LED. Here is a link to his OneWire_DS2413_array repo.

https://github.com/mortonkopf/OneWire_DS2413_array

Here is the code I am using to make this work.

// This sketch is based on mortonkopf's DS2413_button_array_test sketch and allows 
// you to read multiple DS2413 devices and blink an LED connected to each DS2413, 
// individually, down the chain.
// https://github.com/mortonkopf/OneWire_DS2413_array
// 
// This sketch is an improvement on the write feature of the Adafruit DS2413 
// sketch which only reads 1 DS2413 device.
// https://github.com/adafruit/Adafruit_DS2413
// https://learn.adafruit.com/adafruit-1-wire-gpio-breakout-ds2413/reading-writing-and-arithmatic

#include <OneWire.h>

/* reading pins
0x0 (B00000000) - Both pins LOW
0x1 (B00000001) - IOA = HIGH, IOB = LOW
0x2 (B00000010) - IOA = LOW, IOB = HIGH
0x3 (B00000011) - Both pins HIGH
0xFF (B11111111) - Read Failed!
*/
#define DS2413_ONEWIRE_PIN  (4) // GPIO 4 on Adafruit Feather HUZZAH ESP8266

#define DS2413_FAMILY_ID    0x3A
#define DS2413_ACCESS_READ  0xF5
#define DS2413_ACCESS_WRITE 0x5A
#define DS2413_ACK_SUCCESS  0xAA
#define DS2413_ACK_ERROR    0xFF

#define BUTTON_NO 3 //use this for size of array to store state values//

OneWire oneWire(DS2413_ONEWIRE_PIN);
uint8_t address[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

byte Button_states[BUTTON_NO];//this is the array of button states//

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

byte read(void)
{ 
  bool ok = false;
  uint8_t results;

  oneWire.reset();
  oneWire.select(address);
  oneWire.write(DS2413_ACCESS_READ);

  results = oneWire.read();                 /* Get the register results   */
  ok = (!results & 0x0F) == (results >> 4); /* Compare nibbles            */
  results &= 0x0F;                          /* Clear inverted values      */

  oneWire.reset();

  // return ok ? results : -1;
  return results;
}

bool write(uint8_t state)
{
  uint8_t ack = 0;

  /* Top six bits must '1' */
  state |= 0xFC;

  oneWire.reset();
  oneWire.select(address);
  oneWire.write(DS2413_ACCESS_WRITE);
  oneWire.write(state);
  oneWire.write(~state);                    /* Invert data and resend     */    
  ack = oneWire.read();                     /* 0xAA=success, 0xFF=failure */  
  if (ack == DS2413_ACK_SUCCESS)
  {
    oneWire.read();                          /* Read the status byte      */
  }
  oneWire.reset();

  return (ack == DS2413_ACK_SUCCESS ? true : false);
}

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

  Serial.println(F("Looking for a DS2413 on the bus"));
}

void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  if ( !oneWire.search(address)) {
    Serial.println("");
    Serial.print("No more addresses.\n");
    oneWire.reset_search();
    delay(50); //was 250
    return;
  }
  Serial.println("");
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(address[i], HEX);
    Serial.print(" ");
  }  

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

  if ( address[0] != DS2413_FAMILY_ID) {
      Serial.print("Device is not a DS2413 family device.\n");
      return;
  }

// Blink each LED connected to the DS2413 one at a time
  bool ok = false;
  ok = write(0x1);
  if (!ok) Serial.println(F("Wire failed"));
  delay(200);
  ok = write(0x2);
  if (!ok) Serial.println(F("Wire failed"));
  delay(200);
  ok = write(0x0);
  if (!ok) Serial.println(F("Wire failed"));
  delay(200);
///////////////////

uint8_t state = read();
  const int IOA = 0x1;
  const int IOB = 0x2;

  if (state == -1)
  {
    Serial.println(F("Failed reading the DS2413"));
  }
  else
  {
    if (state & IOA)
    {
       Serial.print("   A");
    }
    if (state & IOB)
    { //can use this IO if needed to perfom tasks
        Serial.print("   B");
    }
  }

}

Here is a link to the Gist I created for this sketch. https://gist.github.com/orbitrod/51eb10c1a88f5747dc79298030e4480c

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.