Finally got around to playing with the AC500 (PM554) and AdvancedHMI (3.98g). I found this document:
http://www402.abbext.com/DownloadFile.aspx?file=UserFiles/Answers201308/ABB-Ac500-Modbus.pdf&filename=ABB-Ac500-Modbus.pdfTo start with; You cannot read or write to I/O directly. You have to assign the variables to memory, just like you found out the hard way.
I played around with some bits and words and got it working after some headscratching. Here's the global variable list I set up with comments which function codes/addresses works:
VAR_GLOBAL
Bit0 AT %MX0.0.0 : BOOL; (* Read: 10001 - Write: 00001 *)
Bit1 AT %MX0.0.1 : BOOL; (* Read: 10002 - Write: 00002 *)
Bit2 AT %MX0.0.2 : BOOL; (* Read: 10003 - Write: 00003 *)
Bit3 AT %MX0.0.3 : BOOL; (* Read: 10004 - Write: 00004 *)
Bit4 AT %MX0.0.4 : BOOL; (* Read: 10005 - Write: 00005 *)
Bit5 AT %MX0.0.5 : BOOL; (* Read: 10006 - Write: 00006 *)
Bit6 AT %MX0.0.6 : BOOL; (* Read: 10007 - Write: 00007 *)
Bit7 AT %MX0.0.7 : BOOL; (* Read: 10008 - Write: 00008 *)
Word0 AT %MW0.0 : WORD; (* Read & write: 40001 *)
Word1 AT %MW0.1 : WORD; (* Read & write: 40002 *)
Word2 AT %MW0.2 : WORD; (* Read & write: 40003 *)
Word3 AT %MW0.3 : WORD; (* Read & write: 40004 *)
END_VAR
Note that the bits are from the first word. The funny thing is that I couldn't write bits or words with any of the intended function codes.
Just take a look at the document I linked for the mapping of the memory. Note that the addressing is completely wrong in it.