I have had times when the prototype seemed to be close to working, but it would all collapse as I tweaked elements. It was maddeningly illogical, on the surface that is, and led to considerable frustration. One minor cause was the default of the Xilinx toolset for the Spartan 3E, to use low voltage 2.5V CMOS logic levels when the Digilent board is running the fpga at 3.3V. That will work just fine for inputs, but the logic high voltages will be <= 2.5 volts, not the 3.3-ish level that I was designing for.
Interfacing different logic types and chips requires careful attention to the specifications for what constitutes the minimum voltage guaranteed to be treated as a 1 on input, the maximum voltage that will still be guaranteed to act as a 0 on input, and the corresponding guarantees for output of the minimum high voltage and maximum low voltage. Some combinations of chips may produce a 1 output that could be below the threshold for the input circuit of the next chip, which can lead to circuits that seem to work okay but sporadically misbehave, when small dips in the power level occur because of other gates conducting nearby.
The LED driver chip, a MAX7219, is a 5V powered chip whose input requirement is a minimum of 3.5V to guarantee detection as a 1. Many hobbyists report success driving this with 3.3V devices like the Digilent board, but they are in that twilight zone area where proper operation is a lucky gift, one that can be revoked by the whimsical gods of electricity at any instant. I designed the driver board with extra chips to shift the levels properly - the initial prototype used 74HCTxx chips, which have specifications that guarantee successful interpretation of the 0 and 1 voltages from 3.3V CMOS - my fpga - and produce output that is TTL compatible, meaning the 1 is high enough to be assuredly detected by the MAX7219 chip.
I built the first prototype on breadboard, soldering the components on but using discrete wire to connect them. I skimped a bit on filter capacitors, very important to shield the logic from noise produced elsewhere. In this particular case, the MAX chip itself produces a lot of noise and power fluctuation because it is firing between 0 and 64 LEDs at any instant. I added them in and put some hefty capacitors on the power lines to keep it steady in spite of the variable draw due to LED activity. Of course, I forgot that I was using thin wires snaking from my lab power supply to the board - the resistance in those wires would vary the voltage on the board in proportion to the power draw, swung by the LED activity. All that contributed to issues that I had to clean up with good practices. Those who have been hardware designers or proficient hackers for a long time will think of these things and do it right the first time; I, as a neophyte, had to be reminded the hard way.
Everything was cleaned up, my logic simulations kept showing me the protocols were done right with no signals having any close timing. I rewrote my code a few times. I finally built a second prototype board, using a better quality PCB and the components and remaining wiring done very carefully. Lots of attention to filtering, ground planes, and a completely different approach to level shifting. I wasn't sure if the 74HCT00 chip was muddling the signals somehow, so I went for a simpler method. I connected the inputs to the MAX chip through pull up resistors to 5V, and through a diode to to the FPGA output. That meant that the FPGA was not driving the high logic level - if it went to its 3.3V high level, the voltage drop (.6V) of the diode put the input at 3.9V, not 3.3V, pulled up by the resistor to my 5V supply. When the fpga went to logic 0 level, it conducted and pulled the MAX chip input down to less than 1V, but well above its threshold for logic 0. Seemed pretty straightforward, so I began debugging with this version but results weren't much better.
Yesterday when I clipped on my logic analyzer (another fpga board that records up to 32 lines and has a nice GUI on the PC to display it), and analog and scope gear as needed, I detected the problem with the 2.5V CMOS levels. A simple override in the constraints file converted this to the more appropriate 3.3V CMOS levels and I had adequate levels to work with the MAX. However, it was still flaky. One time I could bring it up and the display test function, a command sequence I would send, would light all LEDs and the reset sequence would turn them back off, but I had no data displaying. The next time, even with a very minor change, and I would have wild flickering or a completely dead panel staring back at me.
With the voltage at proper levels, I clipped on the logic analyzer problems to the connectors on my fpga, on top of the wiring heading out to the prototype board. Everything worked well! The display function was clean, the data was displayed, in fact I only had a few tweaks to make to what LEDs were assigned to 1130 functions. I was very pleased, shut it down, removed the logic analyzer and packed it away.
About an hour later I turned the panel on, no analyzer attached, and it was complete random behavior again! That was the clue - the logic analyzer probes were extending the wires between the prototype board and fpga, extending them in the opposite direction to the analyzer itself. Now, the fpga was in the middle of the line. It was reflections on the wires - transmission line effects - something I wasn't expecting for a few reasons.
1 - I was operating that is 50Khz signaling rate, not very fast at all.
2 - the fpga was set up to have slow slew of its outputs, meaning more gradual rise and fall of the logic levels. Fast switching, a very steep square wave appearance to the change, produces tons of high harmonics and these can ring like a struck bell and bounce back and forth on the wires if not absorbed.
However, that was exactly the problem. The fpga, itself clocked at 50Mhz, considered something to be a slow slew that was just too fast for the wire distance to the prototype. This was made worse by the design of the Digilent board I was using, whose "PMOD" connectors for I/O I was wired to include some protection by putting a 200 ohm resistor in series with the signals. I couldn't even attempt to terminate the transmission line with a 50 ohm resistor at the source, because the 200 ohm resistor was already there. My level shifter, a naked diode connection at the far end of the wire, didn't make things any better.
Fortunately, my 'production' PCB has higher quality printed circuit lines, ground planes and a different chip based level shifter, and I will make sure my cabling is handling the transmission line effects better. I also dropped the drive current on the fpga outputs, which should itself lessen the reflection problem.
On the typewriter front, I reassembled the fully cleaned and lubricated pin block onto the carrier and began hand cycling. It was obvious that when the R5 pin was fully released and sitting in the groove at the starting point of the print cycle, as the cam rotated it would very reliably hop into the worn 'false' groove and not do its rotation of the typeball. After lots of very close study, I decided to dig out the groove a bit to get the pin deeper before it hit the low spot in its sidewall (cut by the bad groove). I put in the time carefully reshaping the groove and moving the cam back and forth until I had it cut to reliably put the pin in deep before it hit the problem area and to swing the pin along its intended groove.
I did the PCB design for my keyboard interface board, which will also hold the Hirose FX2 100 pin connector to the fpga that will give me the more reliable IO connections. I had connectors on the board to route the typewriter logic signals on and off the FX2, plus another MCP23017 concentrator that will multiplex the 9 photocell channel signals and the control signal to fire the keyboard release solenoid, all over one pair of wires using I2C protocol.
The photocells are several megohms when dark but drops to around 10K resistance when lit up. I am operating the MCP23017 at 3.3V to be logic compatible with the fpga, but the photocells are attached to the chip as part of a voltage divider network, +5V into the photocells, the output of the photocells dropped to ground through a 16.8K resistor and the junction between photocell and resistor will feed the MCP23017 input gate. That gives it logic 0 when dark and a 1 when lit up. When the photocell is at its normal 10K, the divider circuit provides 3.13V at the MCP23017 pin, whose minimum voltage for logic 1 recognition is 2.64V. Even if the light is a bit reduced and the photocell is at 15K, the gate will recognize the input value, and it won't rise over 3.5V until the photocell gets below 7.2K total resistance which it has never approached. The MCP chip has a safety margin above 3.3 supply voltage, abs max of .6 but my design keeps it well below the 3.9V drop dead level. Logic 0 level will be under .05V with this design.
Photocell channel 2 is activated only when the KB Restore key is pressed, so this is first connected to a 74HCT14D chip, a Schmitt Trigger inverter to give crisp swings but with slightly different required voltage levels to shift on or off - below .55V to shut off and above 2V to trigger. The same voltage divider works fine for this, although the minimum guaranteed resistance of the photocell for detection of 1 is an even more unlikely 6K. The output of the inverter can be divided and delivered to the MCP23017 at its required levels by using a divider network with the output of the inverter going through a 4.2K and then a 10K resistor to ground. Providing the MCP23017 with a signal from the center connection of the two resistors will convert the 74HCT14 chip output, which is no less than 4.3V high but no more than 4.5V, to the target of 3.1 to 3.3V at the MCP input pin. Logic low output of the 74HCT14 is no higher than about .25V worst case, divided down the resistor network to .175V, while the MCP threshold for logic 0 switching is .66V; the network thus meets the requirements for both 1 and 0 detection at the schmitt trigger thresholds.
I found an old laptop power brick that produces 20V, perfect for firing the keyboard restore solenoids, and will use a fast relay on the board to switch the 6W used by those relays on and off. The 74HCT14 is feeding the voltage divider to the MCP23017 but also feeding the base of a driver transistor circuit, through a 2K resistor to produce about 2ma of current, which is amplified to drive the 33ma of a surface mount relay. The relay will switch the 20V line to fire the keyboard restore solenoids, which together will draw about 290ma (about 6W of power consumed when energized).
Thus, the KB Restore key acts locally through the board in addition to the photocell 2 channel signal that is sent to the fpga. The keyboard adapter logic of the 1130 expects to see the KB Restore key signal, which is why it is delivered there too. All other keys are decoded in the fpga from the results of the various photocell signals.
My LED driver board was flow soldered to put the surface mount components in place. The MAX7219 chips are through hole (DIP) devices, coming in the mail tomorrow, and I will hand solder them to finish this board. The input interface board has components mounted on both top and bottom faces, which adds some small complication for flow soldering in the toaster oven setup. I chose to use relatively high temperature lead free solder paste for the underside components, of course soldering them with that face physically upwards in the oven. Now that the 'bottom' parts are on with a solder that melts at a high temperature, I will place the top side components and use a low temperature solder paste for that side. By keeping the oven just hot enough to flow the low temp paste, those top side parts will be soldered while the components already in place on the underside stay firmly soldered. This board is all surface mount, 14 ICs, plenty of capacitors and quite a few connectors.
I hope to send the PCB design for the keyboard/typewriter interface board off to the fab tomorrow, once I prototype a few portions to validate the choice of parts values. Having to lay out the pads for a connector with 100 closely spaced pins in four staggered rows was pretty tedious, but it is now done. It is late now, time to walk away from the project for a while.
I have the new compressor for the airbrush and an adhesion promotion spray to improve the bonding of the paint to the keycaps, put on as a first layer once I rough the caps up slightly and clean off all dirt and greases.I will experiment with the airbrush and the spare keycaps until I am ready to recolor the selected keys. Part of the technique will be ways to fill in the shallow etched legends on caps that currently have wording but should be blank for the 1130 replica. I have not worked out how to form the new legends for keys whose wording has to change, for example Int Req, Rest KB, Erase Fld, EOF, and left arrow (backspace).
Friday - my components came and I worked on the LED driver board first. My first action is to carefully check all the connections, ensuring that the traces were produced correctly, the vias that link top and bottom layers are lined up and connected, and that any tight clearances avoided accidental corrections. While working through the board, I discovered that an assumption I made about the PCB design software has come to bite me, requiring a little wiring be added to fix the board. It is the only board where I let the software autoroute all the connections, otherwise I might have spotted this before manufacture.
|It appears that C6, R1 and +5V are connected|
|Moved +V symbol, the gap is now visible|
I completed that connection and soldered in the DIP package Max7219s (traditional IC packaging with a rectangle that has leads extending through holes, soldered on the opposite face of the PCB from where they are mounted) and the connectors for cabling to LEDs and the fpga. On Saturday I will finish testing it.
|LED Driver board - LED connectors across top, white is signal/power|
Saturday - finished the adjustments and tweaking, the typewriter now reliably selects with all solenoids! Time to move on, finish the cabling to the fpga and my logic inside the fpga to do character translation and control signal timing. Very pleased.