Designing a replacement for an obsolete Electro Cam control system in a Maac thermoformer using a Teensy Arduino-compatible

A high-output count DIY Arduino industrial controller and interface on the cheap

This story revolves around one of the workhorse machines in the company where I work: a Maac vacuum former. It is a solid, well-designed machine with a solid, well-designed control system that Maac contracted out to the Electro Cam systems group. As with any industrial equipment, as time goes by the OEM develops new products that replace their old stuff, technologies advance, and eventually they start the formal process of obsoleting their older inventory.

The situation started out years ago, long before I arrived on the scene, when the company I work for hired a contractor to add some automation to the Maac. When the automation was added almost all of the Electro Cam system was necessarily replaced with an Allen-Bradley SLC500 PLC to provide the changes in logic & the additional I/O points to do all of the new functions. The only Electro Cam components left in the Maac are the parts in the 84 zone oven controller. This is comprised of:

  • CPU & power supply
  • Keypad & 7-segment LED display
  • Monochrome CRT display
  • 32 point SSR output boards

We have been aware that more and more of it’s components, especially the Electro Cam controls, were being obsoleted. Recently we were put in the position to ask ourselves what our options are when one of these proprietary controls have a permanent catastrophic failure. What we learned was that we would be given few options through the official channels. We would have to leave the machine down and idle for an undetermined amount of time while the failed component was sent to Electro Cam for assessment and possible repair. This would certainly take longer than a week, but my gut says it would be closer to a month. There are also no guarantees that the part could be repaired at all. We were quoted a price for a replacement as starting at $4500, but with no promises.

Not having a replacement for a proprietary single-sourced part on the shelf is scary. Worse is when that single source says that they really can’t help you. This is one of several (maybe many) triggers for the maintenance department that I am a part of to fly wildly into a re-engineering frenzy.

The primary design requirement of 84 output points was a stickler. Buying any PLC with that many output modules is expensive. We were able to get one design into the $3500 range, but would still need an operator interface also. The original design used a set of 3 custom-designed boards that each housed 32 outputs in the form of these Opto-22 quad SSRs. Even aside from the fact that they are already installed in the machine & thus won’t cost anything additionally, these are attractive for a number of other reasons as well: very dense form factor means the 84 points don’t take up much physical space, readily available from a lot of vendors and made by a number of large manufacturers means that they are likely to be around for a long time to come, and they have already proven their longevity by having been installed in their purpose for the last 20+ years without ever having a single failure.

We agreed that the original output boards were an elegant and optimal design, in addition to the ability to reuse these would alone save close to a thousand dollars. The problem is we had no idea how to communicate with them.

Reverse Engineering

The first step to figuring these boards out was to call Electro Cam and just ask them straight out. After a few calls it was learned that the techs at Electro Cam do not deal with these boards very often and were not at all familiar with the circuitry and control itself. I was disappointed, but completely understood..


This setback made the next step to sit down and make a schematic and try to figure out all the whats and hows. It was very fortunate that we had kept 2 spare output boards that had been removed during the first automation upgrade all those years ago. Without being able to have them sitting on my desk for about a week I would have never been able to figure out how to manipulate the outputs. Here is a rough schematic. It’s the logic portion of the circuit only. I did not include any of the supporting circuitry. The inputs of the SSRs are driven by the outputs of the buffer/driver chips and designated “OA” and their single-digit position (which is the data line that sets it’s state) as well as which SSR it is in the bank (1 or 2) and it’s relative position in the SSR.

This was my first in-depth dealing with the venerable 7400-series digital logic that I’ve heard so much about my entire adult life. To be perfectly honest it has daunted me up to this point, but I dove into the datasheets nonetheless. What I found is that this is a fairly standard old-school memory addressing architecture. Hopefully all will be made more clear in the firmware code, but first here is an overview of how these boards work for our purposes:

  • The 74LS138 chip that I have designated U3 is used to address the individual boards. Setting the binary address at pins A0-2 to match the corresponding jumper position at outputs /Y0-7 allows the an enable pin of each of U1 & U2 to be brought active.
  • At this point it is necessary to set the desired state of the outputs of a bank using the 8 data lines
  • U1 & U2 are then used to address the 4 individual 8 output banks. A0 & A1 of U1 are set to the binary address of the desired bank and then the remaining enable pin of U1 is pulsed to give the clock pin of the bank’s flip-flop chip a rising-edge transition. This sets the flip-flop’s outputs (Q0-7) to the same state as it’s inputs. The transceiver takes these as input and in turn drives the corresponding 8 SSR positions

The Solution: Arduino industrial controller

The next task was to decide how to construct the glue logic that would tie an operator interface into direct control of these outputs. I decided on a Teensy 2.0 Arduino-compatible development board for the control as I’ve come to love these tiny CPUs through a number of projects. (such as the PacMod MIDI controller detailed elsewhere on this site) The fact that we now have control of 84 output points in a 2 inch square area using only 17 pins is astounding. That number could easily be much much higher in the same size and pin count.

