I have access to a HDL3000 PSU and it is connected to an Arduino Uno via I2C.
I found this documentation that explains how to communicate with the HDL3000 from an Arduino using I2C HDS_Series_I2C.pdf .
When I send the command "0x00" to get "Unit Manufacturer" the response is "XP Power Ltd".
But when I send the command "0x60" to get "Output Voltage Measurement" the response is empty.
The same result is for "Output Current Measurement", "Output Voltage Setting" and "Output Current Setting".
It states on page 36:
• Start bit (S_)
• Slave Address[W] – Enter the slave address of the device to communicate with.
The Write bit should be cleared to indicate a write operation.
• Word Address – Enter the word address
• Restart (RS),
• Slave Address[R] – The slave address with the Write bit set will be automatically
entered when the Slave Address[W] has been entered.
• Byte Count – Enter the number of bytes to be read
• Stop bit (P_)
That means the device measures a voltage of 0x0BFF cV = 30.71V. Does that make sense?
The second half of page 5 explains how to interpret the bytes.
You almost had it:
Wire.beginTransmission(i2cAdd);
Wire.write(0x60); // Send command
Wire.endTransmission(false);
Wire.requestFrom(i2cAdd,2);
uint16_t l = Wire.read();
uint16_t h = Wire.read();
uint16_t v = h << 8 | l;
float voltage = (float) v / 100.0;
Is that a high quality meter? According to the datasheet the output voltage has an accuracy of +/-1%, so about a half of the difference might be on the PSU side, cheap voltage meters often have an accuracy in the same range.
No, but a full sketch would be nice.
Are you talking to I2C address 0x50 ? Did you run a I2C Scanner sketch ?
I assume that multiple data bytes can be read and written, but pylon is right, it is somewhat vague.
There are two registers that are 16-bit and also Read/Write. You can do a test if you can write two bytes and read two bytes and then check with other values.
How do you get a couple of readings ? Do you reset the Arduino board ?
It might need a delay between I2C sessions.
Can you add a delay of 1ms after each I2C session ?
You could try a lower or higher clock, for example 50kHz and 200kHz
Wire.begin();
Wire.setClock(50000UL); // 50kHz as a Unsigned Long
You could test the error returned by Wire.endTransmission() and the number by Wire.requestFrom();
Wire.beginTransmission(i2cAdd);
Wire.write(0x60); // Send command
int error = Wire.endTransmission(false);
if(error != 0)
{
Serial.println("O no, communication lost with the sensor");
}
int n = Wire.requestFrom(i2cAdd,1);
if(n == 1) // same amount as requested ?
{
uint16_t l = Wire.read();
}
else
{
Serial.println("Something wrong, communication lost with the sensor");
}
How is your bus ? What are your pullup resistors ? What kind of cable or wires do you use ?
It seems that the communication is okay, the device is really returning zeros.
Result1 and 2 are the error codes and are zero, that is okay.
Result3 is the return value of Wire.requestFrom(), that is also okay since 1 byte was requested, so it should return 1.
Somehow the device gets tired of sending data.
I did not read everything, can you find example of others ?
Can you put it in the loop with a 5 second delay at the end of the loop() ?
Maybe try an other register, maybe include reading the manufacturer string, so you know that everything is working.
They say that a pullup resistors of 2k are needed.
Hello,
How did it end up ? were you able to program the power supply ? In my case, I am trying to use Rasberry Pi I2C to communicate and still no luck. I don't detect any device at all. Should the wiring be the same ?