16CH Isolated I/O shield

Greetings,

I'm toying with the idea of creating a 14CH I/O shield intended for controlling larger components up to a few amps and at a variety of voltages. I'm trying to mimic something like an industrial PLC in robustness, configurability and connection philosophy. The goal is to have something that can be used to control larger scale equipment whether it's automotive, small scale process (home breweries and such), light shows whatever have you. Clearly this many channels would probably not fit on a single shield - so most likely it would be set up to connect to a break out board which could be mounted inside of an enclosure and onto a variety of loads, relays, etc. There are many similar boards already in existence, but they all seem limited from what I've found - most commonly a low number of output channels and no I/O reconfiguration option; they seem to just not really be suitable for other than benchtop, small robotic work or simple control systems (few channels)

In order to be flexible in application I'd like to set up each channel to be jumper selectable as either an input or an output. This I/O could operate at a variety of voltages, allowing a load of up to 60V on each output at a few amps, and provides a 12V common for connecting switches and logic to the input side of the board - because there's no telling what could be connected to the other side I want the load & input side of the system to be fully isolated from the control layer of the board, effectively there will be two power connectors given (one for the Arduino & controls and another for the loads and input sensing), with the option to bridge the two together if full isolation is not a concern.

I've tinkered with electronics a good bit ever since I was little - but this is my first time ever really designing something from scratch; I'm posting up an image of one of these channels I'm proposing hoping to get some good design feedback. I intend to post everything I learn about the project online as I develop it. I intend to make a couple boards of this for my own use - is this something that anyone foresees there to be enough of a demand for for me to have a few extra boards punched out and try and sell just the PCB for a small profit? Does something like it already exist in a nicely packaged format?

Here's a run-down of the circuit

JP1 would be connected to one of the Arduino D pins, and can be jumpered to 1 (input) or 3 (output). Removing the jumper will disable the pin and free it up for use with other shields.

First off; +5V and GND are isolated power inputs for the Arduino and other delicate components - I'll call this "clean power", V+ (12V) and GND1 are connected to a power connector for controlled loads and off-board inputs, I'll call this "dirty power". Again if the user does not see the need for full power supply isolation, GND and GND1 may be jumpered, and V+ (12V) may be jumpered to the Arduino's VIN pin.

If pin 1 is jumped to 2 (input mode):

X1-2 becomes an input sunk to ground, an incoming control would share a common ground with the input side of the optocoupler and be powered the 12V V+ leg on the dirty power connector (some on-board terminals for a common connection will be provided). R4 is intended to draw current at an acceptable level for the LTV816 input side. If X1-2 is high, current flows from the +5V leg "clean power" source, through pull up-resistor R3 and into JP1 onwards to the Arduino. If X1-2 is low, this flow stops and R6 serves as a pull-down to prevent a floating logic condition. R2 and LED1 serve as a visual indicator of the process.

If pin 3 is jumped to 2 (output mode):

Power flows from the Arduino D pin through R7 which is set an allowable current and voltage drop to control OK2's input side and power visual indicator LED2. If the output on OK2 is activated, power is tapped from the board's 12V V+ "dirty power" leg, flows through pull-up resistor R1, through OK2's transistor and into MOSFET Q2 (an IRFZ44??). This will activate the MOSFET and current is allowed to flow from X1-1 to GND1; the other side of X1-1 may be connected to 12V V+ dirty power, or any power source up to 60V with a ground tied to dirty GND1.

I fear this post has gotten a bit longer than I had hoped, but that's all I have for now - please let me know of any comments or suggestions you may have.

Thanks!

Repost circuit - only part of it is showing. Can I also suggest that black on white is easier to see rather than red on black

second the above comments. cct is pretty illegible and I don't want to have to readjust my screen every time I need to look at a cct.

This idea is not bad as an outline. It would be good to multiplex the Arduino's 6 ADC ports with something like 74HC4051

You may need consider whether low side switching is suitable for all applications you are targeting.

Thanks and sorry about that - I've updated the image on the first post.

I like the idea of the multiplexer, creating the ability of either more channels or taking up fewer of the Arduino's; am I right in that multiplexing is taking a few inputs and turning them into many outputs, and that demultiplexing is reading those many outputs and turning them into inputs for the arduino (effectively the devices works bidirectionally). To me this would be important in order to maintain the board as an input and output.

Look up the datasheet for the chip reference I gave.

