Skip to content

JSR — Jump to Subroutine

Category
Program Control
Type
Output
Availability
All platforms

JSR instruction block: a block labelled JSR with one row, Routine: Auto_Cycle


JSR (Jump to Subroutine) scans another ladder routine of the project when its rung is true. The called routine’s rungs run in order, top to bottom, at the point of the JSR, and the scan then continues with the rung after the JSR. Main scans every cycle on its own; every other routine runs only when a JSR reaches it. Use JSR to split a program into routines, one per machine section or operating mode, and to run a whole block of logic only while a mode is selected. Do not use JSR to switch outputs off: a routine that stops being called is simply not scanned, so its outputs keep whatever value they last had. LadderIDE’s JSR carries no parameters and needs no SBR or RET in the routine; the routine runs to its last rung and returns. Logic that needs parameters belongs in an MBS (Method Bound Struct).


Operand Type Format Valid Range Required Description
Routine Routine name Picked from a dropdown Any ladder or text routine of the project other than Main Yes The routine to scan while the rung is true. The dialog lists the project’s routines; nothing is typed. A JSR with no routine, or one naming a routine that has been deleted, is a build error.

JSR owns no tag and takes no arguments. Data passes between routines through ordinary program tags, which every routine can read and write.


Nothing. A routine that has never been called has never run, so its outputs sit at their power-up values.

The routine is not scanned this cycle. Nothing in it is updated:

  • An OTE in the routine keeps its last value. It does not go false.
  • A timer that was timing keeps measuring wall-clock time. When the routine is next called its accumulator jumps to the elapsed time, and its DN bit may set on that first scan.
  • A counter, sequencer, shift or FIFO keeps its edge memory. If its rung is true when the routine is next called and was false when the routine was last scanned, it acts once on that scan.
  • Any JSR inside the routine is not reached either, so routines it calls are not scanned.

The routine’s rungs are scanned in order, exactly as Main’s are, with any JSR inside them followed the same way. When its last rung has run, the scan returns to the rung after this JSR. A text routine’s code runs once in the same place.

Nothing.

Rung condition Routine scanned this cycle Outputs in the routine
False No Hold their last values
True Yes, at the point of the JSR Driven by their own rungs

Scenario: A conveyor’s automatic logic lives in its own routine, Auto_Cycle. Main calls it only while the Auto mode selector is on. In Hand mode the routine is skipped and the conveyor is driven from elsewhere.

Tags:

  • Auto_Mode — Auto mode selected, BOOL
  • Start_Btn — Start pushbutton, BOOL
  • Conveyor — Conveyor run output, BOOL

Main, rung 1:

—|XIC Auto_Mode|———[JSR Auto_Cycle]———

Auto_Cycle, rung 0:

—|XIC Start_Btn|———(OTE Conveyor)———

Scan 1 — Auto_Mode = 0. The rung is false, the JSR is not reached and Auto_Cycle is not scanned. Conveyor stays at 0.

Figure 1 — JSR rung false: Auto_Mode off, the wire dark, the JSR block showing Routine: Auto_Cycle

Scan 2 — Auto_Mode = 1. The rung is true and Auto_Cycle scans at this point in the cycle.

Figure 2 — JSR rung true: Auto_Mode on, the wire lit up to the JSR block

Inside Auto_Cycle on the same scan — Start_Btn = 1. Open the routine’s tab, next to Main: its rung is true and Conveyor = 1. A routine’s tab paints its live state like any other while the simulator or Online monitor runs.

Figure 3 — The Auto_Cycle tab, open beside Main, while the routine is called: Start_Btn on, the rung lit, Conveyor energized

Then Auto_Mode goes back to 0. Auto_Cycle is no longer scanned and Conveyor stays at 1, even after Start_Btn is released. It goes to 0 only on the next scan in which Auto_Mode is on and Start_Btn is off. If the conveyor must stop when Auto mode is left, put XIC Auto_Mode in series on the output rung inside the routine, or drive the physical output from a rung in Main that the routine only requests.


  • AFI — Always False Instruction (take one rung out of service)
  • OTE — Output Energize (holds its last value in a routine that is not called)
  • TON — Timer On Delay (times on the wall clock, called or not)
  • MBS — Method Bound Struct (reusable logic with parameters and its own state)
  • Program Control Instructions — Category index

Where JSR sits. JSR is an output instruction. Place it at the right end of the rung, on the main line; it is not allowed inside a parallel branch. Conditions go to its left as for any output. A JSR with nothing to its left calls its routine every scan, which is how a routine that must always run is normally included.

Main cannot be called. Main is the routine the controller scans on its own, every cycle. A JSR may target any other routine.

Do not build a call loop. A routine must not call itself, directly or through another routine. The build reports a JSR call cycle as an error and names the routines in it.

Call each routine from one place. Two JSRs to the same routine scan it twice per cycle on the controller. Nothing breaks, because edge memory is updated by the first call, but the second call is wasted scan time and makes the program harder to follow. Gate one JSR with the OR of the conditions instead.

A routine keeps its state while it is not called. This is what makes JSR safe for mode logic and dangerous as an off switch. Anything the routine last wrote stays written. Reset what needs resetting from a rung that always scans.

Not allowed in an MBS body. A block’s logic may not reach outside itself, so JSR is refused inside an MBS body.

No SBR, RET or parameters. Older platforms mark a subroutine’s entry with SBR and its exit with RET and pass values through them. LadderIDE has neither: a routine is a named list of rungs, and tags are program-wide.

Applies to LadderIDE >=1.2.2 · Last reviewed 2026-09-11 · Screenshots verified 2026-09-11