Communication between DS2482 and DS28E17

Hello everyone,
I'm using an STM32L452RE-P, DS2482 module, DS28E17 module and SHT40 temperature sensor.
The STM32 is connected via I2C to the DS2482 module and this module is connected via 1-wire to the DS28E17.

I can communicate correctly with the DS2482. but I can't send commands to the DS28E17 and make sure I'm communicating correctly.
I use the arduino framework with the "Wire.h" library for the I2C connection.

Someone would have any idea ?

THANKS.

Please show a schematic of your setup and a clear photograph of how everything is wired together. Please also share the code you're running on the STM32 and indicate how the behavior of this code is different from what you want/expect. In doing so, please build a minimum implementation that demonstrates the problem without extraneous devices or code that do not relate to the issue at hand.

Ok !

You will therefore find attached a photo of the wiring schematic between the different components and some photos of the code.

When I say that I communicate correctly between the NUCLEO and the DS2482, this means that when for example I initialize channel oW0 and I come to do a reading I have the value 0xB8 which corresponds to the initialization of channel 0.

Then I would like to simply do something that ensures that I communicate with the DS28E17. So I first made the communication between NUCLEO and DS28E17 (with a GPIO) using the “OneWire.h” library. And I note the result of the "search": OneWire Device Found: 19:56:CA:4:0:0:0:3A

Then I try to go back to my project and do similar code to send the same commands but this time on the i2C bus. And when, I try to configure the transmission speed to 100khZ. The speed that I read next is "1A" which is inconsistent with the real value.

I hope this is a little clearer if you have any other questions I will answer them as soon as possible.



image

And here is the schematic :
image

There's no power supply. There's also no pullup on the OneWire bus.
Please show the entire schematic.
Please also show a photo of the setup as this generally helps to spot hardware/wiring problems that aren't apparent in a schematic and sometimes help augment data otherwise missing (see e.g. power supply comment).

Please post the code as a single sketch in 'code' tags; it's now unclear what exactly you're running. Screenshots of text are not as useful as actual text. Code tags help with formatting and make everything easy to read.

I don't see anything in your present code that does this or would create this "1A" output.

I hope that you're now starting to recognize that providing complete and consistent information will be critical in enabling others to help you with this issue. It's a relatively specific situation and muddling the waters and holding back information will make things unnecessarily complicated.

Here is the code :

void setup() {
  pinMode(I2C_SDA, INPUT);
  pinMode(I2C_SCL, INPUT);
  Serial.begin(115200);
  Serial.println("---------------------- START PROG ----------------------"); 
  // Serial.println("Initialisation OneWire...");

  i2c.begin();
  resetDS2482();    // Reset the DS2482

  selectChannelOW0();   // Select and initialize the channel oW0

  uint8_t status = readStatusDS2482();    // return the 0xB8
  Serial.print("Statut du DS2482: 0x");
  Serial.println(status, HEX);

  if (resetOneWireBus()) {    // Do a reset pulse
    test_writing_function();  // Write speed configuration to 100khz
  } else {
    Serial.println("ERROR RESET ONE WIRE");
  }

  Serial.println("AFTER FUNC");

  if (resetOneWireBus()) {    // Do a reset pulse
    test_reading_function();  // read the speed configuration
  } else {
    Serial.println("ERROR RESET ONE WIRE 2");
  }

  Serial.println("AFTER FUNC 2");
}

void select_DS28E17() {
  Serial.println("START OF SELECT FUNCTION");

  uint8_t data[] = {0x55, 0x19, 0x56, 0xCA, 0x04, 0x00, 0x00, 0x00, 0x3A};

  for (int i = 0; i < sizeof(data); i++) {
    i2c.beginTransmission(DS2482_ADDR);
    i2c.write(DS2482_CMD_WRITE_1WIRE);
    i2c.write(data[i]);

    if (i2c.endTransmission() == 0) {
      Serial.print("DATA 0X");
      Serial.print(data[i], HEX);
      Serial.println(" OK");
    } else {
      Serial.print("Error DATA 0X");
      Serial.println(data[i], HEX);
    }

    delay(10);
  }

  Serial.println("END OF SELECT FUNCTION");
}

void test_writing_function(){

  select_DS28E17();
  
  Serial.println("DEB WRITING FUNCTION");

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_1WIRE);
  i2c.write(0xD2);

  if (i2c.endTransmission() == 0) {
    Serial.println("DATA 0xD2 OK");
  } else {
    Serial.println("Error DATA 0xD2");
  }

  delay(1);

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_1WIRE);
  i2c.write(0x00);

  if (i2c.endTransmission() == 0) {
    Serial.println("DATA 0x00 OK");
  } else {
    Serial.println("Error DATA 0x00");
  }

  Serial.println("END WRITING FUNCTION");
}