We also decided on a C-More Micro 6″ color touchscreen as an operator interface. We have used a variety of the C-More sizes and models over the past 10 years and it is my unpaid opinion that you just can’t beat their price, performance, and ease of use. Seriously. In my own personal opinion in many instances it is more effective, both in cost and in efficiency, to use a $150 D05 PLC and one of the 3-inch base model displays than a number of pushbuttons. In that usage you can have, outside of the normal machine controls, machine diagnostic screens showing the real time state of every limitswitch, pushbutton, actuator, and anything else connected to the decision making process.

Due to my wanting to get this to a functional proof-of-concept stage as quickly as possible what I think is the best way to tie this all together is not the way I did it. The bottom line is that at the very beginning I was not absolutely certain that I could get it all to work together, so I needed to waste as little time as possible finding out if we needed to move on to one of our other design possibilities. In the future I may (probably will) write firmware for the Teensy that can directly communicate using the DirectNet protocol so that the C-More Micro will connect directly to the Teensy. As it stands now, I used an old D05 connected between the two. Since this tiny PLC wasn’t going to be doing anything other than acting as an intermediary for serial data from the C-More Micro to serial data to the Teensy I was able to use a D05 that had a burned output and so was removed from equipment several years ago.

MOTA schematic

Etched Prototype

Prototype hooked to spare Electro Cam output boards

I initially breadboarded the Teensy and the 40-pin ribbon header, but once the basic control sequence and protocol were written I etched a custom adapter prototype. Several revisions were made even after this stage, each requiring a new prototype board. Once the MOTA prototype sufficiently proved itself in running production a professionally made board was ordered from ITEAD Studio

Hopefully the Teensy firmware code below is documented well enough to make it clear what is going on. The fundamental principles are that the Teensy loops through a cycle of time base duration. The 84 zones are each assigned a duty cycle percentage by the operator and will energize a heater for that percentage of the time base. There is also an overall percentage adjustment that affects all zones called comp. Comp is a percentage of each individual zones percentage. For this reason I used 3 separate arrays. One for the zone percentages, one for the calculated millis for each zone, and a third for the comp-adjusted millis for each zone. If a single zone is changed then it is only necessary for the firmware to update the 3 array positions for that specific zone. If the time base or comp are changed then the 2 resultant arrays need to be entirely recalculated.

At the beginning the time base loop all outputs are turned on. In each iteration of the loop the current elapsed time of the loop is checked against each of the comp-adjusted time calculated for each zone. Any zones that have a value less than the elapsed time are turned off. These output states have to be sent to the board for each bank through the 8 data lines.

Any time serial data is received it is processed by a handler routine. It accepts several 1, 2, and 3 byte command packets. I’ve left all of the serial debug output in since it also serves as a form of documentation for the code.

The communication protocol between the PLC and the Teensy was a source of several frustrating roadblocks. The first plan was to have the Teensy store all necessary data and the PLC would just directly pass along user activity on the operator interface. This seemed impossible because the PLC was using what DirectSoft (the PLC programming software) calls ‘non-sequence’ protocol. This means plain ASCII serial with no wrapping protocol. When using a wrapper such as MODBUS or DirectNet 2-way communications are easily implemented. Of course, if I had written the firmware to use one of these established protocols then I would be communicating directly with the operator interface and wouldn’t need the PLC at all.

When using the non-sequence protocol there is apparently no way for the PLC to receive data, only to transmit. In setting up the PLC com port for non-sequence you are required to give a memory location for data that makes it appear that this is where received data will be placed, but I was unable to get it to work and I could find exactly zero documentation for non-sequence communications. The design compromise I made was to move responsibility for storing user data up one level into the PLC.

This now makes it necessary to transmit more data from the PLC to the Teensy. Trying to accomplish this has it’s own set of problems stemming from the serial implementation in the PLC. Originally the design was to transmit small 2- and 3- byte command packets for individual zone changes and a larger 86-byte packet to transfer an entire data set at once. The PLC wasn’t having it. The scan time of the PLC processor is faster than it’s serial port transceiver so back-to-back writes to the serial port fail. It seemed obvious that I would have to format the 86 byte packet into a single write to the serial port. Luckily the DirectSoft software allows for an entire memory range to be specified and written to the port. Unfortunately when writing a range like this the PLC inexplicably writes an 0x00 char in between each legitimate byte. I could write the Teensy firmware to discard these zeroes, but it additionally has a limit of 128 characters per serial write – and it counts those zeroes as characters. Thus, the PLC considers my 86 characters as 172 and refuses to write it to the port correctly.

The PLC strangely does not write a zero after a single byte write, so I tried doing a single write as a huge chunk of single byte calls, but again I was thwarted. This time by the text-size limit in the IDE.

This forced me to write a hugely complicated and very efficient command queuing system to manage and send the 86 individual 2- and 3- byte packets. This was too efficient and would overflow the PLC serial transmit buffer in around 70 command messages.

I ended up using a very slow packet queuing process that takes between 15 and 60 seconds to transfer all of the data set varying with how sleepy the PLC is. Depending on how much success I have writing the DirectNet protocol into the firmware I may eventually re-write the original fast block transmission into 3 smaller block commands.