What I was suggesting is taking , for example, one GPIO line of arduino and using it as an output to select either of two groups of external signal sources onto the first four arduino ADC inputs.

This gives you 8 ADC channels while only taking 4 of those on the arduino (hence only four input lines).

Alright that's starting to make sense.

Attached is what I have so far on that concept - the multiplexer will pass from it's Z to the Arduino's D5 (PWM), the multiplexer's channel is selected by D2-D4 which are tied to S0-S3. A5 is used as a GPIO to choose a multiplexer; when it's low IC1's enable pin is grounded enabling the unit, when it's high, IC1's E is set o high disabling it, and IC2's VEE is fed enabling that unit. Is this anywhere along the right track?

Thanks

I don't know much about them, but I would suspect you may want to investigate hooking each of the channels up to a serial bus such as i2c or spi. You would presumably need a tiny digital control on the end to act as the control for i2c or spi, but it would allow you to easily add more stations. I believe i2c is limited to 112 devices and uses 2 wires on the Arduino, and spi has a byte address which would give 255 devices and uses 4 wires.

There are some errors in hardware design:

Q2 - most likely conducting all the time , doesn't matter what digital outputs state;
LED2 - never lights up;
Logical Input is "undefined" with voltage around 2.4V corresponding to logical "1".

Trying to extend project ( up to 255 ) w/o fixing bugs in just one channel does not make any sense.

Magician:
There are some errors in hardware design:

Q2 - most likely conducting all the time , doesn't matter what digital outputs state;
LED2 - never lights up;
Logical Input is "undefined" with voltage around 2.4V corresponding to logical "1".

Trying to extend project ( up to 255 ) w/o fixing bugs in just one channel does not make any sense.

Would you mind describing why Q2 would always be on? Does LED2 not light up because of a lack of voltage? Not sure if I understand your logical voltage comment.

The reason I'm posting this is to get advice on the bugs and overall good practices; none of these channels have been tested yet (parts in the mail)

Thanks.

O'K,
Q2 - is a MOSFET, which control by Voltage (not current). Optocoupler's BJT has "collector dark current" parameter, which means it's conducting even there is no current via couplers LED diode flows. To "fix" this, you need a resistor across gate-source or gate-ground of the MOSFET. 10 k , or better check specification of optocoupler's "collector dark current" and pick a resistor which creates a voltage less than MOSFET's threshold.
R <= V(threshold) / I(dark).

LED2 - assuming regular 5 mm green led requires at least 2.2V to lights up, which is more than "drop-off" forward voltage for specified optocoupler , ~ 1.25V.

Logical Input - has "complex" voltage divider, consisting 1k and 220 oHm resistors, plus BJT and LED in series. I didn' calculate precisely what voltage this divider outputs, probably around 2-3 volts.

Magician:
O'K,
Q2 - is a MOSFET, which control by Voltage (not current). Optocoupler's BJT has "collector dark current" parameter, which means it's conducting even there is no current via couplers LED diode flows. To "fix" this, you need a resistor across gate-source or gate-ground of the MOSFET. 10 k , or better check specification of optocoupler's "collector dark current" and pick a resistor which creates a voltage less than MOSFET's threshold.
R <= V(threshold) / I(dark).

LED2 - assuming regular 5 mm green led requires at least 2.2V to lights up, which is more than "drop-off" forward voltage for specified optocoupler , ~ 1.25V.

Logical Input - has "complex" voltage divider, consisting 1k and 220 oHm resistors, plus BJT and LED in series. I didn' calculate precisely what voltage this divider outputs, probably around 2-3 volts.

Thanks, that helps. I've attached a revised circuit.

Upon inspecting the IRFZ44 datasheet it states that the gate-source leakage at 20V is about 100nA; does this mean that R1 is not required or will its absence cause a short circuit condition when OK2 is high? LTV816 has a dark current of 100nA, IRFZ44 has a minimum gate-source threshold of 2V which by my calc puts R5 at 20K - does this make sense?

Update: On the OK1 side of things I'm still trying to come up with a way to address the voltage divider issue; stay tuned on that one.
I've attached an updated diagram, does moving R9 after R2 eliminate the divider issue?

, does moving R9 after R2 eliminate the divider issue?

