Arduino Wire IIC

Hi,

I have a IIC device with an address for read, 0xDD and an address for write, 0xDC. The address is marked as 7bits, which means the lowest bit is for marking reading/writing. So, the 7bits address of the device should be 0x6E.

To read the device data, I need to write 0xDD, 0x03 to the device. like this:

My code is here:

The .h file:

#ifndef BATTERY_PACK_H
#define BATTERY_PACK_H


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

#define BP_ADDRESS  0x6E // 
#define BP_REG      0x03


//=========================================================================
// Parameter structures
//=========================================================================

typedef struct
{   
    uint8_t  BMS_addr;
    uint8_t  REG_addr;
    uint16_t voltage;
    uint16_t current;
    uint16_t capacity;
    uint16_t state;
    uint8_t  version;
    uint8_t  SOC;
    uint8_t  FET;
    uint8_t  battery_serial;
    uint8_t  max_temp;
} Battery_state;



class Battery_pack {
    private:
     

    public:
     void read_BP_state(Battery_state *data);
};
#endif /* BATTERY_PACK_H */

The .cpp file:

#include "battery_pack.h"
void Battery_pack:: read_BP_state(Battery_state *data){
    Wire.beginTransmission(BP_ADDRESS); // I2C 0, for GIGA, it's Pin 20 (SDA), Pin 21 (SCL)
	Wire.write(BP_REG);
    Wire.endTransmission();

    Wire.requestFrom(BP_ADDRESS,15);
    if (Wire.available()) {
        Serial.println("Data received");
        // Read and assign values to Battery_state struct
        data->BMS_addr  = Wire.read();
        Serial.println(data->BMS_addr, HEX);
        data->REG_addr  = Wire.read();
        data->voltage = Wire.read() << 8 | Wire.read();
        data->current = Wire.read() << 8 | Wire.read();
        data->capacity = Wire.read() << 8 | Wire.read();
        data->state = Wire.read() << 8 | Wire.read();
        data->version = Wire.read();
        data->SOC = Wire.read();
        data->FET = Wire.read();
        data->battery_serial = Wire.read();
        data->max_temp = Wire.read();
    } 
}

I also tried this .ccp file:

#include "battery_pack.h"

void Battery_pack:: read_BP_state(Battery_state *data){
    Wire.beginTransmission(BP_ADDRESS); // I2C 0, for GIGA, it's Pin 20 (SDA), Pin 21 (SCL)
	Wire.write(BP_REG);
    Wire.requestFrom(BP_ADDRESS,15);
    if (Wire.available()) {
        Serial.println("Data received");
    // Read and assign values to Battery_state struct
        data->BMS_addr  = Wire.read();
        Serial.println(data->BMS_addr, HEX);
        data->REG_addr  = Wire.read();
        data->voltage = Wire.read() << 8 | Wire.read();
        data->current = Wire.read() << 8 | Wire.read();
        data->capacity = Wire.read() << 8 | Wire.read();
        data->state = Wire.read() << 8 | Wire.read();
        data->version = Wire.read();
        data->SOC = Wire.read();
        data->FET = Wire.read();
        data->battery_serial = Wire.read();
        data->max_temp = Wire.read();
    }
    Wire.endTransmission();
}

The main code is here:

#include <battery_pack.h>

Battery_pack battery;

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  
  Wire.begin();
}


void loop() {
  Battery_state data;
  battery.read_BP_state(&data);
}

The problem is, the IIC read nothing from the device. I am not sure what happened.

If you have any advice? Thanks very much!

Can you post details of the I2C device you're trying to communicate with, as well as a schematic diagram of your setup and some good photos that show how everything is wired up?

Your logic analyzer output suggests that there's no ACK returning after each byte, which can mean anything from trying to communicate with the wrong address to a hardware/wiring fault.

Hi @rsmls:
Thanks for your reply. The device is customized battery pack. There is no too much detailed information. The master needs to send 0xDD, 0x03 to the slave and the device will return 0xDC 0x03 with 13 bytes data. The wiring is quite sample. GND to GND, SCL to SCL and SDA to SDA. I am using arduino giga and the IIC 0 with internal pull-up resistors.

Try adding 3k3 on SCL and SDA.

Can you post a photo of the setup?
Is the battery pack controller self-powered? Have you determined that the chip you're talking to is in fact powered?


Here is a photo. The battery pakc is self-powered. Not sure what's chip inside.

Has this unit been repaired after a major malfunction?
Are you sure it actually works?

This is the one you're talking to:
image
It's undoubtedly a microcontroller running some custom firmware made by/for the battery pack manufacturer.

Does the device show up when you perform an I2C bus scan?

Execute the following simple sketch to check the rpesence of your Slave device -- the sensor.

#define slaveAddress 0b1101110   //0x6E

#include<Wire.h>

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

void loop()
{
      Wire.beginTransmission(slaveAddress);
      byte busStatus = Wire.endTransmission();
      if(busStatus != 0)
      {
          Serial.println("Slve is not present.");
          while(true);   //wait for ever
      }
      Serial.println("Slave is present.");
}

void loop()
{
     //insert your codes
}

I think it‘s logo has been erased by the manufacturer. I ran the IIC scan program, showing no device is detected. The the range of scan is from 0 to 127. Not sure if the address should be 0xDD or 0xDC which are out of this range.

Thanks very much. No device is detected. :rofl:

Have you tried the I2C scanner example to see if any address responds?

Never mind, I see that you did.

0x6E is within this range. You could modify the I2C scan sketch to scan up to 255 if you want; any present device should respond twice: once on its read and once on its write address.

That's possible.
Also given the repairs done on the unit, it's a gamble. It looks to me like the high side switch FETs blew and took their driver with it, and who knows what other damage may have occurred to the logic on that board.

Thanks very much.

Still can't fine any device

Using DVM in tone mode, check the continuity of every jumper wire that you are using in your setup. Find faulty wire; esle, suspect your target device.

The wiring is okay. I think the chip for IIC is not working.

I would not have expected it to. It should have responded on 0x6E if that's its native read address.

Did you try the additional pullups that I mentioned? Sorry if I missed it.

It's certainly possible.

I'd be tempted to hook up an UART to the unpopulated header here and power up the board, see if any output is generated:
image
The two circled pins are likely TX and RX. Which is which...you'll have to figure that out. I'd expect RX to be pulled up to Vcc.
However, it's very well possible that no UART output is generated even if the chip works just fine. If it does produce readable output, it's certainly a sign that something is alive on that board.

This is unusual. Most I2C devices only have one address.

Have you tried the I2C scanner to see what addresses are active on your device?

That is only one address. The LSB is Read / Write-bar.

1 Like

Yes, I tried 4.7k pullups. But doesn't work.

A little bit complicated for me. I have contacted the manufacturer for help. I appreciate your help!

1 Like

Yes, I tried. But cannot fine any device.