Complete DOPSoft Macro Guide
SummaryThis note is a complete study guide for DOPSoft Macro. It covers macro types, editor workflow, command categories, programming patterns, safety checks, and many practical macro examples. Images were intentionally removed. Code examples use Expressive Code-style fenced blocks with titles, line markers, line numbers, wrapping, diff blocks, and terminal frames.
What This Chapter Teaches
This chapter explains how DOPSoft macros work in Delta HMI projects. A macro is a user-written sequence of commands that can run at specific moments: when a button changes state, before or after an object action, when a screen opens or closes, repeatedly while a screen is active, once after HMI startup, or continuously in the background.
The chapter also documents the macro command set:
| Category | Main Purpose |
|---|---|
| Arithmetic | Integer, double word, signed, floating-point, trigonometric, and accumulation operations |
| Logical Operation | Bitwise OR, AND, XOR, NOT, left shift, and right shift |
| Data Transfer | Move values, copy blocks, fill blocks, handle strings, and store floating-point values |
| Data Conversion | BCD/BIN, Word/DW, byte/word, ASCII/HEX, float/integer, and string formatting |
| Comparison | IF, ELSEIF, ELSE, ENDIF, GOTO labels, conditional CALL, and floating-point comparison |
| Flow Control | GOTO, LABEL, CALL, RET, FOR/NEXT loops, and END |
| Bit Setting | Set, clear, toggle, and read bits |
| Communication | COM port initialization, checksum, send/receive characters, station control, and IP changes |
| Drawing | Rectangle, line, point, circle, and circle-center calculation |
| File Access | FileSlot read, write, remove, length, export, and import |
| Others | Time, errors, delay, system time, history, recipe, alarm, disk format, screen capture, PLC download |
Practical takeawayUse macros for HMI-side helper logic, display calculations, data preparation, formatting, communication helpers, screen behavior, and small automation tasks. Keep time-critical machine control in the PLC whenever possible.
Mental Model of DOPSoft Macros
A DOPSoft macro is similar to a small script. Each macro contains command lines, and each macro type has a specific trigger. According to the manual, each macro type can contain up to 512 command lines.
A useful mental model is:
Trigger event happensDOPSoft selects the macro assigned to that eventThe macro reads internal memory, PLC registers, constants, or stringsThe macro executes commands line by lineThe macro writes results back to internal memory, PLC registers, display objects, files, or communication buffersThe HMI continues with the next object action, screen action, or macro cycleAddress Types
| Address Type | Example | Notes |
|---|---|---|
| Internal HMI word | $10 | Stores Word values inside the HMI |
| Internal HMI bit | $10.0 | Bit 0 of internal word $10 |
| PLC bit/register | M1, device registers | Depends on PLC connection and station settings |
| Constant | 100, 67.5, "READY" | Literal values inside the macro |
| String memory | $100 with character object length | Used by character entry/display objects |
Word, Double Word, and Signed Values
| Data Option | Meaning | Practical Warning |
|---|---|---|
| Word | 16-bit value | One register/address is used |
| Double Word / DW | 32-bit value | Two consecutive registers/addresses are used |
| Signed | Negative values allowed | Needed for values below zero |
| Unsigned | No negative values | Good for counters, raw ADC values, IDs |
| Floating-point | Usually stored across Double Word space | Display object format must match |
Double Word overlapIf
$100is used as a Double Word,$101is part of that same value. Do not store a separate Word at$101.
Core Syntax Rules
Assignment
$100 = $20$101 = 67$102 = $100 + $101Function Calls
$100 = BCD($20)$110 = MAX($10, $11)$120 = FADD(67.5, 34.9) (Signed DW)$130 = TIMETICKCommand Calls Without Assignment
BITON $10.0BITOFF $10.1BMOV($200, $100, 10)Delay(500)Comments
# This comment is not executed$100 = $20$101 = $100 * 10# End of scaling blockRecommended Macro Layout
# 1. Read inputs$100 = $20$101 = $21
# 2. Normalize or convert values$110 = TODWORD($100)$112 = $110 * 10$114 = $112 / 4095
# 3. Apply decisionsIF $114 > 80 BITON $200.0ELSE BITOFF $200.0ENDIF
# 4. Write display output$300 = $114Macro Types and Execution Timing
Quick Comparison
| Macro Type | Trigger | Best Use | Important Limitation |
|---|---|---|---|
| On Macro | Button state changes to ON | Start command, latch, timestamp | Only available for supported button types |
| Off Macro | Button state changes to OFF | Stop command, reset, timestamp | Requires state change caused by button action |
| Before Execute Macro | Before button/input action | Validation and input preparation | Runs only when object action is actually executed |
| After Execute Macro | After button/input action | Post-processing user input | Runs after the object action |
| Screen Open Macro | Once when a screen opens | Screen initialization | Other screen actions wait until it finishes |
| Screen Close Macro | Once when a screen closes | Cleanup, save temporary values | New screen actions wait until it finishes |
| Screen Cycle Macro | Repeated while screen is open | Screen-local monitoring | Depends on Macro Cycle Delay |
| Submacro | Called by another macro | Shared reusable logic | Must return properly with RET when needed |
| Initial Macro | Once after HMI startup | Global initialization | Runs only once |
| Background Macro | Repeated during HMI operation | Continuous low-load helper tasks | Executes one or several lines per execution cycle |
| Clock Macro | Repeated during HMI operation | Periodic batch logic | Executes all commands in one run |
On Macro and Off Macro
Use On/Off Macros when you need to react to the state transition of supported buttons such as Set ON, Set OFF, Maintained, and Momentary buttons.
# On Macro: button changed to ONBITON $100.0$110 = TIMETICK$111 = 1
# Off Macro: button changed to OFFBITOFF $100.0$112 = TIMETICK$111 = 0Before Execute Macro
Use it to validate or prepare data before the object action runs.
# Before Execute Macro for a Numeric Entry objectIF $10 < 0 $10 = 0ELSEIF $10 > 1000 $10 = 1000ENDIFAfter Execute Macro
Use it to calculate derived values after a button or input element finishes its action.
# After Execute Macro for a Numeric Entry object$100 = $10 * 10$101 = $100 / 100$102 = TIMETICKScreen Open Macro
# Screen Open Macro# Reset temporary screen stateFILL($100, 0, 20)
# Load current machine values into display buffer$200 = $20$201 = $21$202 = $22Screen Close Macro
# Screen Close MacroBITOFF $150.0BITOFF $150.1$151 = 0$152 = TIMETICKScreen Cycle Macro
The Screen Cycle Macro repeats while the screen is open. The manual states that the default Macro Cycle Delay is 100 ms.
# Screen Cycle MacroIF $20 > 800 BITON $300.0 $301 = 2ELSEIF $20 < 100 BITON $300.1 $301 = 1ELSE BITOFF $300.0 BITOFF $300.1 $301 = 0ENDIFSubmacro
Submacros are similar to subroutines or helper functions.
# Main MacroCALL 10$300 = $150END
# Submacro 10: scale raw value$150 = $20 * 100$150 = $150 / 4095RETInitial Macro
# Initial Macro: runs once after HMI startupFILL($100, 0, 50)BITOFF $200.0BITOFF $200.1$300 = TIMETICK$301 = 1$302 = 0Background Macro
# Background MacroBITNOT $500.0$501 = TIMETICKDelay(1000)$502 = $502 + 1Clock Macro
Clock Macro runs repeatedly and executes its program as a batch. The manual notes a default delay of 100 ms and a maximum delay of 65535 ms.
# Clock Macro$600 = TIMETICKIF $600 > 60000 BITON $601.0ELSE BITOFF $601.0ENDIF$602 = $602 + 1Macro Editor Workflow
DOPSoft provides a macro edit window and a toolbar. The important toolbar functions are Open, Save, Update, Cut, Copy, Paste, Syntax Check, Macro Wizard, Insert, Delete, Comment, Command, Variable, and Input Address.
| Tool | Purpose | Recommended Use |
|---|---|---|
| Open | Import a macro | Reuse tested logic from another project |
| Save | Export a macro | Keep backups and reusable snippets |
| Update | Apply changes and check syntax | Use before closing the editor |
| Syntax Check | Check syntax errors | Use often, but do not treat it as full testing |
| Macro Wizard | Build commands through UI | Good for avoiding address and parameter errors |
| Insert/Delete | Add or remove command lines | Keep command order clean |
| Comment | Add non-executed notes | Explain intent, not obvious syntax |
| Input Address | Select addresses through UI | Prevent typing wrong PLC/HMI addresses |
Syntax Check is not enoughSyntax Check verifies command syntax. It does not prove that the logic is correct, that the PLC address is right, or that communication timing is safe.
Suggested Editing Routine
1. Write the macro in small sections2. Add comments for address groups and assumptions3. Run Syntax Check4. Update the macro5. Compile the project6. Test with safe values7. Test boundary values8. Download only after reviewing destructive commandsCommand Reference Map
Full Category Overview
| Category | Commands |
|---|---|
| Arithmetic | +, -, *, /, %, +-*/, MUL64, ADDSUMW, FADD, FSUB, FMUL, FDIV, FMOD, SIN, COS, TAN, COT, SEC, CSC |
| Logical Operation | ` |
| Data Transfer | MOV, BMOV, ArrayCopy, FILL, FILLASC, STRCAT, FMOV |
| Data Conversion | BCD, BIN, TODWORD, TOWORD, TOBYTE, SWAP, XCHG, MAX, MIN, TOHEX, TOASC, FCNV, ICNV, SPRINTF |
| Comparison | IF...THEN GOTO, IF...THEN CALL, IF, ELSEIF, ELSE, ENDIF, FCMP |
| Flow Control | GOTO LABEL, LABEL, CALL, RET, FOR/NEXT, END |
| Bit Setting | BITON, BITOFF, BITNOT, GETB |
| Communication | INITCOM, ADDSUM, XORSUM, PUTCHARS, GETCHARS, SELECTCOM, CLEARCOMBUFFER, CHRCHKSUM, LOCKCOM, UNLOCKCOM, STATIONCHK, STATIONON, STATIONOFF, IPON, IPOFF, IPCHANGE |
| Drawing | RECTANGLE, LINE, POINT, CIRCLE, GetCircleCenter |
| File Access | FileSlotRead, FileSlotWrite, FileSlotRemove, FileSlotGetLength, FileSlotExport, FileSlotImport |
| Others | TIMETICK, GETLASTERROR, COMMENT, Delay, GETSYSTEMTIME, SETSYSTEMTIME, GETHISTORY, EXPORT, EXRCP16, IMRCP16, EXRCP32, IMRCP32, EXENRCP, IMENRCP, EXHISTORY, EXALARM, EXALARMGROUP, DISKFORMAT, BMPCAPTURE, PLCDOWNLOAD |
Arithmetic Commands
Arithmetic commands include integer, Double Word, signed, floating-point, trigonometric, and accumulation operations.
Integer Operations
$1 = 67 + 34$2 = 67 - 34$3 = 67 * 34$4 = 67 / 34$5 = 67 % 34# Convert a raw 0-4095 value into a 0-100 percent value$100 = $20 * 100$101 = $100 / 4095$102 = MAX($101, 0)$103 = MIN($102, 100)# Engineering value = raw * gain + offset$100 = $20 * $21$101 = $100 + $22$200 = $101Combined Expression
# Calculate a compact expression in one line$1 = $2 + $3 - 57 * $464-bit Multiplication
# Store a large multiplication result$1 = MUL64(67, 34) (Signed DW)Accumulation
# Example data: $0=1, $2=2, $4=3, $6=4, $8=5 when using DW spacing$0 = 1$2 = 2$4 = 3$6 = 4$8 = 5$50 = ADDSUMW($0, 5)Floating-point Operations
$100 = FADD(67.5, 34.9) (Signed DW)$102 = FSUB(67.5, 34.9) (Signed DW)$104 = FMUL(67.5, 34.9) (Signed DW)$106 = FDIV(67.5, 34.9) (Signed DW)# Convert Celsius to Fahrenheit: F = C * 1.8 + 32$100 = FMUL($20, 1.8) (Signed DW)$102 = FADD($100, 32.0) (Signed DW)$200 = $102Trigonometric Operations
$10 = SIN(67) (Signed DW)$12 = COS(67) (Signed DW)$14 = TAN(67) (Signed DW)$16 = COT(67) (Signed DW)$18 = SEC(67) (Signed DW)$20 = CSC(67) (Signed DW)Arithmetic ruleUse integer commands for counters, states, raw values, and register manipulation. Use floating-point commands only when the displayed or calculated value truly needs decimals.
Logical Operation Commands
Logical operations work on binary representation of values.
| Command | Meaning | Example |
|---|---|---|
| ` | ` | OR |
&& | AND | $10 = $1 && $2 |
^ | XOR | $10 = $1 ^ $2 |
NOT | Bitwise NOT | $10 = NOT $1 |
<< | Left shift | $10 = $1 << 2 |
>> | Right shift | $10 = $1 >> 2 |
# Use a mask to check whether bit 4 is set$100 = $20 && 16IF $100 != 0 BITON $200.0ELSE BITOFF $200.0ENDIF# Build a status word from separate bit masks$100 = 0IF $10.0 == ON $100 = $100 | 1ENDIFIF $10.1 == ON $100 = $100 | 2ENDIF# Move low-level packed data into the expected position$100 = $20 << 4$101 = $100 && 255$102 = $101 >> 2# Toggle bit mask 1 in a status word$100 = $100 ^ 1Data Transfer Commands
MOV
$100 = $20$101 = $21$102 = $22$103 = $23BMOV
# Copy 10 words from $100 to $200BMOV($200, $100, 10)ArrayCopy
# Copy a section of an array-like memory area# Parameters must be selected according to Macro Wizard and project memory layout$10 = ArrayCopy($100, 0, $200, 0, 20)FILL
# Clear 50 words starting at $300FILL($300, 0, 50)# Initialize recipe defaultsFILL($400, 100, 10)FILL($410, 0, 10)FILL($420, 1, 5)FILLASC
# Store ASCII text for a character display areaFILLASC($500, "READY")FILLASC($520, "ALARM")FILLASC($540, "STOP")STRCAT
# Join two character areas into one display buffer$600 = STRCAT($500, $520, 20)FMOV
# Store a floating-point constant$700 = FMOV(67.5) (Signed DW)Data Conversion Commands
BCD and BIN
$100 = BCD($20)$101 = BIN($100)Word and Double Word Conversion
# Prepare a Word value for a larger calculation$100 = TODWORD($20)$102 = $100 * 1000$104 = $102 / 4095Byte and Word Conversion
# Convert byte-level data into Word-level data$100 = TOWORD($20, 4)
# Convert Word-level data back into byte-level data$200 = TOBYTE($100, 4)SWAP
# Swap high and low bytes for two wordsSWAP($10, $20, 2)XCHG
# Exchange two blocks of two wordsXCHG($10, $20, 2)MAX and MIN
# Clamp $20 into 0..100 range$100 = MAX($20, 0)$101 = MIN($100, 100)ASCII and HEX Conversion
$100 = TOHEX($20)$110 = TOASC($100)FCNV and ICNV
# Convert integer to floating-point, divide, then convert back if needed$100 = FCNV($20) (Signed DW)$102 = FDIV($100, 10.0) (Signed DW)$104 = ICNV($102)SPRINTF
# Format a text message for a character display buffer$500 = SPRINTF($100, "TEMP=%d", $20)# Conceptual formatted status string$520 = SPRINTF($200, "P=%d T=%d MODE=%d", $20, $21, $22)SPRINTF parameter checkUse Macro Wizard to confirm the exact parameter count and destination length in your DOPSoft version. Character display length must be large enough for the final string.
Comparison and Conditional Commands
Operators
| Operator | Meaning |
|---|---|
== | Equal |
!= | Not equal |
> | Greater than |
>= | Greater than or equal |
< | Less than |
<= | Less than or equal |
AND == 0 | Bitwise AND result equals zero |
AND != 0 | Bitwise AND result is not zero |
== ON | Bit is ON |
== OFF | Bit is OFF |
IF / ELSE / ENDIF
IF $10 > 800 BITON $200.0 $201 = 2ELSE BITOFF $200.0 $201 = 0ENDIFELSEIF Chain
IF $10 < 100 $300 = 1ELSEIF $10 < 500 $300 = 2ELSEIF $10 < 900 $300 = 3ELSE $300 = 4ENDIFIF THEN GOTO
IF $1 == $2 THEN GOTO LABEL 1$100 = $100 + 1END
LABEL 1$100 = $200IF THEN CALL
IF $1.0 == ON THEN CALL 5$300 = $100END
# Submacro 5$100 = $20 + $21RETAND Condition
IF ($10 && 16) != 0 BITON $200.4ELSE BITOFF $200.4ENDIFFloating-point Comparison
$50 = FCMP($10, $20) (Signed DW)IF $50 > 0 $60 = 1ELSEIF $50 < 0 $60 = -1ELSE $60 = 0ENDIFNesting limitThe manual states that nested
IFstructures support up to 7 layers. For maintainability, prefer Submacros over deeply nested logic.
Flow Control Commands
GOTO and LABEL
GOTO LABEL 1$100 = 0
LABEL 1$100 = $100 + 1CALL and RET
CALL 20$300 = $150END
# Submacro 20$150 = $10 + $11RETFOR / NEXT
FOR 4 $100 = $100 + 1NEXT$101 = $100END
IF $1.0 == OFF ENDENDIF
$100 = $100 + 1Loop With Data Buffer
# Conceptual loop: repeat a calculation block$100 = 0FOR 10 $100 = $100 + 1 $200 = $200 + $100NEXT$300 = $200Bit Setting Commands
BITON $1.0BITOFF $1.1BITNOT $1.2$10.0 = GETB $2.0# Set alarm bits from thresholdsIF $20 > 900 BITON $100.0ELSE BITOFF $100.0ENDIF
IF $21 == 0 BITON $100.1ENDIF# Toggle mode bit and store timestampBITNOT $200.0$201 = TIMETICKIF $200.0 == ON $202 = 1ELSE $202 = 0ENDIFCommunication Commands
Communication macros can initialize COM ports, calculate checksums, send and receive characters, select/clear/lock/unlock COM ports, check stations, and enable/disable/change IP connections.
Communication warningDo not run heavy communication loops with very short delay. Always use timeout values, clear buffers intentionally, and check return values.
COM Initialization
# Parameters must match your port, interface, data bits, parity, stop bits, baud rate, and flow control$50 = INITCOM(1, 0, 8, 0, 1, 9600, 0)Send Characters
# Send 12 bytes from $100 with a timeout$50 = PUTCHARS($100, 12, 500)IF $50 == 0 $51 = GETLASTERROR BITON $300.0ELSE BITOFF $300.0ENDIFReceive Characters
# Clear buffer before receiving a new messageCLEARCOMBUFFER(1, 0)$60 = GETCHARS($200, 12, 500)IF $60 == 0 BITON $300.1ELSE BITOFF $300.1ENDIFChecksums
$70 = ADDSUM($100, 12)$71 = XORSUM($100, 12)# Calculate string length/checksum according to selected parameters$80 = CHRCHKSUM("READ", 0, 4)Lock and Unlock COM Port
$90 = LOCKCOM(1, 1000)IF $90 == 1 CLEARCOMBUFFER(1, 0) $91 = PUTCHARS($100, 8, 500) $92 = GETCHARS($200, 8, 500) UNLOCKCOM(1)ELSE $93 = GETLASTERROR BITON $300.2ENDIFStation Control
$100 = STATIONCHK(1, 1000)IF $100 == 0 STATIONON(1, 1000)ELSE $101 = 1ENDIFIP Control
$120 = IPON(192, 168, 0, 1)IF $120 == 1 $121 = IPCHANGE(192, 168, 0, 20, 502, 1000)ELSE $122 = GETLASTERRORENDIFDrawing Commands
Drawing commands are useful for simple visual marks. For complex interfaces, use DOPSoft objects instead.
RECTANGLE($50)LINE($60)POINT($70)CIRCLE($80)# Conceptual example: draw a marker only during alarmIF $100.0 == ON RECTANGLE($50) LINE($60)ELSE $90 = 0ENDIF# Parameters must be configured using Macro Wizard for the project coordinate system$100 = GetCircleCenter($20, $21, $22, $23, $24, $25)File Access Commands
FileSlot commands work with file storage slots. Use them carefully, especially write/remove/import operations.
Read and Write
$10 = FileSlotRead(1, $100, 0, 20)IF $10 == 1 $11 = $100ENDIF$12 = FileSlotWrite(1, $200, 0, 20)Remove and Length
$20 = FileSlotGetLength(1, $300)IF $20 > 0 $21 = FileSlotRemove(1)ELSE $21 = 0ENDIFExport and Import
$30 = FileSlotExport(1, $400, 0, 20)$31 = FileSlotImport(1, $500, 0, 20)File operation safetyNever call
FileSlotWrite,FileSlotRemove, or import commands from a fast repeated macro without a strong condition, confirmation bit, and status feedback.
Other Utility Commands
Time Tick
$100 = TIMETICKDelay(500)$101 = TIMETICKElapsed Time Measurement
# Start event$100 = TIMETICK
# Later in the macro or after another event$101 = TIMETICK$102 = $101 - $100GETLASTERROR
$10 = FileSlotWrite(1, $100, 0, 20)IF $10 == 0 $11 = GETLASTERROR BITON $200.0ENDIFDelay
BITON $10.0Delay(500)BITOFF $10.0Delay(500)System Time
$100 = GETSYSTEMTIMESETSYSTEMTIME($200)Recipe Export and Import
$100 = EXRCP16(1, $200)$101 = IMRCP16(1, $200)$102 = EXRCP32(1, $300)$103 = IMRCP32(1, $300)$104 = EXENRCP(1, $400)$105 = IMENRCP(1, $400)History and Alarm Export
$200 = GETHISTORY(1, $300, $301, $302, $303)$210 = EXHISTORY(1, $400, 0)$220 = EXALARM(1, $500)$221 = EXALARMGROUP(1, $520, 2)Screen Capture and Destructive Utilities
# Only run these commands behind an explicit service-mode conditionIF $900.0 == OFF ENDENDIF
# Examples must be verified through Macro Wizard before real use$910 = BMPCAPTURE($920)
IF $900.1 == ON # DISKFORMAT is destructive. Use only with strict confirmation. DISKFORMAT($930)ENDIFPractical Programming Recipes
Recipe 1: Safe Numeric Entry Clamp
# After Execute Macro for Numeric Entry $10IF $10 < 0 $10 = 0ELSEIF $10 > 100 $10 = 100ENDIF
$100 = $10Recipe 2: Alarm With Acknowledgement
# $20 is process value, $21 is high limit, $30.0 is acknowledge buttonIF $20 > $21 BITON $100.0ELSE BITOFF $100.0ENDIF
IF $100.0 == ON BITON $101.0ENDIF
IF $30.0 == ON BITOFF $101.0ENDIFRecipe 3: HMI Heartbeat Bit
# Background or Clock Macro with a reasonable delayBITNOT $500.0$501 = TIMETICKDelay(1000)Recipe 4: Display Raw Value as Percent
# raw input: $20, output percent: $200$100 = $20 * 100$101 = $100 / 4095$102 = MAX($101, 0)$103 = MIN($102, 100)$200 = $103Recipe 5: Mode Selector From Two Buttons
# $10.0 = auto button, $10.1 = manual buttonIF $10.0 == ON $100 = 1 BITOFF $10.1ELSEIF $10.1 == ON $100 = 2 BITOFF $10.0ELSE $100 = 0ENDIFRecipe 6: Startup Default Values
# Initial MacroFILL($100, 0, 50)$200 = 100$201 = 500$202 = 1000BITOFF $300.0BITOFF $300.1Recipe 7: Communication Request With Timeout Status
$50 = LOCKCOM(1, 1000)IF $50 == 1 CLEARCOMBUFFER(1, 0) $51 = PUTCHARS($100, 8, 500) $52 = GETCHARS($200, 8, 1000) UNLOCKCOM(1)
IF $52 == 0 $53 = GETLASTERROR BITON $300.0 ELSE BITOFF $300.0 ENDIFENDIFRecipe 8: File Write With Confirmation Bit
# $10.0 is a one-shot confirmation bit from an HMI buttonIF $10.0 == OFF ENDENDIF
$20 = FileSlotWrite(1, $100, 0, 20)IF $20 == 0 $21 = GETLASTERROR BITON $200.0ENDIF
BITOFF $10.0Recipe 9: Submacro-Based Scaling Library
# Main macroCALL 100CALL 101END
# Submacro 100: scale pressure raw value$300 = $20 * 100$301 = $300 / 4095$302 = MAX($301, 0)$303 = MIN($302, 100)RET
# Submacro 101: scale temperature raw value$310 = $21 * 200$311 = $310 / 4095$312 = $311 - 50RET
4 collapsed lines
# Reserved for future reusable conversions# Submacro 102# Submacro 103# Submacro 104Recipe 10: Screen-Local State Machine
# $100 is state: 0=idle, 1=ready, 2=run, 3=alarmIF $20.0 == ON $100 = 3ELSEIF $10.0 == ON $100 = 2ELSEIF $11.0 == ON $100 = 1ELSE $100 = 0ENDIF
IF $100 == 3 BITON $200.0ELSE BITOFF $200.0ENDIFBefore and After Refactoring Examples
Replace Repeated Logic With Submacro
$100 = $20 * 100$101 = $100 / 4095$200 = $101$110 = $21 * 100$111 = $110 / 4095$201 = $111CALL 10CALL 11$200 = $101$201 = $111CALL 10CALL 11END
# Submacro 10$100 = $20 * 100$101 = $100 / 4095RET
# Submacro 11$110 = $21 * 100$111 = $110 / 4095RETGuard Destructive Commands
DISKFORMAT($930)IF $900.0 == ON IF $900.1 == ON DISKFORMAT($930) ENDIFENDIFAdd Error Handling
$10 = FileSlotWrite(1, $100, 0, 20)$10 = FileSlotWrite(1, $100, 0, 20)IF $10 == 0 $11 = GETLASTERROR BITON $200.0ELSE BITOFF $200.0ENDIFTesting and Debugging Workflow
Test Memory Map
| Memory Range | Suggested Use |
|---|---|
$0-$49 | Temporary values for small macros |
$50-$99 | Communication return values and errors |
$100-$199 | Display buffers and calculated values |
$200-$299 | Status words and alarm bits |
$300-$399 | Recipe and file operation buffers |
$400-$499 | String buffers |
$500-$599 | Background/Clock macro state |
Boundary Test Macro
# Test clamp logic with low, normal, and high values$10 = -1CALL 30$11 = 50CALL 31$12 = 1001CALL 32ENDDebug Status Pattern
$900 = 0IF $20 > 800 $900 = 1ENDIFIF $21 == 0 $901 = GETLASTERRORENDIF$902 = TIMETICKRecommended Test Flow
Syntax CheckUpdate macroCompile projectRun with safe simulated valuesRun lower boundary valuesRun upper boundary valuesRun communication timeout testRun power-cycle startup testReview destructive commands before downloadCommon Mistakes
| Mistake | Why It Matters | Fix |
|---|---|---|
Using $101 after $100 as DW | $101 belongs to $100 DW value | Reserve two addresses for DW values |
| Running communication too fast | Buffer and timeout errors | Use delay, locks, and return checks |
Missing RET in Submacro | Macro may not return as expected | End reusable Submacros with RET |
| Duplicate labels | GOTO may jump to the wrong place | Keep label numbers unique per macro |
| Using Screen Cycle for global logic | Logic only runs while screen is open | Use Clock or Background Macro |
| No confirmation for file/write/format commands | Data loss risk | Use service mode and confirmation bits |
| Too many nested IF blocks | Hard to maintain and debug | Split into Submacros |
| No comments for memory ranges | Future edits become dangerous | Document address ownership |
| Syntax Check only | Logical errors remain hidden | Compile and test behavior |
Final Checklist
- Macro type matches the required trigger.
- The macro does not rely on a screen being open unless that is intended.
- Word and Double Word addresses do not overlap.
- Signed, unsigned, floating-point, and display formats are consistent.
- Submacros end with
RETwhen they must return. - Labels are unique within the same macro.
- Screen Cycle and Clock delays are safe.
- Communication commands check return values.
- File, recipe, disk, and PLC download commands are guarded.
- Syntax Check has passed.
- Project Compile has passed.
- Boundary tests were performed.
- Power-cycle behavior was checked for Initial Macro and persistent states.
FAQ
Should control logic be written in the HMI macro or PLC?Safety-critical and time-critical control should remain in the PLC. Use HMI macros for display logic, data preparation, formatting, simple helper tasks, and UI-related automation.
When should I use Screen Cycle Macro instead of Clock Macro?Use Screen Cycle when the logic only matters while a specific screen is open. Use Clock Macro for repeated global logic that should run regardless of the current screen.
Why does my button macro not execute?Some button-related macros execute only if the button state changes through the user action. If the state is controlled externally by the PLC or another macro, the trigger may not occur.
Why does my floating-point value display incorrectly?Check the macro command type, Double Word address allocation, display object Data Type, and display Data Format. Floating values usually require matching DW/floating configuration in the object.
How should I organize many Submacros?Group them by function. For example,
1-99for screen helpers,100-199for scaling,200-299for communication, and300-399for file/recipe utilities.
Can I use comments inside macros?Yes. Use
#comments for memory maps, assumptions, and purpose. Avoid commenting obvious single assignments unless the address meaning is important.
References
- Delta Electronics, DOPSoft User Manual - Chapter 24: Macro, November 2018.