Pullup resistors for PCA9600 buffer & MCP23008 extender

Hi All.

I need some advice with pull-up resistors when using the I2C expander (MCP23008) and extenders(PCA9600). I am a bit confused on where I need pullup resistors, where to place optional resistors and if I should use trim pots rather than normal resistors.

Background: I am currently in conceptional phase of my home automation system and have decided on using I2C for communication between multiple Master controllers and their Slaves. Due to cable lengths a I2C buffer extender PCA9600 will be used. Slaves that do not require a controller will be connected to MCP23008 expanders which give me 8 GPIOs, e.g. light switches. The MCP23008 will be powered by 5V whereas PCA9600 will probably be connected to 9V. Cables will be standard twisted pair 2x2x0.8 EIB/KNX cable running SDA, SCK, Gnd and 12-30V (with cable losses, 9V shouldn't be an issue for the buffer on the slave side). Cable length will vary up to 30ish m. Due to the number of master controllers and slaves that will be rewuired throughout the house, I will be making custom assembled PCB boards.

Now my issue are the pullup resistors.

  1. Master controller (See image 1, section 5). I know that pullup resistors will be required before and after the PCA9600 buffer. However, the values seem to differ depending on cable length.
    Q1: Am I correct that the resistor value (R1, R2) )between Arduino and PCA9600 is always constant and only the resistors (R3, R4) on the cable side vary?
    Q2: With varying cable lengths, should one rather use a tripot instead of normal resistors with a fix value for R3 & R4? If so, what range would be best suitable?
    Q3: Is a higher voltage of 9V for PCA9600 an advantage or should I stick to the 5V as in all the examples in the datasheet? I know that P82B715 would be less prone to interference, but PCA9600 seems to be a bit different in many ways.

  2. Slave side (See image 2, section 3 & 4) Slave side has both PCA9600 and MCP23008.
    Q4: Based on the general datasheets on buffers, pullup resistors (R1, R2) on the buffered side are not required at the slave as they are already at the controller side. Is that correct understanding? If so, I would keep empty solder pads on the PCB should occasionally be required.
    Q4: I am unclear from the datasheets if pullup resistors (R3, R4) are required between PCA9600 and MCP23008 or if I should just leave optional solder pads here.

Image 1 - Master controler

Image 2 - Slave

Thanks
Mike

1 Like

Great job on the Schematics!
1-2. "I am a bit confused on where I need pullup resistors, where to place optional resistors and if I should use trim pots rather than normal resistors." You can use trimp pots but eventually they can get you into trouble. You should add some resistance in series with them so you do not short the bus. You need to calculate the pull up resistors for each bus, they are dependent on the rise and fall times of the signals which is in turn affected by the capacatance. I just use a scope if 3.3K does not work (starting is 4.7K).
3. Go with the higher voltage. My system was originally 24VDC and I am staying with that. I use a SEPIC converter (Buck Converter would work great as well) to drop the 24VDC to about 9V for the Vin.
4. The outputs are open collector or open drain depending on the chip. Pull up resistors are required on SCL and SDA lines. Where you have them is generally not very important. A lot of designs simply put them on one end. Several of the modules simply take a SWAG and place 10K on each board etc.
5. "using I2C for communication between multiple Master controllers and their Slaves. Due to cable lengths a I2C buffer extender PCA9600 will be used." This bus was not designed for that type of use but many people are doing it. I am in the process or rebuilding my HA system (currently has 100 outputs operating for many years). In the reconfiguration I will probably have about 10 slaves. I bit the bullet so to say and went with CAN. So far during development it is working great and very reliable at 250K. I strung wire all around just to be sure.

Thanks Gilschultz, that helped

1-2. Ok, the chosen components all support fast plus I2C. I found an online calculator today and calculated different pullup resistor values for very short to long cables at different speeds. Based on that, I need a tripot values in the range of 0.430 KOhm - 3540 kOhm. OMG

Just an idea, maybe I should connect the tripot to to the arduino/ESP pin too and have a setup routine which reads the current tripot setting and based on the cable length gives me an estimated tripot setting.... getting fancy I guess. Also could add a capacitance routine, but that means disconnecting everything to have an open circuit cable... just some thoughts.

3 Cable supply voltage will be 12v or more. The voltage regulators will support up to 40V. 12, 24, 36 volt... its a matter of cost and requirement but I have the flexibility.

