Reading from Slave device using wire library

Hello, I am trying to use the arduino wire library to change some register values of an inductive position sensor that I designed. I'm having trouble writing to specific registers that by referencing the datasheet I should be able to write to. Im using the LDC3114-q1 IC from T.I. There are 4 sensor control register which I call SCR_x that I am trying to change values in to test different sensor frequencies. The code below shows how I am trying to write the new value into one of them to test.

#include <Wire.h>
uint8_t IC_address = 0x2A;
uint8_t SCR_0 = 0x20;
uint8_t SCR_1 = 0x22;
uint8_t SCR_2 = 0x24;
uint8_t SCR_3 = 0x26;


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

}

void loop() {
  Wire.beginTransmission(IC_address); // Address of the device
  Wire.write(SCR_0); // Register address (0x20)
  Wire.write(68); // Byte value to write (68)
  Wire.endTransmission();
  
  Wire.beginTransmission(IC_address);
  Wire.write(0x20);
  Wire.requestFrom(IC_address,1);
  byte sensor0 = Wire.read();
  Serial.println(sensor0);
  Wire.endTransmission(); 
   
  Serial.print("SCR reg val ");
  Test(SCR_0);
  Serial.print("status reg val ");
  Test(0x00);
  delay(1000);
}

void Test(uint8_t Reg) {
  Wire.beginTransmission(IC_address);    // Get the slave's attention, tell it we're sending a command byte
  Wire.write(Reg);                               //  The command byte, sets pointer to register with desired address
  Wire.requestFrom(IC_address,1);          // Tell slave we need to read 1byte from the current register
  byte slaveByte1 = Wire.read();        // read that byte into 'slaveByte1' variable
  Wire.endTransmission();                  // "Hang up the line" so others can use it (can have multiple slaves & masters connected)
  Serial.println(slaveByte1);

I believe the problem may lie in the way I am reading the bits back out of the register. The device is acting as a slave device with the address 0x2A which I assigned to IC_address. It seems as though when I read the data back out it doesn't read from the SCR_x registers but from something else that I can't understand. Oddly enough it always seems to read out a value that matches the status register, making me think the register pointer is being reset to 0x00 when I try to read.

I am using the adafruit feather M0 but I dont believe the arduino I'm using has any relation to the problem.

The sensor runs at 1.8V. That means that it also has a 1.8V I2C bus. [EDIT] The chip is designed to be compatible with a 3.3V I2C bus.
Do you have that sensor on a module ? Can you give links to the parts that you use and photos and a schematic of your project ?

The I2C bus can either write or read data. You should use the Wire library to either write or read. I have written an alternative explanation of the functions of the Wire library.

So it is either one of these:

  • Write data: Wire.beginTransmission() - Wire.write() - Wire.endTransmission().
  • Read data: Wire.requestFrom(). It may be followed by Wire.available() and/or Wire.read().

The Wire.beginTransmission() does not start the I2C session and the Wire.endTransmission() may not be used to stop something.

I think you need to call Wire.endTransmission() before you call Wire.requestFrom().

You don't need to call Wire.endTransmission() after Wire.read().

Heres, the schematic. So what you are saying Is I need to change the voltage levels on the I2c lines (scl and sda) to 1.8V ? I have a regulator to drop the voltage to 1.8 but the recommendations in the datasheet instructed the lines to be wired at 3.3v.

Yes, you are right. I see it in the datasheet now. They made the SDA and SCL and INTB pin compatible with a 3.3V processor.

The problem still persists where when I run the program the value inside of the register is the same as what it is when it is reset which is 4. It should be 68 I would think as that is the value I just wrote to it. I still think there may be an issue with how I am writing to the register.

The alternative explanation is very helpful and clear, but I want to make sure I'm thinking correctly. I start by beginning a transmission to the slave address (0x2A). When using the write command my first write is the address of the register I want to write too (0x20), and the second one, 68, is the decimal value that I want to write into that register. Then I end the transmission. I request 1 byte from the slave address (not the register I want to read from, but the address of the salve in general. this is 0x2A). I then make a variable that will be given the value of the byte that is read. Is this the correct train of thought? I still get the incorrect value for the variable. I think it is the correct register that I am reading from as the value is "4" which is the value on reset for the register.

Perform simple read/write operation and see if you are reading back what you have written into a particular register. Simply, run the following sketch and check that the Serial Monitor shows 68 at 1-sec interval.

#include <Wire.h>
uint8_t IC_address = 0x2A;
uint8_t SCR_0 = 0x20;

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

void loop() 
{
  Wire.beginTransmission(IC_address); // Address of the device
  Wire.write(SCR_0); // Register address (0x20)
  Wire.write(68); // Byte value to write (68)
  Wire.endTransmission();
  
  Wire.beginTransmission(IC_address);
  Wire.write(SCR_0);
  Wire.endTransmission();
  
  Wire.requestFrom(IC_address,1);
  byte sensor0 = Wire.read();
  Serial.println(sensor0);
  delay(1000);
}

The serial monitor shows 4, the default reset value of the register. Maybe I am unable to write to this register? the datasheet says I should be able too.

You may read the following excerpt of data sheets, implemnt the process and check if it helps:

1 Like

Thanks, I missed that.

You could read the four ID bytes and print it to the Serial Monitor as HEX values.
You might even keep that in setup() to be sure that you can communicate with the chip.
Write a single byte 0xFC to set the register address, then read 4 bytes.

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