有了控件和逻辑两部分后,
要做出类似上下位通信般连接两者的效果的话,
还需要有一个能够提供通信机制的工具。
思路
- 常见的PLC与上位机间通信通过相互读写各自的一块内存块实现。
- 读写操作需要可以直接指定字地址操作,也可以直接指定位地址操作。这在前一部分里已经总结出了接口:
interface Memory{
void writeWord(int _addr, int _value);
void writeBit(int _addr, int _bit, boolean _value);
int readWord(int _addr);
boolean readBit(int _addr, int _bit);
}
- 实现这个接口的类模拟的是一块可读写的内存块。可以用一个数组实现。
- 为方便寻址和检查可以限制其容量在二的指数倍。
- 真实PLC的一个字是16位,应该用short数组实现。但Java语言不支持无符号操作,用int实现更方便。另外要同时照顾位读写及16位运算与数组输出功能较复杂,所以应该把读写操作总结成接口,根据情况在其他场景用其他方式实现。
class WordMemory implements Memory{
int[] data;
int mask;
WordMemory(int _size) {...}
@Override void writeWord(int _addr, int _value){...}
@Override void writeBit(int _addr, int _bit, boolean _value){...}
@Override int readWord(int _addr){...}
@Override boolean readBit(int _addr, int _bit){...}
}//***
- 功如果要为将来可以应用到真实的PLC通信准备,则还应该使其支持序列化或能手动输出byte数组的功能。
...
void writeArray(int _addr,int[] _array){...}
int[] readArray(int _addr, int _lenth){...}
void writeByteArray(int _wordAddr, byte[] _array){...}
byte[] readByteArray(int _wordAddr, int _wordLength){...}
byte[] toByteArray(){...}
...
- 仅在本地模拟动作时,可以完全不考虑字运算与数据的连续性,也不考虑和将来真实PLC的网络连接,则用布尔值数组和整形数组实现地址读写最方便。
class SimplifiedMemory implements Memory{
int[] wordArray;
boolean[][] bitArray;
...
}
用例伪码
CPU controller;
SimplifiedMemory memory;
SomeSubTask task;
...
void setup(){
...
task = new SomeSubTask();
memory = new SimplifiedMemory (256);
controller = new CPU(memory);
controller.addTask(task);
...
}
void draw(){
...
memory.writeBit(
mousePressed && coordinator.someUIButton.isMouseOver()
);
...
controller.run();
...
coordinator.someUILamp.setActivated(
memory.readBit(THAT_LAMP_ADDERSS, THAT_LAMP_BIT)
);
...
}
https://github.com/keyboard2769/nb-kosui/blob/master/src/kosui/ppplogic/ZcWordMemory.javagithub.com