Not quite, current transfer ratio for OK1 is about 50%, LED1 is loading output, which means output voltage would greatly depends on input OK1 current. Why not transfer LED1 in series with input OK1 LED? The same with LED2, connecting in series with OK2 LED, you will reduce current demand from arduino output. Adjustment in R4 and R7 would be necessary, R6 - removed.
I would leave R1 as it is, for different purpose - limit current via optocouplers BJT. MOSFET has high input capacitance, and best of all to use special MOSFET drivers, or at least additional BJT to drive gate. W/o driver, it would be impossible to solve different issues: max optocoupler output current, and time to switch on / off MOSFET, which should be as fast as possible. R5 = 2 / 10^-7 = 20 MOHM, just to fix "dark current", but there is more , it helps to improve switch off time, and has to be as low as possible, 10 - 20 k looks acceptable.

Magician:
Why not transfer LED1 in series with input OK1 LED? The same with LED2, connecting in series with OK2 LED, you will reduce current demand from arduino output. Adjustment in R4 and R7 would be necessary, R6 - removed.

That's doable; R7=(5V-1.3V)/0.02=185Ohms, but how would one size the resistor for LED1 if it was connected in series to pin 1 on OK1? OK1's LED runs at 1.3V (1.2-1.4) and your average LED runs at 2.2V, If the input source is 12V, do I just size for the cumulative voltage for the two LEDs eg. R4=(12V-[1.3+2.2V])/20mA=425 ohms?

Also by eliminating R6 are you saying a pull-down resistor is not needed? How do you fight floating logic problems?

If the input source is 12V, do I just size for the cumulative voltage for the two LEDs eg. R4=(12V-[1.3+2.2V])/20mA=425 ohms?

Yes. And remove R2. Same with R7 = 5V - 1.3 - 2.2 / 0.02 = 75

Also by eliminating R6 are you saying a pull-down resistor is not needed? How do you fight floating logic problems?

This problem only concern for inputs, not outputs.

Bear in mind that MUXs cannot normally be used for outputs because they are not latched.

Also using them for analog input defeats the purpose of the board because they won't be isolated. If you want isolated analog inputs you'll have to work a bit harder :slight_smile:


Rob

Magician:
Yes. And remove R2. Same with R7 = 5V - 1.3 - 2.2 / 0.02 = 75

Alright - I've rearranged the resistors some more; lets see if this makes sense

Magician:
This problem only concern for inputs, not outputs.

Right but isn't OK1 (tied to R6) used with the channel set to "input" mode? Thus the corresponding pin tied to that channel on the Arduino would be set as an input and read; I've moved R6 around as well - let me know if you still think it can be removed. Thanks again for all your help - I know a lot of this probably seems somewhat remedial but I really appreciate it.

Graynomad:
Bear in mind that MUXs cannot normally be used for outputs because they are not latched.

Also using them for analog input defeats the purpose of the board because they won't be isolated. If you want isolated analog inputs you'll have to work a bit harder :slight_smile:

Good point - I'd have to add some external components to do the latching which would add more complexity than I think is necessary. I really like MichaelMeissner's idea posted up earlier about using I2C or SPI for the interface; this would free up a lot of pins on the arduino - I'll start investigating going that route (using an I2C or SPI GPIO expander) instead of the MUX's. I'm not quiet doing an Analog input side yet - but I may start looking into that as well.

I've moved R6 around as well - let me know if you still think it can be removed.

I say R2, not R6. I think, R6 and R9 better to leave as they were in previous version. Now they form a divider.

Magician:

I've moved R6 around as well - let me know if you still think it can be removed.

I say R2, not R6. I think, R6 and R9 better to leave as they were in previous version. Now they form a divider.

Yup you're right - how's this?

I think I found an IO expander that will do the trick; an MCP24016 http://ww1.microchip.com/downloads/en/DeviceDoc/20090C.pdf.

This simplifies the connection the the Arduino substantially, occupying only pins A5 and A4. The other bonus is with I2C (and SPI) in that you can adress multiple of these together. Given the cost of this IC is only a couple of bucks I may eliminate the jumper feature of each channel, provide two MCP24016s on board; one to handle the inputs and one to handle the outputs.

You probably should have pullup resistors on SDA and SCL (~4k7), you can use the internal ones but they are too high a value really.

Also I can't see any mention of internal resistors on the 23016s so I would assume they also need pull down resisters on the address lines.

Given that that's a total of 8 resistors I'd use a DIP resistor array and probably swap the address switches so they pull low, that way you can use a smaller 9-pin SIL pack for the resistors.


Rob