void test_reading_function(){
  uint8_t read_command = 0xE1;
  uint8_t config_value;

  select_DS28E17();

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(0xA5);
  i2c.write(read_command);

  if (i2c.endTransmission() == 0)
  {
    Serial.println("DATA 0xE1 0xE1 OK");
  } else {
    Serial.println("Error DATA 0xE1 0xE1");
  }

  delay(10);

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(0x96);

  if (i2c.endTransmission() == 0)
  {
    Serial.println("DATA 0x96 OK");
  } else {
    Serial.println("Error DATA 0x96");
  }

      delay(10);

  i2c.requestFrom(DS2482_ADDR, 1);  // Lire un octet depuis le DS2482

  if (i2c.available()) {
    uint8_t config_value = i2c.read();
    Serial.print("Current configuration value: 0x");
    Serial.println(config_value, HEX);
  } else {
    Serial.println("Error reading configuration value");
  }

  // // Read the configuration value
  // config_value = i2c.read();

  // Serial.print("Current configuration value: 0x");
  // Serial.println(config_value, HEX);

  
}

// Result on the ouput

---------------------- START PROG ----------------------

DS2482 réinitialisé avec succès.

Canal OW0 sélectionné avec succès.

Statut du DS2482: 0xB8

Réinitialisation du bus OneWire réussie.

START OF SELECT FUNCTION

DATA 0X55 OK

DATA 0X19 OK

DATA 0X56 OK

DATA 0XCA OK

DATA 0X4 OK

DATA 0X0 OK

DATA 0X0 OK

DATA 0X0 OK

DATA 0X3A OK

END OF SELECT FUNCTION

DEB WRITING FUNCTION

DATA 0xD2 OK

DATA 0x00 OK

END WRITING FUNCTION

AFTER FUNC

Réinitialisation du bus OneWire réussie.

START OF SELECT FUNCTION

DATA 0X55 OK

DATA 0X19 OK

DATA 0X56 OK

DATA 0XCA OK

DATA 0X4 OK

DATA 0X0 OK

DATA 0X0 OK

DATA 0X0 OK

DATA 0X3A OK

END OF SELECT FUNCTION

DATA 0xE1 0xE1 OK

DATA 0x96 OK

Current configuration value: 0x1A

AFTER FUNC 2

Regarding the schematic, there is the power supply (3v3 line and GND).
For simplicity I use the 1-wire click and 1-wire I2C click I2C modules from MIKROE which use its components.
This is the entire outline of the project.

I only put this part of my code because it has a lot of unnecessary stuff and I don't want to confuse you.

HI, @tomfm
Welcome to the forum.

Are you using pullup resistors on the I2C lines?

Why are you using a one wire between the SHT40 and the Nucleo?
How far is the 1-Wire link?

Can you please post links to specs/data for the 2482 and 28E17?

Tom.. :smiley: :+1: :coffee: :australia:

OK, have you verified presence of the required pullup on the OneWire line?

Finally:

One more thing you can do is try to connect a DS18B20 or some other OneWire device in place of the 28E17 and see if you can talk to that.

Since I notice my responses are becoming a bit repetitive, I'll hold back on commenting further for now. Good luck with your project.

Hello Tom,

THANKS :slight_smile:

Indeed, on the 1wire click and 1wire I2C click I2C cards (which use the DS2817 and DS2482) already have pull-up resistors on the SDA and SCL lines but also a pull-up resistor on the 1-wire bus.
Indeed, I know that for my use (a few meters) it is not necessary to have both modules. However, I'm a little frustrated that I can't get them to work together because they're supposed to work together.

I will soon post a summary or the entirety of my code for the commands that I send between the different modules.

#include <Arduino.h>
#include <OneWire.h>
#include <Wire.h>

#include "DS28E17.h"

// Définir les broches I2C personnalisées
#define I2C_SDA PB11
#define I2C_SCL PB10

#define ONE_WIRE_BUS_PIN PA0
#define SHT40_ADDR 0x44
#define SHT40_CMD_MEASURE_HIGHREP 0xFD

/******************* DS2482 *******************/
#define DS2482_ADDR 0x18
#define DS2482_CMD_RESET 0xF0
#define DS2482_CMD_STATUS 0xF0
#define DS2482_CHANNEL_OW0 0xF0

#define DS2482_CMD_WRITE_CONFIG 0xD2
#define DS2482_CMD_SET_READ_PTR 0xE1
#define DS2482_CMD_CHANNEL_SELECT 0xC3
#define DS2482_CMD_1WIRE_RESET 0xB4
#define DS2482_CONFIG_APU 0x01  // Active pull-up enabled
#define DS2482_CMD_WRITE_1WIRE 0xA5