4 Ok, I'll keep it simple and have the pullup via tripot on the controller side. Makes things easier to manage. But Ill keep solder pads available on the slave side just in case

I am aware that I2C bus initially wasn't made for this type of use. I was looking at the pros and cons of SPI, I2C, TTL, Ethernet, RS485, KNX and CAN bus systems. My goal is to keep costs down and have at least half-duplex communication. The issue I have with most of the options is that I need a controller at each point even for something as simple as a switch and the I2C expanders do not require this which helps my budget. I2C also allows me to mix basic I/O expanders, controller boards and I2C compatible sensors. In the loooong run I probably will switch to KNX system which too was considered,e.g. cable wiring.

I am estimating about 50 light switches, 200 RGBW lights, temerature sensors, motion sensors, door + window sensors, heater controls, Multimedia, Appliances and lots more. RGBW lights tend to use esp8266 which can connect to I2C via TX/RX pins (eliminating WiFi issues). CAN/KNX just need tooo many additional controllers/components to keep it all within the budget. Obviously I cant control all of this with 1 master controller, so I will have multiple specialized masters which function even if the network/Server/HA are down for maintenance or other issues...

Not sure if I should start a new topic, but I think this post might be a good place too as my next question is related.

Q How do I measure the rise time of a BUS using an arduino, in my case I2C?

So my schematic has now evolved to include a trimpot on the buffered bus side which has a cable length that can short or very long. Now I would like to be fancy and automate the setup of the trimpot pullup resistor... maybe... but not sure if this can work....

The circuit consist out of 3 parts.

  1. The pullup resistor. R1 is the minimum pullup resistance required and also acts as a failsafe should the trimpot fail. The trimpot adds 0-max ohm to the total pullup resistance.

  2. A voltage divider which reduces the max voltage to a Arduino acceptable voltage, connected to the trimpot. GPIOx can read the analogue voltage which will vary depending on the trimpot position. This allows the Arduino to read the pullup resistance that was set (Ohm's law).

  1. Voltage divider between the BUS line, e.g. I2C serial clock or SPI etc... GPIOy can then be used to read the voltage over time and calculate the rise time of of the BUS.

The easy part, the arduino sketch would during setup mode read the setting of the variable pullup resistor at GPIOx and calculate the resistance.

Now I am struggling with the rise time. The sketch reads the voltage on the bus at GPIOy and runs a couple of test signals. Based on the rise time, It can determine if it is suitable for the desired communication speed and instruct us to adjust the trimpot appropriately.

But, how does one measure the rise time without influencing the bus? I think my schematic with a voltage divider will want to drain the bus? Adding a transistor to between bus and voltage divider? A shunt resistor which comes with a high price tag? Hall sensor? So, how does one measure the voltage rise without influencing the bus?

Mike

By the time you get all those parts and assemble them you will have at least the cost of a MCP2515 CAN module which has the controller and driver already mounted and tested on a PCB. Add a jumper and you have termination. There are several good libraries for this board, I use cory's it has been great. CAN will give you multi master multi slave and thousands of different address all the units can communicate with. The boards take care of the communications, error checking etc. You would be limited to a maximum of 8 bytes per transmission. I am using them with 8Mhz crystals at 250k baud. There is one big gotcha with CAN you must have two nodes as somebody has to ACK a transmission. The library has a send and receive .ino modules they work just fine. You only terminate the physical ends of the bus, nothing in the middle.

In general I like CAN, but haven't found examples without having a controller at each peripheral "slave" location. So looks like I would need to combine CAN module with e.g. Arduino Nano.

I have space constraints in the wall outlets when using off the shelf modules and would need to make my own PCB assembled either way. I did a quick MCP2515 + ATMEGA328 PCB design (without USB peripherals) but the components cost is more than double that of the I2C approach, not to mention the standby current which too is higher. Multiplying the component cost + running cost by >200 units makes a big chunk in my wallet in which case standard KNX components are very competitive in cost. Having controllers at each location is also a nightmare when maintaining the firmware (ESP with OTA even more costly)

Yes, I2C is limited to fast plus 1.7MHz and the long cable will slow it down, 32 character messages which only occasionally are used, but it should be enough to a handle a hand full of switches, read sensors every couple of minutes and occasionally sending general calls to lights or other devices.

You could probably put more then one sensor and or output on each node. I set them up for 16 outputs and 8 inputs. I do not use them all but later they are there.

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