Ladder Logic 401: Data Acquisition and Analysis

Courtesy of
Courtesy of

Todays post is in response to a request by Quy Phan, who I met a couple of weeks ago while teaching for Automation Training in San Diego. He is having some problems with some existing equipment concerning noise on his analog transducers; he has pretty much exhausted his options as far as shielding and physical filters, and since I was doing training on PLC programming he asked about options in software. I told him if he would post the question on my blog, I’d address the issue here. I decided to include it as two posts, this one on signal analysis and the next on filtering in software.

Before being able to address the filtering, it is convenient to know something about the signal itself. If you have an oscilloscope, that would be ideal since you can get a great picture of the signal levels; but the PLC can also capture data and it can be analyzed. Unfortunately the methods can vary a lot depending on the platform. I am going to try and discuss this in a generic way, but the programming images come from my AB ControlLogix software.

First, capturing the signal levels: These assume a signed integer signal from an analog card, unknown resolution.

Unsigned analog signal values collected over an unspecified time
Unsigned analog signal values collected over an unspecified time

This shows a random sampling of values collected from a typical analog card. Since AD converters don’t change values very quickly, it can be difficult to see the spikes that may occur in the signal.

Close up of analog values gathered at a higher rate
Close up of analog values gathered at a higher rate

If values can be sampled at a higher rate than a typical PID control scheme might require, it might show some data like this. The spikes in these images illustrate what you can do if you do some simple limiting of values based on averaging. Next week’s post will go into more elaborate methods of smoothing out the signal.

One point I’d like to emphasize here: any modification of data collected will require a delay of the signal. After all, it takes time to process the signals and improve them. But more on that next week, this is more on the data collection side.


This is one method of creating sampling pulses that will work on pretty much any PLC platform, a free-running timer. One problem with it is that it is not going to be particularly precise since it operates within the scan. If it is necessary to improve precision, a cyclic routine or interrupt can be used.


This is a method of capturing ten values into an array. It uses a FIFO instruction, which is available in most of your more expensive processors, including Allen-Bradley and Siemens. If you want to capture more values, simply increase the size of your array, this is a handy instruction since it does everything at once.


Here is another method if you don’t have or don’t want to use a FIFO instruction. You still have to have array and file movement capabilities. The first instruction moves 9 elements, leaving room for the current signal value to be copied into the first, most recent element.

Unfortunately for Quy, his PLC platform doesn’t have either arrays or file manipulation capabilities, so he would have to do it the hard way. (His processor is an Automation Direct DL250-1)


……. and so on, down to


This takes about 20 instructions for movement of 10 values using the Automation Direct software. The MOV instructions would each need to be replaced with a LD Vxxx and an OUT Vxxx where the V’s are your desired data locations; sensor value and storage location. These are 16 bit accumulators.

More bad news: Automation Direct’s timers use a 100ms time base, so you aren’t going to be able to exceed the conversion rate of your analog cards by much, if at all. The analog cards are also probably only 12 bit resolution, if that; so there is also not going to be a lot of precision.


Here is an instruction that averages all of the elements in an array. Again, this is available on higher-end PLCs.


And the end of the rung:


This is the method you need to use if you don’t have arrays or an average instruction. Sum up all of your values and divide by the number of values. Takes 21 instructions for 10 values on the AD platform. You can keep a running average of your values this way for two or three values at a time. This could in turn be read back into another array for a running record of averages for smoothing.


This rung calculates the rate of change or Delta between consecutive captures. It works on any platform fortunately. Again, this could be read back into an array for analysis. It is useful for determining the direction of change as well as its amplitude. For filtering, you can use it to capture “spike” values.

When analyzing signals it can be useful to capture signals as quickly or frequently as possible, unlike control and filtering. The limit will be how often your card actually posts a new value to its register. By capturing lots of values in an array, you can determine the update rate of your analog card, or A-D converter. If you have an average of 5 identical values in a row at a capture rate of 5ms, your card updates every 25ms. Also, the faster you capture signals, the more likely you are to record a “spike” or out of tolerance value.

My next topic, Ladder Logic 402, will be on what to do with these values after they are analyzed along with some good filtering examples. As I have mentioned before, I am writing another book, this one on PLC programming. These topics along with some of the others in my Ladder Logic series of posts will be in there. I am experimenting with using this kind of presentation of logic images; rather than using addresses and registers or specific instructions, I am attempting to present material in a non-brand-specific way. Please let me know if you have any suggestions for the layout.


Electrical Engineer and business owner from the Nashville, Tennessee area. I also play music, Chess and Go.

4 Comments on “Ladder Logic 401: Data Acquisition and Analysis

  1. You can implement a simple moving average filter with no data storage requirements with this formula:
    An = Ao + X – Ao/S
    Where An is the new average, Ao is the old (previous) average, X is the new sample and S is the number of samples to average. Easy to implement on any controller. If you want a weighted average where more recent values contribute more, you can choose a factor and use it as such: An = Ao + F*X – F*Ao
    Where F is the factor.