TwoWire i2c(I2C_SDA, I2C_SCL);
OneWire oneWire(ONE_WIRE_BUS_PIN);
DS28E17 ds28e17(&oneWire);


// PROTOTYPE OF FUNCTION
void detectOneWireDevices(); 
void c1wirei2c_write_configuration(uint8_t config);
void c1wirei2c_read_configuration();
void reading_temp_hum();
bool address_of_device(byte *addr);

// // PROTOTYPE OF FUNCTION
void resetDS2482();
void writeConfigDS2482(uint8_t config);
uint8_t readStatusDS2482();
bool resetOneWireBus();
void selectChannelOW0();
void select_DS28E17();
void test_writing_function();
void test_reading_function();

// TEST
void configureDS2482();


void setup() {
  pinMode(I2C_SDA, INPUT);
  pinMode(I2C_SCL, INPUT);
  Serial.begin(115200);
  Serial.println("---------------------- START PROG ----------------------"); 
  // Serial.println("Initialisation OneWire...");

  i2c.begin();
  resetDS2482();    // Reset the DS2482

  selectChannelOW0();   // Select and initialize the channel oW0

  uint8_t status = readStatusDS2482();    // return the 0xB8
  Serial.print("Statut du DS2482: 0x");
  Serial.println(status, HEX);

  configureDS2482();

  if (resetOneWireBus()) {    // Do a reset pulse
    test_writing_function();  // Write speed configuration to 100khz
  } else {
    Serial.println("ERROR RESET ONE WIRE");
  }

  Serial.println("AFTER FUNC");

  if (resetOneWireBus()) {    // Do a reset pulse
    test_reading_function();  // read the speed configuration
  } else {
    Serial.println("ERROR RESET ONE WIRE 2");
  }

  Serial.println("AFTER FUNC 2");
}

void loop() {
  // i2c.beginTransmission(DS2482_ADDR);
  // i2c.write(0xA5);
  // i2c.write(0x55);
  // if (i2c.endTransmission() == 0)
  // {
  //   Serial.println("Sending DATA SUCCESS");
  // }
  // else
  // {
  //   Serial.println("ERROR Sending DATA");
  // }
  // delay(3000);
}

void configureDS2482() {
  Serial.println("Configuring DS2482...");

  // Lecture du registre de configuration actuel
  uint8_t configValue = DS2482_CONFIG_APU; // Exemple de valeur pour configurer l'APU

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_CONFIG);
  i2c.write(configValue | (~configValue << 4));  // Écrire le registre de configuration
  if (i2c.endTransmission() == 0) {
    Serial.println("Configuration APU OK");
  } else {
    Serial.println("Error configuring APU");
  }
}


/*******************************************************/
/*******************************************************/
/* FUNCTION FOR COMMUNICATION BETWEEN NUCLEO AND D2482 */
/*******************************************************/
/*******************************************************/

void resetDS2482() {
  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_RESET);
  if (i2c.endTransmission() == 0) {
    Serial.println("DS2482 réinitialisé avec succès.");
  } else {
    Serial.println("Échec de la réinitialisation du DS2482.");
  }
}

void writeConfigDS2482(uint8_t config) {
  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_CONFIG);
  i2c.write(config | (~config << 4)); // Config value and its complement
  if (i2c.endTransmission() == 0) {
    Serial.println("Configuration du DS2482 écrite avec succès.");
  } else {
    Serial.println("Échec de l'écriture de la configuration du DS2482.");
  }
}

uint8_t readStatusDS2482() {
  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_SET_READ_PTR);
  //i2c.write(DS2482_CMD_STATUS);  // Status register
  if (i2c.endTransmission() != 0) {
    Serial.println("Erreur de transmission lors de la lecture du statut.");
    return 0xFF; // Erreur de transmission
  }

  i2c.requestFrom(DS2482_ADDR, 1);
  if (i2c.available()) {
    return i2c.read();
  }

  Serial.println("Erreur de lecture du statut.");
  return 0xFF; // Erreur de lecture
}

void selectChannelOW0() {
  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_CHANNEL_SELECT);
  i2c.write(DS2482_CHANNEL_OW0);
  if (i2c.endTransmission() == 0) {
    Serial.println("Canal OW0 sélectionné avec succès.");
  } else {
    Serial.println("Échec de la sélection du canal OW0.");
  }
}

