I need to switch 128 solenoids either on or off individually, several times a second. I'd like to drive this from either a PC, or an embedded device.

How would you recommend I do this? Perhaps there is a way I can enable addressing of a group of (8 or 16) solenoids and send a turn on, or turn off command to them?

Considering what's out there, what is the easiest way to go about this? What is the best or most preferred way?

I am looking at these solenoid valves that run at about $50 each. Do share information if you know of any cheaper/better ones. The purpose is to control an indoor waterfall. It's low-pressure so all the water drips downwards.


  • \$\begingroup\$ Need to know how big the solenoids are - voltage/current. \$\endgroup\$ Commented Dec 5, 2010 at 0:35
  • \$\begingroup\$ I'm looking at these that draw 6 to 8W. If you know of a better/cheaper one that will control the release of water "droplets" do share. $50/per unit is expensive ascovalve.com/Applications/ProductSearch/… \$\endgroup\$ Commented Dec 5, 2010 at 1:45
  • \$\begingroup\$ Would a sprinkler valve work? Do you need the solenoid to use a 120V coil, or could you use a lower voltage (e.g. 6V, 12V)? \$\endgroup\$
    – W5VO
    Commented Dec 5, 2010 at 4:42
  • \$\begingroup\$ I can use a lower voltage... but a purely mechanical (non computer controlled) sprinkler valve probably won't cut it. What would determine my required voltage? \$\endgroup\$ Commented Dec 5, 2010 at 4:57
  • \$\begingroup\$ Sprinkler valves are not that simple. They actually won't work without significant pressure, and they take a while to close as well. \$\endgroup\$ Commented Dec 5, 2010 at 6:29

7 Answers 7


FTDI USB chip + daisy-chained '595 shift register. Put a separate transistor on each relay.

More detail:

A chain of 74hc595 is described here: http://www.arduino.cc/en/Tutorial/ShiftOut (Only two are shown, but the concept can be expanded to any number of '595s.)

To drive a the chain, three signals are needed, data, latch, and clock.

You can use an FTDI part in "bitbang" mode to generate three signals from computer control. To use the FTDI in bitbang mode, use libftdi (You could also use FTDI's official drivers, but libftdi is less hassle in my experience). A FT232R has enough pins to do this. FTDI sells a DIP breakout, and Sparkfun sells some breakouts too.

alt text

Notice you will need 128 2N2222s and 128 330 ohm resistors. (you can get resistor arrays that might be easier to manage.)

I've drawn the circuit assuming a 12V supply for your relays and no less than 24 ohm coils. If this is not the case, you might need a sturdier transistor or logic-level MOSFETs. The 2222 is about as cheap a transistor as you will find, and when you're buying 128 pieces that makes a difference.

I didn't show bypass caps or the exact 232R hookup. Read the datasheet.

OK, I just saw the solenoid you are trying to control. 2N2222 won't work. You need to switch 120VAC to the solenoid. So you can either have a small relay (with 2N2222) to switch the 120V, or use a solid-state relay that can take logic inputs and connect it directly to the '595 output.

OK, here's code to drive this using libftdi. Pin assigments in the source code. apt-get install libftdi-dev, then compile like this: "gcc test_595.c -lftdi"

/* This program is distributed under the GPL, version 2 */

#include <stdio.h>
#include <ftdi.h>

#define HC595_CT (1) // number of '595 chips

int main(int argc, char **argv)
    struct ftdi_context ftdic;
    int f,i;

    unsigned char buf[2*8*HC595_CT+1]; // latch pulse, 8*HC595_CT clock pulses

    if ((f=ftdi_init(&ftdic)) < 0)
        fprintf(stderr, "ftdi_init failed\n");
        return f;

    f = ftdi_usb_open(&ftdic, 0x0403, 0x6001);

    if (f < 0 && f != -5)
        fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(&ftdic));

    printf("ftdi open succeeded: %d\n",f);

    // FTDI cable assignments:
#define BIT_DATA (1<<0)  // 1: orange. TXD, "data"
                         // 2: yellow. RXD, unused
