Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to write ethercat slave PDO using ecx_SDOwrite #536

Closed
bhargavah opened this issue Jul 28, 2021 · 7 comments
Closed

Not able to write ethercat slave PDO using ecx_SDOwrite #536

bhargavah opened this issue Jul 28, 2021 · 7 comments

Comments

@bhargavah
Copy link

Hi Guys,

We are trying to control an servo motor using soem library and the first basic thing which we would like the servo motor to do is to move a bit. :)

To initiate things, we have written some code and made sure that slave is in OPERATE state. Basically, this condition satisfies for us after writing quite a bit of code.

if (ec_slave[0].state == EC_STATE_OPERATIONAL) {
 ...
 ...
}

I believe that is cool. Please let me know if it is otherwise. :)

Moving on, to move it a bit, we would like to write at 0x607A(targetPosition) and some other address as well like profileVelocity etc. And then set the control word to 6, 15, 47, 63 in order to move it. I hope I am clear in explaining my process.

Now, the problem:

    int32_t targetPosition = 5000000;
    int result = ecx_SDOwrite(&ecx_context, 1, 0x607A, 0x00, TRUE, sizeof(targetPosition), &targetPosition, EC_TIMEOUTRXM);
    if(result == 0) {
           printf("Failed to write at 0x607A\n");
    }

With this chunk of the code, we try to write value 5000000 at 0x607A and expect function 'ecx_SDOwrite' returns an non NULL value on success. We see result variable as 0 and in turn printf statement gets exectured. This ultimately means that data is not written properly.

We are still learning/reading manuals and would like to get some inputs from champs across the world. Cheers!

I can share the whole code if someone likes.

@ArthurKetels
Copy link
Contributor

You can not access PDO data via SDOread/write. Please read tutorial.txt in the doc folder. Specifically \subsection iomap Accessing data through IOmap. Also PDO access via IOmap is many times more efficient than via mailbox CoE.

@bhargavah
Copy link
Author

@ArthurKetels Aah. I see. Thanks a lot for your reply. Can you please give me an example about how to access PDO? That would be cool. You might want me to point to an concise document as well.

@ArthurKetels
Copy link
Contributor

Again, please see tutorial.txt. Also this forum is a good source of information, you are not the first asking this question. See for example #461

@bhargavah
Copy link
Author

Hi @ArthurKetels , Thanks for being so helpful. Not only to me but to others as well. I see that you are very much active in replying to others.

Coming back to my problem statement, I read through this forum and learnt many things and changed my code accordingly. Snapshot:


if (ec_slave[1].state == EC_STATE_OPERATIONAL ) {
         printf("Operational state reached for all slaves.\n");
         inOP = TRUE;

         // Setting up of the time units
         // uint32_t timeInMilliSeconds = 0;

         // Setting up of mode of operation
         // spOut->mode_of_operation = 0x3;
         // ec_send_processdata();
         // wkc = ec_receive_processdata(EC_TIMEOUTRET); 
         int modeOfOperation = 0x3;
         ecx_SDOwrite(&ecx_context, 1, 0x6060, 0, 0, 1, &modeOfOperation, 1000000);

         // Setting up control word as 6. 6 means shutdown
         spOut->controlWord = 0x6;
         ec_send_processdata();
         wkc = ec_receive_processdata(EC_TIMEOUTRET);
         osal_usleep(1000);  // 0.5ms

         // Setting up control word as 7. 7 means switch on & enabled for operation
         spOut->controlWord = 0x7;
         ec_send_processdata();
         wkc = ec_receive_processdata(EC_TIMEOUTRET);
         osal_usleep(1000);  // 0.5ms

         // Setting up control word as 15. 15 means ?
         spOut->controlWord = 0x0F;
         ec_send_processdata();
         wkc = ec_receive_processdata(EC_TIMEOUTRET);
         osal_usleep(1000);  // 0.5ms

         // Setting up target position
         spOut->targetPosition = 0x4c4b40;
         ec_send_processdata();
         wkc = ec_receive_processdata(EC_TIMEOUTRET);
         osal_usleep(1000);  // 0.5ms

}

I expect servo motor to move now till targetPosition is reached but it did not move. I am happy to take feedback/suggestion from you from here again. Till that time, I would continue scratching my head against it. :)

@ArthurKetels
Copy link
Contributor

I would not rely on such a primitive way to advance the slave servo state. It is better to have a proper state machine in your code that asynchronously sets the servo state, checks the status of the slave and only then advances. Set-up a real-time task that does the SDO transfers. Have a look at the red_test.c example.

There are many other posts her on how to get a servo drive up and running. Please search those first and learn.

Some servo slaves need to work in synchronized mode. You did not bother to mention what your servo drive is. It is hard to give some general advice when having so little information. For synchronization see : #487 (comment)

@toshisanro
Copy link

@bhargavah I have been engaged in the development of EtherCAT master (SOEM) for more than two years.Based on soem, I have realized multiple master , and I can control Panasonic (A6B),elmo,STEP,inovance (ISN620),tsino-dynatron(cooldrive rc) servo driver ,and beckhoff IOs ( EK1100 ,EL1008,EL2008 etc). If you have technical requirements, please contact me.

@nakarlsson
Copy link
Contributor

Closed due to inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants