点击上方“正运动小助手”,随时关注新动态!
本文导读
今天,正运动小助手给大家分享一下运动控制卡之ECI 0系列IO板卡的用法,并测试一下多个IO读写的速度。ECI其他系列IO板卡的输入输出使用也类似,读写速度也类似,可以供参考。
一、ECI0032/ECI0064 IO卡硬件介绍
ECI0032 IO控制卡
ECI0064 IO控制卡
ECI0064典型连接配置图:
二、IO接口介绍
通用输入口接线图参考
通用输入口的硬件规格
通过硬件参数我们发现通用输入口的输入方式是NPN漏型信号,所以在IO传感器的选择上大家要注意选择NPN类型的传感器。ZMC系列及ECI其他系列等产品的输入也类似,详见对应产品的硬件手册。
根据上图的输入口等效电路图分析:当输入口和EGND导通的时候输入口就可以捕获到信号。那么我们可以准备一根导线,导线的一段接IO电源的地(EGND),导线的另外一端去不停的触碰对应输入口的端子。同时打开RTSys/ZDevelop软件连接控制卡后打开输入口监控界面去观察对应的输入口状态是否会根据触碰的情况而变化,如果对应输入口和EGND导通对应输入口状态就显示绿灯,输入口和EGND不导通对应的输入口状态就显示红灯,那么输入口的硬件就是正常的。
RTSys输入口监控界面
输入口0(IN0)与EGND导通的输入口视图
输入口0(IN0)与EGND不导通的输入口视图
通用输出口接线图参考
通用输出口的硬件规格
根据上图的输出口等效电路图分析:当输出口输出时,OUT口是和EGND导通的。虽然输出的时候输出口的电压也是0V但输出口没有输出的时候,输出口的状态是一个高阻态的状态。所以验证输出口的功能是不推荐使用万用表的电压档去测试,而是通过万用表的导通档去打导通测试输出口的功能是否正常。(万用表打到导通档,如果是红黑表笔之间是导通的,那么万用表会发出滴滴的声音。不同的万用表的叫声不同,大家可以把万用表打到导通档后短接红黑表笔听听声音就知道你的万用表是什么音色了)
万用表导通档档位图
RTSys输出口监控界面
输出口0(OP0)未输出的万用表导通档测试情况
操作演示
三、C#语言进行ECIO板卡的开发
2.选择开发语言为“Visual C#”和.NET Framework 4以及Windows窗体应用程序。
3.找到厂家提供的光盘资料里面的C#函数库,路径如下(64位库为例)。
B、选择“函数库2.1”文件夹。
D、根据需要选择对应的函数库这里选择64位库。
E、解压C#的压缩包,里面有C#对应的函数库。
F、函数库具体路径如下。
4.将厂商提供的C#的库文件以及相关文件复制到新建的项目中。
A、将zmcaux.cs文件复制到新建的项目里面中。
5.用vs打开新建的项目文件,在右边的解决方案资源管理器中点击显示所有,然后鼠标右键点击zmcaux.cs文件,点击包括在项目中。
四、PC函数介绍
2.链接控制器,获取链接句柄。
指令3 | ZAux_OpenEth | ||||
指令原型 | int32 __stdcall ZAux_OpenEth(char *ipaddr, ZMC_HANDLE * phandle) | ||||
指令说明 | 以太网连接控制器。 | ||||
输入参数 |
| ||||
输出参数 |
| ||||
返回值 | 成功返回值为0,非0详见错误码说明。 | ||||
指令示例 | 网口连接控制器 | ||||
详细说明 | 1.网口采用RJ45标准网线接口,通讯速率为100Mbit/s。 2.控制器出厂的IP地址为192.168.0.11,端口号为502。对端通讯设备需与控制器处于同一网段,才可进行连接。 3.最常用的控制器连接方式。 4.ZMC_HANDLE类型:Zmotion库中,专门用于控制卡连接数据定义类型; |
3.快速读取多个输入口当前状态接口说明。
指令200 | ZAux_GetModbusIn | ||||||||
指令原型 | int32 __stdcall ZAux_GetModbusIn (ZMC_HANDLE handle,int ionumfirst, int ionumend, uint8 * pValueList); | ||||||||
指令说明 | 快速读取多个当前的输入状态。 | ||||||||
输入参数 |
| ||||||||
输出参数 |
| ||||||||
返回值 | 成功返回值为0,非0详见错误码说明。 | ||||||||
指令示例 | 多个IO读取 | ||||||||
详细说明 | Modbus方式获取出来的状态是未反转前的状态。如果有用INVERT_IN反转,读取的状态可能就是不对的 |
指令201 | ZAux_GetModbusOut | ||||||||
指令原型 | int32 __stdcall ZAux_GetModbusOut (ZMC_HANDLE handle,int ionumfirst, int ionumend, uint8 * pValueList); | ||||||||
指令说明 | 快速读取多个当前的输出状态。Modbus方式获取出来的状态是未反转前的状态。如果有用INVERT_IN反转,读取的状态可能就是不对的 | ||||||||
输入参数 |
| ||||||||
输出参数 |
| ||||||||
返回值 | 成功返回值为0,非0详见错误码说明。 | ||||||||
指令示例 | 多个IO读取 | ||||||||
详细说明 | Modbus方式获取出来的状态是未反转前的状态。如果有用INVERT_IN反转,读取的状态可能就是不对的 |
五、C#快速读取多个IO状态的测试例程
//链接控制器
private void LinkButton_Click(object sender, EventArgs e)
{
zmcaux.ZAux_OpenEth(IP_comboBox.Text, out g_handle);
if (g_handle != (IntPtr)0)
{
// MessageBox.Show("控制器链接成功!", "提示");
timer1.Enabled = true;
LinkButton.BackColor = Color.FromArgb(200, 255, 200);
}
else
{
MessageBox.Show("控制器链接失败,请检测IP地址!", "警告");
LinkButton.BackColor = Color.FromArgb(255, 200, 200);
}
}
3.通过定时器1监控控制器的IO状态。
//定时器更新IO信息
private void timer1_Tick(object sender, EventArgs e)
{
int j, k;
int TestNum = 50;
//快速读取输入口状态接口时间测试
byte[] InState = new byte[4];
DateTime beforeDT = System.DateTime.Now;
for (int count = 0; count < TestNum; count++)
{
zmcaux.ZAux_GetModbusIn(g_handle, 0, 32, InState);
for (int i = 0; i < 32; i++)
{
j = i / 8;
k = i % 8;
if (((InState[j] >> k) & 1) == 1)
{
InStatus[i].BackColor = Color.FromArgb(200, 255, 200);
}
else
{
InStatus[i].BackColor = Color.FromArgb(255, 200, 200);
}
}
}
DateTime afterDT = System.DateTime.Now;
//计算beforeDT与afterDT的时间差
TimeSpan ts = afterDT - beforeDT;
InMoitoring.Text = "输入口监控_刷新时间: " + (ts.TotalMilliseconds * 1000 / TestNum).ToString() + " us ";
//快速读取输出口状态接口时间测试
byte[] OutState = new byte[4];
DateTime beforeDTOP = System.DateTime.Now;
for (int count = 0; count < TestNum; count++)
{
zmcaux.ZAux_GetModbusOut(g_handle, 0, 32, OutState);
for (int i = 0; i < 32; i++)
{
j = i / 8;
k = i % 8;
if (((OutState[j] >> k) & 1) == 1)
{
OutStatus[i].BackColor = Color.FromArgb(200, 255, 200);
}
else
{
OutStatus[i].BackColor = Color.FromArgb(255, 200, 200);
}
}
}
DateTime afterDTOP = System.DateTime.Now;
//计算beforeDTOP与afterDTOP的时间差
ts = afterDTOP - beforeDTOP;
OutMoitoring.Text = "输出口监控_刷新时间: " + (ts.TotalMilliseconds * 1000 / TestNum).ToString() + " us ";
}
//多个输入口状态读取交互速度测试
private void ReadInTest_Click(object sender, EventArgs e)
{
int j, k;
int testNum = Convert.ToInt32(TestNum.Text.ToString());
int readInNum = Convert.ToInt32(ReadInNum.Text.ToString());
//快速读取输入口状态接口时间测试
byte[] InState = new byte[4];
DateTime beforeDT = System.DateTime.Now;
for (int count = 0; count < testNum; count++)
{
zmcaux.ZAux_GetModbusIn(g_handle, 0, readInNum, InState);
if (count % 100 == 0)
{
for (int i = 0; i < 32; i++)
{
j = i / 8;
k = i % 8;
if (((InState[j] >> k) & 1) == 1)
{
InStatus[i].BackColor = Color.FromArgb(200, 255, 200);
}
else
{
InStatus[i].BackColor = Color.FromArgb(255, 200, 200);
}
}
}
}
DateTime afterDT = System.DateTime.Now;
//计算beforeDT与afterDT的时间差
TimeSpan ts = afterDT - beforeDT;
//总耗时 ms
ReadInTotTime.Text = ts.TotalMilliseconds.ToString("0.00");
//平均耗时 us
ReadInTime.Text = (ts.TotalMilliseconds * 1000 / testNum).ToString("0.00");
}
//多个输出口状态读取交互速度测试
private void ReadOutTest_Click(object sender, EventArgs e)
{
int j, k;
int testNum = Convert.ToInt32(TestNum.Text.ToString());
int readOutNum = Convert.ToInt32(ReadOutNum.Text.ToString());
//快速读取输入口状态接口时间测试
byte[] OutState = new byte[4];
DateTime beforeDT = System.DateTime.Now;
for (int count = 0; count < testNum; count++)
{
zmcaux.ZAux_GetModbusOut(g_handle, 0, readOutNum, OutState);
if (count % 100 == 0)
{
for (int i = 0; i < 32; i++)
{
j = i / 8;
k = i % 8;
if (((OutState[j] >> k) & 1) == 1)
{
OutStatus[i].BackColor = Color.FromArgb(200, 255, 200);
}
else
{
OutStatus[i].BackColor = Color.FromArgb(255, 200, 200);
}
}
}
}
DateTime afterDT = System.DateTime.Now;
//计算beforeDT与afterDT的时间差
TimeSpan ts = afterDT - beforeDT;
//总耗时 ms
ReadOutTolTime.Text = ts.TotalMilliseconds.ToString("0.00");
//平均耗时 us
ReadOutTime.Text = (ts.TotalMilliseconds * 1000 / testNum).ToString("0.00");
}
//多个输出口状态设置交互速度测试
private void WriteOutTest_Click(object sender, EventArgs e)
{
int testNum = Convert.ToInt32(TestNum.Text.ToString());
int writeOutNum = Convert.ToInt32(WriteOutNum.Text.ToString());
//快速读取输入口状态接口时间测试
byte[] OutState = new byte[4];
DateTime beforeDT = System.DateTime.Now;
for (int count = 0; count < testNum; count++)
{
zmcaux.ZAux_GetModbusOut(g_handle, 0, writeOutNum, OutState);
}
DateTime afterDT = System.DateTime.Now;
//计算beforeDT与afterDT的时间差
TimeSpan ts = afterDT - beforeDT;
//总耗时 ms
WriteOutTolTime.Text = ts.TotalMilliseconds.ToString("0.00");
//平均耗时 us
WriteOutTime.Text = (ts.TotalMilliseconds * 1000 / testNum).ToString("0.00");
}
7.多个IO状态与上位机交互速度测试结果如下。
(2)32个输入输出口读写1W次,交互速度测试结果:
六、分析与结论
测试次数 | 读32个输入口 | 读32个输出口 | 写32个输出口 |
1000 | 228.39us | 197.47us | 196.47us |
1W | 225.99us | 195.29us | 194.17us |
10W | 225.37us | 194.59us | 194.45us |
本次,正运动技术以太网IO控制卡:C#实时读写时间测试,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
关于正运动技术
深圳市正运动技术有限公司成立于2013年,专注于纯国产运动控制技术研究和通用运动控制软硬件平台和产品的研发,是国家级高新技术和专精特新“小巨人”企业。
正运动技术汇集了来自华为、中兴等公司的优秀人才。力求创新,目前公司拥有专利、著作权等知识产权五十余项。在坚持自主创新的同时,积极联合各大高校和科研院所协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。
正运动技术除本部研发中心外,设有中山、武汉、上海三个研发分部。为更好地服务客户,本部之外设有苏州、东莞两个区域性服务中心,设有佛山、厦门、青岛、西安、武汉、成都、天津、郑州等销售和技术服务机构。
经过众多合作伙伴多年的开发应用,正运动技术的产品广泛地应用于3C电子、半导体、新能源、机器人、包装印刷、纺织服装、激光加工、医疗制药、数控机床、传统加工等领域。