SOEM控制io超简洁程序

SOEM控制io超简洁程序

我想用SOEM简单控制io模块,因为我的io模块每个出入输出旁边都会有一个小灯,所以这也算是点灯程序,但是我看了例子并不知道怎么修改,都说igh麻烦,我感觉这比igh更麻烦,然后我看例子和网上的例子分析了一下,要和io从站进行数据交互,要做什么必须的操作。

初始化分析

1,ec_init(ifname)
这是最开始做的,功能:初始化SOEM,将socket绑定到ifname,ifname是你的网卡名字
2,ec_config_init(FALSE)
查看总线情况,可以得出从站数量,调用这个函数之后全局变量ec_slavecount保存的是从站数量
3,ec_config_map(&IOmap);
进行内存映射,在全局处有这么一个定义char IOmap[4096];,然后操作从站out or in,就是往这个数组写入或者读取,然后映射到真实从站
4,ec_slave[i].state = EC_STATE_OPERATIONAL; ec_send_processdata();
使从站状态转换为op状态,并把这个操作命令写入到从站

控制输出

以输出为例,想要控制io的输出,需要这两句代码

ec_slave[0].outputs[0x0001] = 0x0f;
ec_send_processdata();

主要是分析一下这句话ec_slave[0].outputs[0x0001] = 0x0f,
在http://openethercatsociety.github.io/doc/soem/tutorial_8txt.html里面有这么一个图是讲映射例子的
SOEM控制io超简洁程序_第1张图片
看起来好像是不太容易懂啊,没关系,我还有这一个
SOEM控制io超简洁程序_第2张图片
所以所有从站的input和output都映射在IOmap数组里面,我们怎么知道我们要控制的io在数组什么位置呢
那就要用到test/linux/slaveinfo例子了

$ sudo ./slaveinfo eth1 -map

可以看到这么一些信息
SOEM控制io超简洁程序_第3张图片
所以我要控制的io就是在0x0001位置,0x0f就是赋的值,8位output,将会有4位输出1,表现就是小灯亮四个

控制io完整程序

这个程序只有基本功能,没有多线程或者其他各种检查

#include 
#include 
#include 

#include "ethercattype.h"
#include "nicdrv.h"
#include "ethercatbase.h"
#include "ethercatmain.h"
#include "ethercatdc.h"
#include "ethercatcoe.h"
#include "ethercatfoe.h"
#include "ethercatconfig.h"
#include "ethercatprint.h"

char IOmap[4096];
// 使从站进入op状态
void slavetop(int i)
{
        ec_slave[i].state = EC_STATE_OPERATIONAL;
        ec_send_processdata();
        ec_receive_processdata(EC_TIMEOUTRET);
        ec_writestate(0);

}
void simpletest(char *ifname)
{
        int i,k = 1000,j=0;
        if(ec_init(ifname))
        {   
                printf("start ethernet at %s\n",ifname);
                if ( ec_config_init(FALSE) > 0 ) 
                {   
                        printf("found %d slave on the bus\n",ec_slavecount);
                        ec_config_map(&IOmap);
                        for(i=0;i<ec_slavecount;i++)
                        {   
                                printf("slave%d to op\n", i); 
                                slavetop(i);
                        }   
                        if(ec_slave[j].state == EC_STATE_OPERATIONAL)
                        {   
                                while(k--)//控制运行周期数
                                {   
                                        ec_slave[0].outputs[0x0001] = 0x0f;
                                        ec_send_processdata();
                                        ec_receive_processdata(EC_TIMEOUTRET);
                                        usleep(5000);//发送周期
                                }   
                        }   
                        else
                        {
                                slavetop(j);
                                printf("slave again to op\n");
                        }
                }
                else
                {
                        printf("no slave on the bus\n");
                }
        }
        else
        {
                printf("no ethernet card\n");
        }
}
int main(int argc, char *argv[])
{
        printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");

        if (argc > 1)
        {
                simpletest(argv[1]);
        }
        else
        {
                printf("Usage: simple_test ifname1\nifname = eth0 for example\n");
        }

        printf("End program\n");
        return (0);
}

所以,在我这里执行是这样的

结论

这样看的话,是非常简单了,但是在我想要进一步控制伺服电机的时候用这个只是按字节操作,而伺服控制字什么的都是双字节和四字节,我尝试用这个读取了只是一个字节的操作模式,读取的是正确的。我看到应该用ec_SDOread()和ec_SDOwrite(),但是我并没有成功,在调用这两个函数就出现了问题,我不知道在哪的问题,有知道的可以告诉我一下吗

你可能感兴趣的:(ethercat,linux,SOEM,Ethercat,主站协议)