#define BIT_CLOCK (1<<2) // 4: green. RTS, "clock"
#define BIT_LATCH (1<<3) // 8: brown. CTS, "latch"

    ftdi_enable_bitbang(&ftdic, BIT_DATA | BIT_CLOCK | BIT_LATCH);

    // set zero
    f = ftdi_write_data(&ftdic, buf, 1);    

    unsigned char *b=buf;

    unsigned char data;
    unsigned char state;

    if (argc == 2) {
    } else {

    printf("sending data %d\n",data);

    for (i=0; i<8; i++) {   
      state=(data & (128L>>i))?BIT_DATA:0;
      state |= BIT_CLOCK;

    f = ftdi_write_data(&ftdic, buf, (b-buf));    


And here's a picture of my test setup:

alt text

(I used the TTL-232R-3V3 cable.)

  • \$\begingroup\$ I'm a bit new to all of this, and I'm self-teaching almost everything. Can you tell me a little more? IE specific products, or other tips. I'm browsing all the FTDI products now looking for the right USB solution. \$\endgroup\$ Commented Dec 5, 2010 at 2:21
  • 1
    \$\begingroup\$ I'll sketch the circuit for you later. \$\endgroup\$
    – markrages
    Commented Dec 5, 2010 at 2:25
  • \$\begingroup\$ FT245 is probably better than FT232 \$\endgroup\$ Commented Dec 5, 2010 at 6:31
  • \$\begingroup\$ What advantage does the 245 give over the 232R? \$\endgroup\$
    – markrages
    Commented Dec 5, 2010 at 16:02
  • \$\begingroup\$ That solenoid comes in a wide variety of coil voltages, from 6V to 240V. I would probably pick the 12V coil, such as the 8262G002 12/DC. However, the 120V coil was 6-8W, so something a bit bigger than a 2n2222 might be safer. \$\endgroup\$
    – W5VO
    Commented Dec 5, 2010 at 22:03

Cleaned Schematic with niceties (bypass caps, pin numbers, etc...):

alt text

With the FT245 you could use multiple shorter shift-register chains, since you have more IO.

I didn't draw it like that, but there you are. Anyways, the schematic is done in Altium Designer. If you want the schematic files, I can send them to you, but you need the software to open it.

  • \$\begingroup\$ This is an improved schematic for markrages' answer, correct? You should probably just put it as an edit there. \$\endgroup\$ Commented Dec 6, 2010 at 6:15
  • \$\begingroup\$ my sample code takes 1+2*8*N FTDI periods for a full shift. So sixteen 595's would take 257 periods. The FT232R just uses the async baudrate for clocking in bitbang samples. So at 115200 baud, a register update is 2.24 msec. \$\endgroup\$
    – markrages
    Commented Dec 6, 2010 at 7:05
  • \$\begingroup\$ Ideally, yes, but the USB interface is the slow part. I have a project based around a FT245 in bit-bang mode, and I get ~10 updates per second. Now, I'm doing this in python, so there is almost definitely some interpreter overhead, but I have trouble imagining you's get better than 1000 updates per second, considering each update takes a full USB packet. Unless you're doing something different in C than calling the FT_Write command from the driver, I can't see it being much faster. \$\endgroup\$ Commented Dec 6, 2010 at 9:20
  • \$\begingroup\$ You know you can write more than one byte at a time, right? \$\endgroup\$
    – markrages
    Commented Dec 6, 2010 at 21:06
  • \$\begingroup\$ In bit-bang mode? No I didn't realize. Well, nevermind, then. Crap. \$\endgroup\$ Commented Dec 7, 2010 at 0:29

Is there some reason a 7 to 128 decoder wouldn't be appropriate? Using a FTDI chip and serial shift register seems like overkill.

  • 1
    \$\begingroup\$ Yeah. with a pure decoder you can only open 1 valve at a time. \$\endgroup\$ Commented Dec 5, 2010 at 6:32
  • \$\begingroup\$ How expensive are latching relays? \$\endgroup\$
    – krapht
    Commented Dec 5, 2010 at 6:57

Whichever solution you end up using I would recommend taking a look at the power supply for this beast. You have the potential for really drawing a lot of current by accident (shorting out a transistor due to transient, a clock glitch setting a '1' to many, many outputs, etc.) -- Individual PTCs on each coil protects an individual coil, and I would also suggest either a low-ohm (0.1?) shunt resistor or a hall-effect current sensor which will cut power to the entire driver section if an overload is detected. An op-amp that integrates the overload over time is probably a good hardware trip design, but you can do it in a micro if that's your thing, too.


I would put 16 of these or something similar in series could drive. Not sure how you want to determine on/off but a low-end 8 pin PIC (


Matrix drive.

Mutiplex both your sources and sinks.

Connect the solenoids in arrays. ( rows & columns)

a lot less electronics.

Circuits can be like what's depicted, but you can get by with a lot less if you matrix it.

  • \$\begingroup\$ This would allow addressing any single solenoid. But the OP wants to control all the solenoids at the same time. \$\endgroup\$
    – markrages
    Commented Feb 21, 2011 at 2:39
  • \$\begingroup\$ @markrages would a solenoid notice the difference ? \$\endgroup\$ Commented Feb 21, 2011 at 3:27
  • \$\begingroup\$ Let's see, let's say you have a 9x8 multiplex and drive the solenoid 1/9th of the time. With a catch diode on the solenoid, current can flow for a while, keeping the solenoid closed. Assume zero losses, then we want to put the equivalent energy into the solenoid as the solenoid's DC rating. So drive it with rated voltage * 9. (to get rated current, di/dt = v/L). So 24V solenoids would need 216V drivers. If you stay below the voltage where the coil arcs over this might work. \$\endgroup\$
    – markrages
    Commented Feb 21, 2011 at 20:12
  • \$\begingroup\$ LEDs are easily multiplexed because they are open circuit when reverse-biased. For solenoids, each will need a series resistor for this reason. \$\endgroup\$
    – markrages
    Commented Feb 21, 2011 at 20:13
  • \$\begingroup\$ @markrages: If each solenoid had both a series diode to the supply and a reverse-parallel catch diode, multiplexing should be reasonable, though 9:1 seems a bit much. My inclination, if the application would allow it, would be to use a 4:1 wired multiplex with 12.5% duty cycle for most solenoids; any row which had solenoids that were being newly energized would receive 62.5% duty cycle briefly. This would require slightly staggering solenoid "grab" operations, but would allow a nice reduction in circuitry. \$\endgroup\$
    – supercat
    Commented Mar 22, 2011 at 15:45

For an alternative, if you've got a little funds to burn you could always invest in a Fez Domino and expand the I2C bus to 320 IOs.

The Fez Domino is and embeded C# device, however the IO board mentioned in the PDF uses a standard I2C bus which is common on most uCs.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.