MP STUDIO 2 · Memory · V1.3.0 and later

MP STUDIO 2 · Indexed Addresses (Pointers)

An indexed address, such as D100[D0], lets an instruction read and write the cell found by adding an index value to a base address (V1.3.0 and later). If D0 is 3, the instruction uses D103. By changing only the index value, you can step through data laid out like a table, such as recipe setpoints or a log buffer.

View examples How to write one

The whole MP STUDIO 2 window while an example program runs in simulation, with indexed cells showing their values and the cells they point to

Notation Base area Index Version
D100[D0] D, DD, C, DC, R D or C word, ##name V1.3.0 and later

On this page

Writing an Indexed Address

An indexed address takes the form base[index]. C-style pointer forms such as *D0 and &D100 cannot be used.

  1. In the ladder, select a value cell of an instruction (for example IN of MOVE) and enter D100[D0]. You can also type the whole instruction on one line in the Insert Function window (Ctrl+E), as in MOVE D100[D0] D200.
  2. Press Enter to confirm the cell. Lowercase letters and spaces inside and around the brackets are tidied up when you confirm (d100[ d0 ] → D100[D0]).

As with an array in C, the index counts in elements. For D, C and R, the address points to the cell that is the index away from the base. For DD and DC, where one element takes two numbers, it points to the cell that is twice the index away, so elements never overlap.

Address in the cell Index value Cell the instruction uses
D100[D0] D0 = 3 D103
C10[D1] D1 = 5 C15
DD100[D0] D0 = 1 DD102 (D102 and D103)
R5[D0] D0 = 2 R7

If you write a number as the index, the address becomes a fixed address. D100[3] is written as D103, DD100[3] as DD106 and R5[2] as R7, and a notice such as “Wrote D100[3] as D103.” is shown.

Figure 1. D100[3] entered in IN of MOVE, changed to D103, and the notice

Base Areas and Indexes

Part Can be used Cannot be used
Base address (area pointed into) D word, DD double word, C word, DC double word, R real P, M, T, BD, WM, user variables and so on
Index (inside the brackets) D or C word address, ##name user word (for example D100[##IDX]) DD, DC, R, ###name, #name

Nested brackets (D100[D0[D1]]), a bit suffix (D100[D0].3) and two addresses inside the brackets cannot be used either. If you write something that cannot be used, if the base address has a negative number, or if the index is a number outside the data memory area (for example D100[D9999]), the cell turns red and the program cannot be compiled.

The index value is read as a signed 16-bit number (-32768 to 32767), so a negative index can point to cells before the base address. The range you can point to is the size of that area set in Data Memory. What happens outside that range is described in Out of Range and @IXERR.

The index value is read once, when the instruction starts. Even if the same instruction changes the index, the result goes to the cell the index pointed to at the start. For example, DIV 7 2 D100[D0] D0 writes the remainder to D0 and the quotient to the cell that D0 pointed to when the instruction started.

Cells That Accept an Indexed Address

Indexed addresses can be used in the value cells of instructions and in compare contacts. They work as if you had written the address of the cell pointed to in that place, and orange warnings appear under the same conditions.

Category Cells that accept an indexed address
Comparison IN1 and IN2 of comparison functions · comparisons written in contact cells (for example D100[D0]>D9)
Conversion IN and OUT of H2D, D2H, INV and NEG
Math All cells of ADD, SUB, MUL and DIV · INC and DEC · the six cells of SCALE · FLOOR and SQRT
Counter SET VALUE of CTU, CTD and CTUD · HCNT, ENCODER, ENMOV and HRST
Timer SET VALUE of TON, TOFF, TPL, TMON and TMR
Word Logic All cells of WAND, WOR, WXOR, SHL, SHR and SWAP
Analog All cells of ADC, ADC2 and DAC · AFILTER · NTEMP and PTEMP · PWM, FPWM, FDPWM, NPWM, POFF and PSR · all cells of PID · PID_PWM (except PORT)
MOVE All cells of MOVE, GMOVE and FMOVE
Data Processing All cells of MAX, MIN, SUM, AVE, MUX, ENCO and DECO
Serial Port CHANNEL, DATA and LENGTH of PUT · CHANNEL, LENGTH and OUT of GET · PUT_LEN and GET_LEN · SERID and SERRATE · MNET and MNET_READ
I2C ADDRESS of ISTA · IWR · OUT of IRD · ISR · IBR
CLCD (Character LCD) ADR and the value cells of CINI, CLOC, CSTR, CINT, CREAL, CHEX, CCLS, CCON, CCOF, CPUT and CGET (except the cells listed below) · PAGE of CSCR
7-Segment IN, POSITION, LENGTH and DOT of FINT · FDATA · PAGE of FSCR
DS3231 (RTC) All cells of DS3231_WR and DS3231_RD

