Email us at:

Trusted. Reliable. Soultions.

Using TONR in Structured Text

Four Simple Rules for Using TONR in Structured Text

By Douglas Taylor

After struggling with using the TONR instruction within structured text in Logix 5000, I have empirically devised four rules that takes the mystery out of it.  These are:

1. You can call TONR multiple times during a single scan.  This got me for a while, I was afraid I would overwrite something, but it is safe to do so.

2. You must call TONR after you change values in your tag in the same scan.  If you don’t the changes won’t take effect.

3. You must call TONR before you read values from your tag such as the DN bit.  If you don’t the values won’t be correct.

4. You must clear the reset bit yourself.  It won’t be cleared automatically.   


Here is a simple example where the timer executes a line of code once every second: 


// this can be placed in an initialize step but it doesn't hurt to set these each time

my_TONR.PRE := 1000;

my_TONR.TimerEnable := 1;

// you MUST clear the reset flag yourself, it doesn't happen automatically

my_TONR.Reset := 0;

// call TONR() in each scan after you set the Reset value and before you read the DN value


// when timer is done...


               // this represents work being done once per second

               my_work := my_work + 1;

               my_TONR.Reset := 1;

               // call TONR() in each scan after you set the Reset value



In this example the first two lines set up some initial values. The PRE tag contains the number of milliseconds that the timer will count down.  In this case we will set it to 1000 milliseconds and it will trigger every second.  We will set the TimerEnable to be true and leave the timer enabled throughout this example, while the timer is controlled with the reset flag. Even though we set these values on each scan, it doesn’t hurt to do so because the values are constant and don’t ever change.  Also, at the beginning of each scan, we will set the Reset flag to false.  Later when we use this flag to reset the timer by setting it to true, we will need to set it back to false ourselves because it will not be reset by the timer.

Since we have changed values in the my_TONR tag including the Reset flag, we must call the TONR instruction in order for them to take effect.

What follows next is an IF statement.  Here we are checking the done flag (DN) of the my_TONR tag.  Since we keep the TimerEnabled flag on, the timer is always running.  Notice that we check this done flag after we called the TONR instruction.  We must make sure we call the TONR instruction before reading any tag values to ensure the state of the tag is current.  Nothing else will happen in this routine until the timer expires and the done flag is set.

On the first scan after the timer has expired and the done flag is set we enter into the true side of the IF statement.  The line that increments the tag my_work simply represents some task that we want to happen every second.  It is just a place holder.

The last thing that we want to do at the end of the true side of the IF statement is to reset the timer so it will count down again.  To do this we set the Reset flag to true.  In order for our flag to take effect we must call the TONR instruction one more time.  The reset flag will be turned back off at the beginning of the next scan.

In the following example we want a pause in normal operations when some condition occurs:


// In this example we are executing normal tasks

// that can be interrupted by a pause when some

// condition occurs.  We will represent the normal

// task with a section of code that simply increments

// a counter.  When some condition occurs, such as

// a limit switch closing we wish to pause for three

// seconds.  We will control when the pause occurs

// with a boolean flag called do_normal_work_flag.

// This flag will be set to false when the limit

// switch condition exists.  To simulate this you can

// manually set the do_normal_work_flag to false.

// At that time, the code will pause for 3 seconds

// and then set the do_normal_work_flag back to

// true at which time the normal counting will

// continue.


IF do_normal_work_flag THEN

// perform normal routine until do_normal_work_flag goes low

     normal_work_task := normal_work_task + 1;

     IF normal_work_task > 1000 THEN

           normal_work_task := 0;




     // here we will pause for 3 seconds


     // each scan we will set the PRE and

     // TimerEnable tags, since they don't

     // change it is OK to do so


     // set the number of seconds to count down

     my_TONR.PRE := 3000;

     // enable the timer

     my_TONR.TimerEnable := 1;


     // call TONR() in each pass after you set values

     // and before you read values



     // read the DN tag

     // if timer is done...



           // timer is done so disable it

           my_TONR.TimerEnable := 0;

           // call TONR() in each pass after you set values


           // pause is complete so set

           // do_normal_work_flag to true

           do_normal_work_flag := 1;







In this case we will simulate a condition during which you might want to pause.  We will use the Boolean tag do_normal_work_flag to represent this normal operation.  When this flag is false we want to pause for three seconds.

When the do_normal_work_flag is false, first we must setup the TONR to start running.  We do this by setting the time to count to 3000 milliseconds.  We also set the TimerEnable flag to true which will start the timer.  To ensure the tag values take effect, we must call the TONR instruction.

Next, to determine when the timer has expired, we must check the done flag (DN).  We must do this after the TONR instruction has been called to make sure the value of the done flag is current.

If we discover that the done flag (DN) is set and the timer has expired, we need to turn off the timer.  We do this by setting the TimerEnable flag to false and then call the TONR instruction to make sure the flag’s value is implemented.  Finally, we set the do_normal_work_flag tag back to true so that we will end the pause state and continue normal processing.

The walkthrough of this example will look like this:

     1. Assume the normal work condition represented by the Boolean tag do_normal_work_flag starts out true

     2. Initially, the first IF statement will test true and execution will continue immediately following the IF statement

     3. The normal_work_task tag will be incremented

     4. If the normal_work_task tag exceeds 1000 then the normal_work_task tag will be reset to zero

     5. The true side of the IF statement will execute indefinitely until the pause condition exists

     6. Suppose some limit switch closes and other logic sets the normal_work_task tag to false.

     7. In the next scan the first If statement will test false and execution will continue with the code following the ELSE statement

     8. Here we set the timeout period to some value, in this case three seconds and then set the TimerEnable flag to true

     9. Since we have set values in the my_TONR tag, we must call the TONR instruction for them to take effect

     10. Since we have called the TONR instruction, we can now read values in the my_TONR tag

     11. The next thing we do is to check the DN flag of the my_TONR tag to see if the pause time has been exceeded

     12. The done flag (DN) will be false for three seconds and the scan will end here until the three seconds elapses

     13. Eventually three seconds will have elapsed and the IF statement will return true

     14. We need to turn off the timer so we will set the Enable flag of the my_TONR tag to false

     15. Since we changed the my_TONR tag we must call the TONR instruction to have the changes take effect

     16. Since we have completed the pause period, we can now turn off the pause condition by setting the normal_work_task tag to true

     17. In the following passes the first If statement resolves to true and processing will return to the lines immediately following the IF statement


These are just two examples for using the TONR instruction in Structured Text.  There are many other possible solutions to various problems.  Just remember the four rules and you should stay out of trouble.

Happy programming.

Connect With Us

Stay up to date with what's going on at Trutegra by liking us on Facebook!

Join Trutegra's ever-growing professional network by connecting with us on LinkedIn!

Watch the latest videos from Trutegra by subscribing to our YouTube channel!

Work For Us.

Trutegra Careers

Interested in working for Trutegra? We are always seeking new engineers to grow our staff of innovative problem solvers. Trutegra offers a very flexible and creative work environment, with the opportunity to learn many new technologies. A competitive salary and great benefits await you. Click below to submit your resume today!

Apply Now  

Contact Us

901 Blairhill Road Suite 500, Charlotte, NC
Phone: 704.529.0123 | Fax: 704.529.0139 |