I²C address with raspberry Pi Zero


I´m having the repeater and analogue card from Horter&Kalb, just for starting with I²C.
I need the analogue output as setpoint 0-10V.
Everything is running on a Pi Zero

When I´m using "i2cdetect -y 1" in the table is shown 0x48 (72dez).
But the output card has 144dez (0x90).
If I´m disconnecting the analogue card he´s still finding 0x48, so it´s the repeater,

But how can I use the address 0x90?
The scan node only finds 0x48.

When I´m using I²C-In with command 4 and 4 bytes the output is always different.

The card seems to connected right, because between SDA and SCL to GND is 5V, also on the power input.

Thanks and kind regards, Thorsten

Are you sure ? It is quite rare to find devices with I2C addresses above 0x77. This is the reason the i2cdetect command from I2Ctools package will display only addresses from 0x03 to 0x77.

You probably know that Raspberry Pi does not tolerate 5 Volts in their GPIO pins. I assume therefore that this repeater is some kind of voltage level converter.

If above assumption is correct it makes no sense that a level converter would have an I2C address.

Now, if this "repeater" is more than a simple level shifter then the manual has to describe its functionalities, addresses, internal registers, etc. What exactly you wanted to read/write on the address 0x90 ?


Actually the analogue inputs are working.
The fault were the jumpers for voltage level.
Now 5V is 128 and 10V is 255.

But the analogue output is making me a headache, because it´s always 10,7V.
I´m sending the command 68 and Byte1. Setpoint is changing manually, payload is the same.
But I´m measuring the output and it´s always 10,7V

Looking at the datasheet the i2c address should somewhere between 0XB0 and 0xDE.
How did you set the address jumpers?

The jumper is set to 144 (0x90), but he will find the card on 72 (0x48).

I´ve measured at PCF8591 Aout and it´s always 1,78V.
So maybe command or byte is not correct.

Just a Tip:
If you have 'i2c' global modul installed to node-red, you can use this to list all device addresses on the right debug panel:

[{"id":"b75bc00a.bf1db8","type":"group","z":"34aad6f7.b85c6a","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["ddbdc4be.f2f5b8","c4cdd96b.8ccbf","87286abf.36c54"],"x":44,"y":299,"w":542,"h":82},{"id":"ddbdc4be.f2f5b8","type":"function","z":"34aad6f7.b85c6a","g":"b75bc00a.bf1db8","name":"I2C-11 bus addr scan","func":"'use strict';\n\n// When run, this program will output the same information as the\n// command 'i2cdetect -y -r 1'\nvar   fs = '-'; // = global.get('fs');\nconst i2c = global.get('i2c');\nconst i2c1 = i2c.openSync(1);\n\nconst EBUSY = 16; /* Device or resource busy */\n\nconst scan = (first, last) => {\n  fs = '     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f';\n\n  for (let addr = 0; addr <= 127; addr += 1) {\n    if (addr % 16 === 0) {\n      fs += '\\n' + (addr === 0 ? '0' : '');\n      fs += addr.toString(16) + ':';\n    }\n\n    if (addr < first || addr > last) {\n      fs += '   ';\n    } else {\n      try {\n        i2c1.receiveByteSync(addr);\n        fs += ' ' + addr.toString(16); // device found, print addr\n      } catch (e) {\n        if (e.errno === EBUSY) {\n          fs += ' UU';\n        } else {\n          fs += ' --';\n        }\n      }\n    }\n  }\n\n  fs += '\\n';\n};\n\nscan(0x3, 0x77);\ni2c1.closeSync();\n\nconsole.log(fs);\nmsg.payload = fs;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":320,"y":340,"wires":[["c4cdd96b.8ccbf"]]},{"id":"c4cdd96b.8ccbf","type":"debug","z":"34aad6f7.b85c6a","g":"b75bc00a.bf1db8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":490,"y":340,"wires":[]},{"id":"87286abf.36c54","type":"inject","z":"34aad6f7.b85c6a","g":"b75bc00a.bf1db8","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":140,"y":340,"wires":[["ddbdc4be.f2f5b8"]]}]


I´ve connected the analogue output, who´s giving alway ~10V to analogue input 1, who´s showing the voltage.
But the setpoint is 1 volt !

Knowing that your device uses the PCF8591 makes easier to understand the issue.

This article explain how the address 0x90 gets translated to 0x48 and how to control and communicate with the device.

If I understand it correctly:

To control the DAC we need to send two bytes of data. The first is the control byte, which simply activates the DAC and is 1000000 (or 0x40) and the next byte is the value between 0 and 255 (the output level)

Command 68 with 1 Byte is not enought ???

Not enough or wrong argument.

I normally handle I2C using the i2c-bus npm module, so I don´t know how to configure the contrib node you are using. You should try something equivalent to : bus.write_byte_data(0x48, 0x40, value), where 0x40 is the internal register. I don´t know from where you get command 0x68. Perhaps you could try 64 (0x40) instead of 68 ?

If I´m using the terminal
i2cset -y 1 0x48 0x40 100
nothing´s happening.

It is better that you stick with the i2c contrib node (which probably uses the npm library i2c-bus under the hood). Using the library directly would only add an additional complexity.

I had a look at the datasheet and understood that the auto increment flag would only have effect for the analog input, so 64 (0x40) should not be different from 68 (0x44) as for the analog output.

I was expecting that writing different values to register 0x40 would result in different voltages readings on the output pin. I am clueless why it is not working.

Ok, I´ve tried a little bit and found out, that the node is the fault.

I´m sending every 2 seconds a value and having the setpoint only for the writing cycle.
After that the voltage jumps back to 10,7V.

And it´s interesting, that I can set only a maximum value of 127, but should be 255.

When I´m writing
i2cset -y 1 0x48 0x40 255
it´s working and the voltage ist 10V, with 128 it´s 5V.

1 Like

It is unlikely that the node has some bug as it is used extensively. Anyway I had a look in github for node-red-contrib-i2c and found something that may deserve an investigation. Apparently the node is using the node.js buffer statement writeIntLE with an extra parameter. This extra parameter was used until node.js version 8 but is no longer required in newer versions. I will test later on to understand if this line in the code might be generating any issue.


In fact the extra parameter in writeIntLE is not an issue at all.

I wonder if the problem you faced was caused by the slider node. If configured like below it will generate quite a lot of outputs which may be too fast for the hardware.


with inject or direct entry in the node it´s the same fault

Here you can see the fault

Ok, I got it working.
By using PCF8591 the command for sending (i2c out) is 64, for reading (i2c in) 68.

1 Like