MP STUDIO 2 · Memory · V1.3.0 and later
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
| Notation | Base area | Index | Version |
|---|---|---|---|
D100[D0] | D, DD, C, DC, R | D or C word, ##name | V1.3.0 and later |
DD and DC, one element takes two numbers.@IXERR turns on. No other memory is overwritten.On this page
An indexed address takes the form base[index]. C-style pointer forms such as *D0 and &D100 cannot be used.
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.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.
| 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.
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 forGMOVE,FMOVE,MAXand the like, the Nth element forMUX, and LENGTH bytes forPUTandGET. For example, if the D area isD0toD255andD0is 152, IN ofGMOVE D100[D0] D200 5coversD252toD256and is out of range. Except forMUX, if N is 0 (forMAX,MIN,SUMandAVE, if N is 0 or less), the instruction does nothing and the range is not checked. ForMUX, an N of 0 selects the start element.
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.” |
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.
@IXERR turns on. The SET VALUE of timers and counters is range-checked even while the rung is off, so @IXERR can turn on then too.
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.
D0 is -200, so the address points outside the area before D100 and is shown in red as “Out of range (D0 = -200)”. MOVE is skipped, so D200 keeps its previous value.@IXERR rung: @IXERR is on, so the coil after it is on.@IXERR does not turn off by itself
@IXERRstays 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,@IXERRaccepts 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.
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.
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.
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.
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.
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).
D0: the value of the index register (3).D200: the value that MOVE copied (2000).| 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.
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.
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].
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.
D100 in the figure) and the index register are painted.
You can write both examples in order in a new MPA-8A8R(T) project (default data memory) and check them in simulation.
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.
D100, IDX for D0, NOW_SV for D200, NEXT_BTN for P0 and IXERR_LAMP for M0.| 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.
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.
D10, POS for D1 and LOG for D150.| 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.
[, it is read as a bookmark, not an indexed address..mpx) saves the address as written in the cell (D100[D0]).