【发布时间】:2013-01-28 06:35:36
【问题描述】:
我正在使用一些旧版软件(RSLogix 500,别问)对 PLC 进行编程,它本身不支持模数运算,但我需要一个。我无权访问:模数、整数除法、局部变量、截断操作(尽管我可以通过舍入来破解它)。此外,我可以使用的所有变量都按数据类型排列在表格中。最后,它应该适用于浮点小数,例如12345.678 MOD 10000 = 2345.678。
如果我们做我们的等式:
dividend / divisor = integer quotient, remainder
有两个明显的实现。
实施1:
执行浮点除法:dividend / divisor = decimal quotient。然后将截断操作组合在一起,以便找到integer quotient。将它乘以divisor 并找出dividend 和那个之间的差异,得到remainder。
我不喜欢这样,因为它涉及到一堆不同类型的变量。我不能将变量“传递”给子程序,所以我只需要分配位于多个不同变量表中的一些全局变量,这很难理解。不幸的是,“难以理解”很重要,因为它需要足够简单,让维护人员能够搞砸。
实施 2:
创建一个循环,使得 dividend > divisor divisor = dividend - divisor。这是非常干净的,但它违反了 PLC 编程的一条重要规则,即永远不要使用循环,因为如果有人无意中修改了索引计数器,你可能会陷入无限循环,机器会发疯或出现不可恢复的故障。 Plus 回路很难进行维护故障排除。另外,我什至没有循环指令,我必须使用标签和跳转。哎哟。
所以我想知道是否有人有任何聪明的数学技巧或比这些更聪明的模数实现。我可以访问 + - * /、指数、sqrt、三角函数、日志、abs 值和 AND/OR/NOT/XOR。
【问题讨论】:
-
你真的不能使用循环吗?这似乎很奇怪,因为几乎所有有趣的程序都必须能够循环。
-
能否保证输入在程序循环中的变化有多大?
-
@templatetypedef PLC 在整个程序中使用一个大的隐式循环,并且只在结束/开始时更新 I/O 缓冲区
-
@templatetypedef PLC 程序很少关注数据处理,而非常关注实时操作。风格更像是“当传感器 A 被触发时,将伺服 B 转至接收位置,到达该位置后,触发电磁阀 C 500 毫秒,然后释放并触发电磁阀 D。”所以基本上一个循环劫持了程序控制,你有被卡住的风险,所以整个序列不起作用。
-
@JanDvorak 不能保证,实际上模函数是更大计算的一部分。基本上,我正在捕获编码器位置并将其与其他一些参数一起存储到移位寄存器中,并且我的编码器在 10,000 个脉冲处溢出,因此,如果您检测到上升沿和下降沿,就在折点处您会必须解决这种情况。
标签: algorithm math modulus plc