In instructions that work through several cells in order, such as GMOVE, FMOVE, MAX, MIN, SUM, AVE, MUX, PUT and GET, the indexed address becomes the start cell.

A block instruction does not run if its last cell is outside the area
Every element from the start element to the last cell the instruction reaches must be inside the area. The instruction reaches N elements for GMOVE, FMOVE, MAX and the like, the Nth element for MUX, and LENGTH bytes for PUT and GET. For example, if the D area is D0 to D255 and D0 is 152, IN of GMOVE D100[D0] D200 5 covers D252 to D256 and is out of range. Except for MUX, if N is 0 (for MAX, MIN, SUM and AVE, if N is 0 or less), the instruction does nothing and the range is not checked. For MUX, an N of 0 selects the start element.

Cells That Cannot Take an Indexed Address

If you write an indexed address in the cells below, the cell turns red and the program cannot be compiled. Select the cell to see the reason in the Inspector, or hover over it to see the reason in a tooltip.

Type Cells Reason shown
Cells that take only a fixed address Contact, coil and edge cells · TIMER of timers (T0) and COUNT of counters (C0) · RESET of CTU, SET of CTD, and CU, CD and RESET of CTUD · JMP, JMPN and LABEL · READ of ISTA · ACK of IRD · TYPE of CINI · DEFINE of CPUT · STRING of CSTR · ZERO and SIGN of CINT, CREAL and FINT · ZERO of CHEX · PORT of PID_PWM “D100[D0] is an indexed address, which this cell cannot take, so the program does not compile. Indexed addresses are only for an instruction's value fields (e.g. IN and OUT of MOV) and comparison contacts — write a fixed address such as D100 here.”
Cells that take only a constant ADR of CSCR · DSP of FSCR · NUM of MCS and MCSCLR · CLK and DIO of FINI · NO of MBTRIG and UPTRIG · DIGIT of CREAL “The ADR field of CSCR takes only a constant, so it cannot take an indexed address (D100[D0]) and the program does not compile. Write a constant (a number) in this field.”

Figure 2. An indexed address written in the TIMER cell of a timer, shown in red, and the reason in the Inspector

Out of Range and @IXERR

If the element an index points to is outside its area (the size set in Data Memory) while the program runs, the PLC does the following.

During monitoring and simulation, a notice appears the moment @IXERR turns on, together with the row of the last instruction the PLC skipped (and the tab name if there are two or more tabs). The notice appears even if the ladder has no @IXERR contact.

Figure 3. An index out of range in simulation

@IXERR does not turn off by itself
@IXERR stays on even after the index comes back into range. Turn it off with a RESET coil (@IXERR) in the ladder, or by writing 0 to it in the Data Table during monitoring or simulation. Unlike the other @ system bits, @IXERR accepts a written 0. After a download, it starts off.

@IXERR also turns on when BSFT, BRST or BSETN of the bit control functions goes outside its area while running, or when one cycle of TFLK does not fit in its timer (V1.4.0 and later). In a program that does not use indexed addresses, the notice appears only when @IXERR is on the ladder screen or in the Data Table, so check it with an @IXERR contact in the ladder.

Input Assistance

Index Candidate List

