We've got enough information to get rolling on some design and prototype work. Since a lot of this is new, we'll start with something simple -- something that gives us scope to over-design as well! We're going to design the front panel for our interface modules.
First, some background: I need to do a detailed post on PLC I/O, but for the moment it's enough to know that I/O comes in two flavors, discrete and block. Discrete I/O is simple binary, something is on or it's off. Rather than bits we refer to these things as "points." An interface module may support 8, 16, 24 or 32 points (any number, really, but multiples of 8 are convenient -- multiples of 16 are even more so.) This is useful for things like opening or closing valves or detecting if a button has been pushed.
Block I/O is useful for things that require more information to be transferred. Digital to Analog and Analog to Digital converters, for instance. Or multi-speed motor control. Interface modules that support block I/O are more varied than discrete I/O modules, so we'll have a challenge as far as designing a reusable front panel.
A quick survey of the hardware out there shows that discrete modules generally have one or two indicators that show general status (run/fault, comm, etc.) and an array of indicators showing the state of the points in the module. Block I/O modules, of course, are more diverse. There's the same sort of general status indicator, but other indicators might be bar graphs, or binary coded values (for instance in a Grey encoding module.)
Here are what I think the requirements for this component are:
- One or two general-purpose indicators;
- Support for 8, 16, 24 or 32 point indicators;
- Support for analog or binary coded information;
- User-accessible reset button;
- SPI interface to the core component;
- ICSP interface for programming.
We can use a couple of LEDs for this, but what colors? How about using 3-color LEDs, giving us some flexibility? I've seen them as low as $0.50US in small quantities so that's not going to break the bank. How should we drive these is the next question? We could drive them directly from the MCU on this component, but that's a lot of pins to take up; that would force us into a much larger MCU than we really need. A driver chip would be better. Two possible choices are the TI TLC5940 and TLC5916. The '5940 supports Pulse Width Modulation (PWM) to give us a wide range of intensities. The '5916 is more simple. Both allow us to use a single resistor to regulate the LED current, so that helps reduce the footprint for this section.
We're going to go with the 5916 chip in this case. We don't really need the PWM support, the 8 possible states of a tri-color LED should be more than sufficient. The 5940 also has several more control lines than the 5916, eating up our precious pins.
I thought about using an LED bar graph, but discovered quickly that the standard ones have either 10 or 12 segements, making things awkward for us. I liked what I saw in some, where they support red/green LEDs, giving us three colors (red+green=yellow.) Scouting around I found some rectangular red/green LEDs that should fit the bill. We can configure these in blocks of 8.
Blocks of 8 would make reasonable bar graphs for some of our analog interface modules. I can envison a motor driver using the red and green to indicate forward or reverse speed, or acceleration/deceleration.
We could drive this with the 5916 chip, but four blocks of eight with two LEDs per means a maximum of 64 LEDs we have to drive. That's 8 5916 chips, which is going to make our board very crowded, what with the LEDs and all. Fortunately, there's a popular chip used to drive 7- (8- really) segment displays, the Maxim MAX7219. It's designed to drive 8 8-segment displays, giving us our max of 64 in one chip. Like the 5916 there's only one current resistor necessary.
The 7219 looks at its outputs in terms of digits (0-7) and segments (0-7). We'll map the digits to the 8 LEDs in each block. Each block is really two sets of 8 LEDs (8 red, 8 green), so we'll map the segments to each set of LEDs. (No, I'm not sure why I did it that way and not segments->LEDs and digits->blocks. In the long run, I'm not sure it matters. I remember now -- the LEDs are common cathode and the 7219 maps segments to anode and digits to cathode. We need a common anode LED to make things look right.)
We can make a single connector do double duty as an SPI connection from the core component as well as an ICSP connection for programming the front panel MCU. In a previous post, I described this double-duty interface as the "BASB" and that's what we're going to use here. One 2x5 pin header takes care of both jobs.
The MCU for this component doesn't have to be very powerful. Both the 7219 and 5916 use a 3-wire interface, two of which can be shared. The only other I/O pins we need are for the SPI/ICSP; five will do the job (MOSI, MISO, SCK, SS, RESET.) The ATtiny85 is a little too small (only 6 I/O pins), but the next size up, ATtiny84a(12 pins) should do the job quite well.
The front panel component doesn't have strong timing or performance requirements so we'll use the ATtiny84's internal clock. Since we can spare the pins, we'll leave the MCUs external clock pins unused, just in case.
The actual circuit design is pretty straight-forward. We'll take power from the BASB. Five pins of the MCU are taken up by the BASB and the reset button. The reset button has a 10K pull-up resistor. Since it's connected to the RESET line on the BASB, it will force anything connected to that line to reset; this is how we'll reset the core component as well as the comm component.
We'll have one DATA and one CLK like from the MCU to both of the display drivers, with a separate select line for each.
The 7219 needs a current controlling resistor. Working from the data sheet and the specs for the LEDs, 28K should be about right. For the 5916, a 1K current resistor will work. Add in the usual population of filter capacitors and we're good to go.
So, here it is, my very first public circuit design. Download Plc_fp1_v10
Next up: Prototyping the circuit.