bool resetOneWireBus()
{
  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_1WIRE_RESET);
  if (i2c.endTransmission() != 0)
  {
    Serial.println("Erreur lors de la réinitialisation du bus OneWire.");
    return false;
  }

  // Attendre la fin de l'opération
  delay(10); // Augmentez le délai si nécessaire pour des périphériques OneWire spécifiques

  uint8_t status = readStatusDS2482();
  if (status & 0x01)
  {
    Serial.println("Aucun périphérique OneWire détecté.");
    return false;
  }

  Serial.println("Réinitialisation du bus OneWire réussie.");
  return true;
}

void select_DS28E17() {
  Serial.println("START OF SELECT FUNCTION");

  uint8_t data[] = {0x55, 0x19, 0x56, 0xCA, 0x04, 0x00, 0x00, 0x00, 0x3A};

  for (int i = 0; i < sizeof(data); i++) {
    i2c.beginTransmission(DS2482_ADDR);
    i2c.write(DS2482_CMD_WRITE_1WIRE);
    i2c.write(data[i]);

    if (i2c.endTransmission() == 0) {
      Serial.print("DATA 0X");
      Serial.print(data[i], HEX);
      Serial.println(" OK");
    } else {
      Serial.print("Error DATA 0X");
      Serial.println(data[i], HEX);
    }

    delay(10);
  }

  Serial.println("END OF SELECT FUNCTION");
}

void test_writing_function(){

  select_DS28E17();
  
  Serial.println("DEB WRITING FUNCTION");

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_1WIRE);
  i2c.write(0xD2);

  if (i2c.endTransmission() == 0) {
    Serial.println("DATA 0xD2 OK");
  } else {
    Serial.println("Error DATA 0xD2");
  }

  delay(1);

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(DS2482_CMD_WRITE_1WIRE);
  i2c.write(0x00);

  if (i2c.endTransmission() == 0) {
    Serial.println("DATA 0x00 OK");
  } else {
    Serial.println("Error DATA 0x00");
  }

  Serial.println("END WRITING FUNCTION");
}

void test_reading_function(){
  uint8_t read_command = 0xE1;
  uint8_t config_value;

  select_DS28E17();

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(0xA5);
  i2c.write(read_command);

  if (i2c.endTransmission() == 0)
  {
    Serial.println("DATA 0xE1 0xE1 OK");
  } else {
    Serial.println("Error DATA 0xE1 0xE1");
  }

  delay(10);

  i2c.beginTransmission(DS2482_ADDR);
  i2c.write(0x96);

  if (i2c.endTransmission() == 0)
  {
    Serial.println("DATA 0x96 OK");
  } else {
    Serial.println("Error DATA 0x96");
  }

      delay(10);

  i2c.requestFrom(DS2482_ADDR, 1);  // Lire un octet depuis le DS2482

  if (i2c.available()) {
    uint8_t config_value = i2c.read();
    Serial.print("Current configuration value: 0x");
    Serial.println(config_value, HEX);
  } else {
    Serial.println("Error reading configuration value");
  }

  // // Read the configuration value
  // config_value = i2c.read();

  // Serial.print("Current configuration value: 0x");
  // Serial.println(config_value, HEX);

  
}

Thank you for trying to help me

Usually it's best to just go with what works instead of wasting lots of time on something that nags at you, but doesn't contribute much to your project goals. In this case, I'd just settle for a OneWire sensor suite with no interfacing whatsoever. Much simpler and very effective. The total cost isn't necessarily any higher than the combined cost of the interface modules you're using now (especially if you're using the relatively expensive MikroE boards). If you factor in the cost in hours of getting this I2C-OneWire-I2C contraption to work, you'll be far cheaper off using just a slightly more expensive sensor that doesn't require any interfacing.

Frankly, I find it hard to figure out a reasonable use case, especially in your setup, for this approach. If you're bent on getting it to work, I'd start by hooking up a scope and a logic analyzer to the OneWire bus and monitor what's happening there. Start with the scope to see if the signal quality is decent. If so, proceed with the logic analyzer to work out what data is being sent over the bus. The OneWire protocol definition is open/accessible so you can read up on how a transfer is supposed to look.

In the past I've messed with OneWire, specifically to make a OneWire slave device (implemented as an ATTiny85) that would play nice with other off-the-shelf OneWire devices. Interesting project, spent a lot of time figuring it out, net useful result virtually zero (yes, I did get it to work - it just wasn't a very useful solution). We all learn the hard way sometimes.

1 Like

I take note of everything you said.
I agree with you that using only the 1-wire module is the best option: better mastery of the software, simpler hardware, etc.
I posted this post in order to find someone who had already made this application because there is no application on the web that looks like mine.
We will talk about it internally about this project and make the right decision.

Thank you again for your help and wish you good luck.

1 Like