使用 NanoJ V2 编程 - 应用程序示例:激光打印机

适用于第二代集成编程语言的新技术
在我们的第二代集成编程语言中,我们进行了全面的技术修订,以达到实时性以及更高的执行速度。在第 1 版的 NanoJ 中,程序作为虚拟机中的字节代码并行于电机控制器运行,因此没有受到严格的确定性定时;而在如今的新版本中,则采用确定的 1 ms 循环。此特性通过采用“协同式多任务处理”实现:

在每个 1 ms 循环中,首先从对象目录(它是中央数据库,其中含有控制器的全部设置和状态值)中读出数据。紧接着,“操作系统”(例如电机控制器的高级功能和现场总线通讯)开始运行。
实际的控制器以速度明显更快的 32 kHz 频率运行。当操作系统完成循环所需的全部运算后,把执行转移至 VMM(虚拟机监控程序)中的用户程序。此时,用户程序可以修改对象目录中的数值、执行计算等,但必须在 1 ms 内将控制权再次交还给操作系统。因此,该过程也称为协同式多任务处理。在循环结束前,用户程序的输出值将再次被写回对象目录,以便在下个循环中由电机控制器对数值进行处理。例如,这些数值可通过现场总线再次读出。

用户程序沙箱
VMM 在固件内形成受保护的运行环境。该所谓的沙箱将用户程序限制在特定的存储区和系统资源范围内,确保用户程序在任何时候都不会造成控制器的自有固件发生崩溃。此外,因用户程序运算特别密集而造成控制延迟也被考虑在内:若用户程序不具有协同性,也即如果它不会在循环结束前将控制权交还给操作系统,该程序将被终结。此时将显示错误反馈,但电机控制器仍将继续正常运行且无延迟。沙箱也促成了第二个主要新功能:现在,系统已直接采用执行速度明显更快的机器代码取代字节代码。

NanoJEasy 编程环境
借助于 NanoJEasy 编程环境,可在 NanoJ 中方便地编写程序。可以通过带语法高亮显示功能的集成编辑器开发和汇编程序。借助于带 Ethernet 接口的电机控制器(例如 N5),还可直接将程序传入电机控制器进行启停操作。

示例:标签机

下面,我们将分两步开发一个简单的程序,以此来描述标签机的功能。
应用中其它电机的功能可以非常方便地实现。用于执行缠绕和开卷动作的电机在转矩模式下运行,传送带在速度模式下运行,这两种模式都无需编程即可作为标准运行模式。标签机则需要使用一个小型程序。要实现的目标是:先将电机加速至与传送带速度相同的某一恒定速度,然后在识别到标签边缘时行进一段已定义的距离(标签长度)。为了使该示例易于理解,我们仅使用一个触发器输入端。在实际应用中,至少还需要增加一个启动输入端,用以启动电机。若您理解了该示例,增加输入端查询功能将非常简单。

首个简单版本
下述程序是首个简单版本,它仅激活定位模式并启动电机:

第 5-7 行完成映射,即:将程序中的变量分配至对象目录条目。以第 6 行为例:每个循环开始时,对象 0x6081 的内容将被写入 2 字节、带有符号 (S16) 的变量“ProfileVelocity”中;在循环结束时,内容被再次写回。此时,对象地址或对象符合 CAN 标准 DS402,因此 6081 即为最大调整速度。若映射方式并非“inout”,而仅为“input”或“output”,将仅在循环开始时读取变量或在循环结束时写回变量,例如第 6 行的控制字。无需考虑第 9 行中的“include "wrapper.h"”预处理器指令。因为它是编译器的指令,所以在每个 NanoJ 程序中都会出现。映射对象目录条目
第 5-7 行完成映射,即:将程序中的变量分配至对象目录条目。以第 6 行为例:每个循环开始时,对象 0x6081 的内容将被写入 2 字节、带有符号 (S16) 的变量“ProfileVelocity”中;在循环结束时,内容被再次写回。此时,对象地址或对象符合 CAN 标准 DS402,因此 6081 即为最大调整速度。若映射方式并非“inout”,而仅为“input”或“output”,将仅在循环开始时读取变量或在循环结束时写回变量,例如第 6 行的控制字。无需考虑第 9 行中的“include "wrapper.h"”预处理器指令。因为它是编译器的指令,所以在每个 NanoJ 程序中都会出现。主程序
在第 13 行中,主程序从“user()”函数开始;该函数相当于 NanoJ 中的“main”函数(C 或 Java 语言),并始终第一个得到执行。
在第 15 行中,出现了除映射外第二种访问对象目录的方法(“od_write”命令)。在这个指令下,那些在程序序列中仅用一次或很少使用、因而不必在每个循环中进行读入的对象,可以使用“od_read”命令进行更改或读取。因此,这里通过访问 CAN 对象 0x6060(“Modes of Operation”)启用定位模式。接下来的两行,指定了被映射的速度和目标位置。在“inout”映射方式下,将一个数值分配至变量即可,无需明确的写入命令。最终,通过被映射的控制字,DS402 的状态机切换至“ready to switch on”状态。在接下来的一行中将出现第一个“yield()”,自此,程序把控制权交还给操作系统,从而结束 1 ms 的循环。正如后续行中所呈现的那样,每次移交最终状态机后都会出现一个“yield()”,因为每个状态都必须流经控制器。若第 22 行中未出现“yield()”,从控制器的角度来看,程序将直接切换至“switched on”状态。依据 CAN 标准,这种运行是非法的,因此也无法实现。
在第五个“yield()”(即 5 ms)后,电机控制器启用,电机加速至 200 步/秒的速度。速度单位取决于对象 0x2060-0x2062 中的设置,在本例中,我们假定这些对象包含默认设置。首个程序版本由此结束。在最后几行中,通过一个无限循环来阻止程序结束,否则它会在下个循环中被重启。触发器和模拟输入
现在,我们还需要对触发器输入端做出响应,使其启动预先定义好的行程。首个程序版本将以恒定速度(近乎)无限地运行下去,因为所选择的目标位置在实际上永远都达不到。这其实就是转速模式的一个常规应用;我们虽未使用该模式,但却通过预设无法达到的位置额定值进行了模拟。通过使用这一技巧,下一步无需在两个运行模式间进行切换。作为对输入端的响应,只要重新设定目标位置即可。此外,为了便于设置标签长度,还应使用模拟输入端。为了在程序中看到输入端上的变化,必须首先对数字输入端和模拟输入端的对象进行一次映射(第 8-9 行):

现在,为首个版本的无限循环增加用于查询输入端和设定目标位置的编码:
第 37 行中数字输入端的对象通过“&”(“and”逻辑)连接至位码 0x10000,由此仅对输入端 1 进行监控。输入端变化时,目标位置和速度将被改变。此时,目标位置将由模拟输入端的值(0 至 1023)乘以 10 计算得出。在设定输入端时,将读出当前位置,加上从模拟值计算出的目标位置,并在第 43 行切换为绝对定位。由此确保,因等待控制器接受第 47 行后的位置而造成的 2 ms 延迟,不会对计算出的目标位置产生影响。
由于末端无限循环的存在,系统将等待至输入端再次改变其状态。接着,电机将停止运转,并在每次切换输入端时再次经过由模拟输入端预设的行程。

返回

问题?评论?

拥有对此商品的问题或评论?

联系支持人员