Closed tuanakv closed 4 years ago
You do not give us much data to work with. What is your definition of "correct position"? Some wireshark data would also be helpful. What cycle time are you using? What is your device mapping (which objects are used in which order)? When using windows as OS you can not use PACKED but must use PACKED_BEGIN and PACKED_END.
Hi Below is PDO mapping infor PDO outputs:: [0x0000.0] 0x6040:0x00 0x10 [0x0002.0] 0x607A:0x00 0x20 [0x0006.0] 0x60B8:0x00 0x10 [0x0008.0] 0x60FE:0x01 0x20 PDO inputs addr b index: sub bitl data_type name [0x000C.0] 0x603F:0x00 0x10 [0x000E.0] 0x6041:0x00 0x10 [0x0010.0] 0x6064:0x00 0x20 [0x0014.0] 0x6077:0x00 0x10 [0x0016.0] 0x60F4:0x00 0x20 [0x001A.0] 0x60B9:0x00 0x10 [0x001C.0] 0x60BA:0x00 0x20 [0x0020.0] 0x60BC:0x00 0x20 [0x0024.0] 0x60FD:0x00 0x2
I also use PACKED_BEGIN and PACKED_END as your comments:
PACKED_BEGIN
typedef struct PACKED {
uint16_t control_word;
int32_t value_607A;
uint16_t value_60B8;
uint32_t value_60FE; } output_omron;
PACKED_END // using 0x1B01 mapping
PACKED_BEGIN
typedef struct PACKED {
uint16 value_603F;
uint16 status_word;
int32 actual_position;
int16 value_6077;
int32 value_60F4;
uint16 value_60B9;
int32 value_60BA;
int32 value_60BC;
uint32 value_60FD; } input_omron;
PACKED_END
And this is code for cyclic: / cyclic loop /
for (i = 1; i <= 100000; i++) { // get status of slave status = in_omron->status_word;
bfirst = true;
if (bfirst) {
switch (state){
case 0: out_omron->control_word = 14;
if ((status == 568 ) || (status ==1592)) out_omron->control_word = 128;
if ((status == 561) || (status == 1585)) {
state = 1; }
break;
case 1: out_omron->control_word = 15;
if ((status == 3639) || (status == 2615) || (status == 5687) || (status == 4663)) {
state = 2;
bfirst = false; }
break;
case 2: out_omron->control_word = 15; break; } } ec_send_processdata();
int wkc = ec_receive_processdata(EC_TIMEOUTRET);
if (wkc >= expectedWKC) {
std::cout << in_omron->value_603F << std::endl;
std::cout << in_omron->status_word << std::endl;
std::cout << " actual position: " << in_omron->actual_position << std::endl << in_omron->value_6077 << std::endl; std::cout<< in_omron->value_60B9 << std::endl;
std::cout << in_omron->value_60BA << std::endl <
std::cout << in_omron->value_60FD << std::endl; needlf = TRUE; }
osal_usleep(5000);
////////////////// I compare value read by Twincat 3 to know what is correct or not?
I already check via wireshark, if not power on I see data from WireShark and from SOEM is the same. But if I power on Driver, only status word is the same as data from WireShark.
Can anyone help me?
Thanks
I also attach 2 wireshark file: one file capture when power on Driver, other file just read actual position and data from driver
The wireshark trace looks ok. In both cases the slave is in OP mode because we see a WKC of 3. The PDO is what it is. If you do not see the data you expect then this is a slave configuration issue. As far as SOEM goes all is fine.
I would suggest to carefully look into the slave configuration. A lot of DS402 slaves need homing before operation. And if you select synchronous modes you first have to sync master with slave and start the SYNC0/1 as required. Look for other posts here how to do that.
Hi,
Thank for your feedback. I revised my code to meet your comment and re-check as below:
Example I set out_omron->value_607A = 10000; but when print out_omron->value_607A , value = 0.
Or //////////////////////// 18 command position: 0 actual checking 5687 -1: 1301 target checking 5687 : 0 actual checking 5687 -2: 1301 status: 4663 actual position: 1301 actual torque: 0 469762048 19
I don't know why is it? Can you help me to solve this problem ?
Below I show my code as:
out_omron = (output_omron)ec_slave[0].outputs;
in_omron = (input_omron)ec_slave[0].inputs;
uint16_t status;
int8_t mode_display = 0;
int8_t state = 0;
if (slaves[0].state == EC_STATE_OPERATIONAL)
{
printf("Operational state reached for all slaves.\n");
inOP = TRUE;
/* cyclic loop */
for (i = 1; i <= 100000; i++)
{
// get status of slave
status = in_omron->status_word;
if (mode_display == 8) bfirst = TRUE;
bfirst = true;
//out_omron->control_word = 14;
if (bfirst) {
switch (state)
{
case 0: out_omron->control_word = 14;
if ((status == 568) || (status == 1592)) out_omron->control_word = 128;
if ((status == 561) || (status == 1585)) {// || (status == 624) || (status == 1648)) {
state = 1;
}
break;
case 1: out_omron->control_word = 15;
if ((status == 3639) || (status == 2615) || (status == 5687) || (status == 4663)) {
state = 2;
std::cout << "actual checking 5687 -1: " << in_omron->actual_position << std::endl;
out_omron->value_607A = 10000;
std::cout << "target checking 5687 : " << out_omron->value_607A << std::endl;
std::cout << "actual checking 5687 -2: " << in_omron->actual_position << std::endl;
}
break;
case 2:
out_omron->control_word = 15;
}
}
//int tp = sdo_read16(1, 0x1C32, 0x01);
//std::cout << "type is : " << tp << std::endl;
//int md = sdo_read16(1, 0x6061, 0x00);
//std::cout << "mode is : " << md << std::endl;
if (wkc >= expectedWKC)
{
std::cout << "status: " << in_omron->status_word << " actual position: " << in_omron->actual_position << " actual torque: " << in_omron->value_6077 << std::endl;
std::cout << " " << in_omron->value_60FD << std::endl <<i << std::endl;
std::cout << " command position: " << out_omron->value_607A << std::endl;
needlf = TRUE;
}
osal_usleep(cycle_time);
}
inOP = FALSE;
/////////////////////////////////////////////////////////////////////// / most basic RT thread for process data, just does IO transfer / void CALLBACK RTthread(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { //IOmap[0]++;
ec_send_processdata();
wkc = ec_receive_processdata(EC_TIMEOUTRET);
//std::cout << " this is rt thread " << rtcnt << std::endl;
rtcnt++;
/* do RT control stuff here */
///////////////////////// OSAL_THREAD_FUNC ecatcheck(void *lpParam) { int slave;
while (1)
{
//std::cout << " this is ecat checking " << std::endl;
if (inOP && ((wkc < expectedWKC) || ec_group[currentgroup].docheckstate))
{
if (needlf)
{
needlf = FALSE;
printf("\n");
}
/* one ore more slaves are not responding */
ec_group[currentgroup].docheckstate = FALSE;
ec_readstate();
for (slave = 1; slave <= ec_slavecount; slave++)
{
if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL))
{
std::cout << "ecat checking : " << std::endl;
ec_group[currentgroup].docheckstate = TRUE;
if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
{
printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
ec_slave[slave].state = (EC_STATE_SAFE_OP + EC_STATE_ACK);
ec_writestate(slave);
}
else if (ec_slave[slave].state == EC_STATE_SAFE_OP)
{
printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
ec_slave[slave].state = EC_STATE_OPERATIONAL;
ec_writestate(slave);
}
else if (ec_slave[slave].state > EC_STATE_NONE)
{
if (ec_reconfig_slave(slave, EC_TIMEOUTMON))
{
ec_slave[slave].islost = FALSE;
printf("MESSAGE : slave %d reconfigured\n", slave);
}
}
else if (!ec_slave[slave].islost)
{
/* re-check state */
ec_statecheck(slave, EC_STATE_OPERATIONAL, EC_TIMEOUTRET);
if (ec_slave[slave].state == EC_STATE_NONE)
{
ec_slave[slave].islost = TRUE;
printf("ERROR : slave %d lost\n", slave);
}
}
}
if (ec_slave[slave].islost)
{
if (ec_slave[slave].state == EC_STATE_NONE)
{
if (ec_recover_slave(slave, EC_TIMEOUTMON))
{
ec_slave[slave].islost = FALSE;
printf("MESSAGE : slave %d recovered\n", slave);
}
}
else
{
ec_slave[slave].islost = FALSE;
printf("MESSAGE : slave %d found\n", slave);
}
}
}
if (!ec_group[currentgroup].docheckstate)
printf("OK : all slaves resumed OPERATIONAL.\n");
}
osal_usleep(cycle_time);
}
//return 0;
} }
A wireshark trace of your test run would be nice. Are you able to run a simple slave (for example digital I/O)? When something complex does not work, first try a simple set-up.
Hi ,
I solved this problem. Once status word of slave is at "Ready to Switch On" state , must set value of 0x607A first. if not set , target position =0, so slave move to 0 position.
Good, please close the issue
HI,tuanakv,I worked on Omron R88D-1SN04H-ECT,and i met a problem .If i add code "ec_dcsync0(1, TRUE, cycle_ns, 0);",then the servo had a error 83-03,if i didnot use this code ,servo worked well.did you meet this issue?
Hi, As i know the error 83-03 just warning about lost ethercat master. But it is not problem when slave work. I use ec_dcsync0(1, TRUE, cycle_ns, cycle_ns/2) and slave work well.
HI,i am very glad to receive your letter,and my servo did not work when the error 83-03 dispalyed,so i didnot know why this happened.However,i used panasonic servo worked well used DC mode. How long had you used SOEM?i am a newer,i hope we can discuss on SOEM or ethercat master or everything if you like. this is my first time to write email use english, please forgive me some Chinese English! Best wish!
------------------ 原始邮件 ------------------ 发件人: "OpenEtherCATsociety/SOEM" <notifications@github.com>; 发送时间: 2020年7月17日(星期五) 上午6:43 收件人: "OpenEtherCATsociety/SOEM"<SOEM@noreply.github.com>; 抄送: "阳依草 "<715297306@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [OpenEtherCATsociety/SOEM] Vaule of Reading actual position is not correct, when servo driver be Power On (Operation Enable) (#415)
Hi, As i know the error 83-03 just warning about lost ethercat master. But it is not problem when slave work. I use ec_dcsync0(1, TRUE, cycle_ns, cycle_ns/2) and slave work well.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
Hi,
You can conntact me
Hi,can you give me the demo about the R88D-1SN servo,I want to learn something on how to use DC mode on OMRON servo,i used the ecsync0,then the servo had an error that can not running.thank you Best Wishes!
------------------ 原始邮件 ------------------ 发件人: "OpenEtherCATsociety/SOEM" <notifications@github.com>; 发送时间: 2020年8月4日(星期二) 中午11:14 收件人: "OpenEtherCATsociety/SOEM"<SOEM@noreply.github.com>; 抄送: "阳依草 "<715297306@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [OpenEtherCATsociety/SOEM] Vaule of Reading actual position is not correct, when servo driver be Power On (Operation Enable) (#415)
Hi,
You can conntact me
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
Hi all,
I tried using SOEM Ethercat master to control Omron R88D1SN 200W (COE profile). I can power on the driver by send control word to driver. And I also can read pdo value as "status word", "actual position". If I don't power on Driver I can read actual position correctly( I compared value with Twincat3 also), But when power on actual position value is not correct. (For status word always correct)
For reading PDO i use as: Typedef struct PACKED { Uint16 status_word; Int32 actualposition; ... } input; Input_ * inn And reading : Ec_send_processdata(); Int wkc = ec_receive_processdata(EC_TIMEOUTRET); If (wkc >= expectedWKC) { Cout<<" actual position: "inn->actual_position << endl; ...}
Can somebody can give me ideal to solve this problem ?