When you type up to D100[ in a cell input box (contact editing, a function argument cell, or the Insert Function or Edit Function window), a list shows only what can be used as an index. Index candidates — addresses used in this program lists the D and C word addresses and ##name user words used in the current tab that can serve as an index, and Registered symbols lists the symbols of those addresses, up to 8 in each group.

Figure 4. Index candidates shown after typing MOV D100[ in the Insert Function window

Choose a candidate with ↑ and ↓ and press Tab or Enter to insert it (Tab without a choice inserts the first candidate), or click it. Only the part after [ is replaced, and ] is added (unless it is already there). If the letters before [ are not D, DD, C, DC or R, or if the cell does not accept an indexed address, the usual autocomplete appears.

Using Symbols

You can use symbols for the base address and the index. If RECIPE is the symbol of D100 and IDX the symbol of D0, entering RECIPE[IDX] in a cell is saved as D100[D0]. With View → Show Symbols on, the cell shows “RECIPE[IDX]”, and the comment shown is that of the base address. You cannot register an indexed address as a symbol in the symbol table.

Figure 5. A RECIPE[IDX] cell in the ladder with symbols shown

Same-Address Highlighting and Line Breaks

When the cursor is on a D0 cell, cells that use D0 as an index get a dotted border. When the cursor is on a D100[D0] cell, the D100 and D0 cells are highlighted too. In a cell, a long address breaks onto a new line before [ (DD1000 / [D10]). Printing works the same way.

Monitoring and Simulation

During monitoring and simulation, an indexed cell shows its value together with the cell it points to now. In simulation, the range check, @IXERR and the last row in the notice work the same as on the PLC. The range check and @IXERR also work in functions that are not simulated (such as PUT).

Figure 6. Values and the cells pointed to, shown in indexed cells during simulation

Shown as Meaning
“2000 (→D103)” The value and the cell pointed to. A double word is shown as, for example, “70000 (→DD102)”.
“— (→?)” (dimmed text) The instruction has not run yet, so the cell pointed to and its value are unknown (shown only on the canvas and in the Inspector).
“Out of range (D0 = -200)” (red text) The index is out of range now.

The canvas and the Current value in the Inspector show the cell the instruction pointed to when it last ran, while the Watch card and the Data Table show the cell the index points to now, in the same form. If you change the index while the rung is off and the instruction does not run, the two can show different cells. A block cell such as IN of GMOVE shows only the start cell, as in “(→D252)”. The power flow of a compare contact is drawn from the result the PLC actually compared; a cell that is out of range or has not run yet is false. Right after the index value changes, the cell shown follows one read later.

Writing Values

Select an indexed cell and open Write Value to Memory (Alt+Enter). Address shows the cell it points to now, as in “D100[D0] → writes to D103”, and the value is written to that cell. You cannot write to a cell that has not run yet.

Figure 7. The Write Value to Memory window opened from an indexed cell

Data Table

If you add D100[D0] as a row of the Data Table, its value is shown as “2000 (→D103)”, and a value you write goes to the cell it points to now. If the index is out of range or the cell pointed to is not known yet, the value is not sent and the reason is shown. The Symbol column shows “RECIPE[IDX]”, and if you enter, for example, RECIPE[D7] there, the address becomes D100[D7].

Figure 8. The Data Table with an indexed address row

Used Data

In Run → Used Data, the base element and the index register are painted as used, and the cells from the base element to the end of the area are hatched as cells the index can reach. If the index is a ##name user word, that index is not shown in this window.

Figure 9. Cells after D100 that the index can reach, in the Used Data window (D Memory)

Examples

You can write both examples in order in a new MPA-8A8R(T) project (default data memory) and check them in simulation.

Example 1. Choosing a Setpoint by Recipe Number

In this example, D100 to D109 hold the setpoints of 10 recipes, and each press of P0 copies the value of the next recipe to D200.

  1. In Settings → Symbol, register RECIPE for D100, IDX for D0, NOW_SV for D200, NEXT_BTN for P0 and IXERR_LAMP for M0.
  2. Write the rungs below.
Rung Input Function or coil What it does
0 @ON MOVE D100[D0] D200 Copies the value of the selected recipe to D200.
1 P0 → rising edge INC D0 Selects the next recipe each time P0 is pressed.
2 D0>=10 (compare contact) MOVE 0 D0 Returns to the first recipe after the tenth.
3 @IXERR Coil M0 Turns on when the index goes out of range.

Start Run → Simulation, write 1200, 1500, 1800, 2000 and 2500 to D100 to D104 in the Data Table, and then turn P0 on and off three times. When D0 becomes 3, the IN cell of rung 0 shows “2000 (→D103)” and D200 becomes 2000 (Figure 6). If you write -200 to D0 in the Data Table, rung 0 goes out of range and is skipped, and @IXERR and M0 turn on (Figure 3). @IXERR stays on even after you set D0 back to 0.

Example 2. Logging Measurements in a Ring Buffer

In this example, the value of D10 is logged every second into the 20 cells D150 to D169 in turn, and logging starts over from the first cell after the last one.

  1. In Settings → Symbol, register TEMP for D10, POS for D1 and LOG for D150.
  2. Write the rungs below after the rungs of Example 1.
Rung Input Function What it does
4 @100 MOVE D10 D150[D1] Every second, writes the value of D10 to the cell that is D1 away from D150.
5 @100 INC D1 Moves on to the next cell.
6 D1>=20 (compare contact) MOVE 0 D1 Returns to the first cell after all 20 cells are used.

During simulation, write 25 to D10 in the Data Table and wait a few seconds. The OUT cell of rung 4 shows the cell being written now, as in “25 (→D157)”. In D Memory of Used Data, D150 is shown as used, and the cells after it up to the end of the area are shown as cells the index can reach. @100 means 1 second when the timer base is 10 ms. In a project whose timer base is set to 1 ms, use @1000 instead.

Things to Check

← Back to the MP STUDIO 2 User Manual