Absolute (BiSS-C) position encoder

Ladies and gents,

I am starting a position control project using:

  • a IONI PRO
  • a stepping motor
  • a driving worm screw
  • an absolute position encoder, with a BiSS-C interface.

For safety reasons, the project requires an absolute position reading. Absolutely absolute :wink:
There shall be no homing switch, no hardstop homing, no overtravel switches. All must rely on the absolute position sensor reading.

I tested with Granity at first, while a control software (in c, :technologist: calling the API) is being written.

So far so good :smile_cat: but whenever I power the IONI on, the absolute sensor reading is reported to be ZERO (whatever its true position might be), which I rather call a relative reading :scream:. The sensor seems not guilty: whenever I unplug and replug it, it reports the same reading. Only the IONI seems to subtract the power-on position from the actual reading.

Did I overlook some option to turn the position reading to absolute ?

A relative reading would be a no-go : we need an absolute position control. Absolutely absolute :wink:

Ideas welcome :pray:

connect to granity and show all the tabs with photos, but what you are looking for is most likely position feedback device in machine tab. if your settings are correct maybe check your wiring

I absolutely donā€™t see what I could possibly change :thinking:

since i donā€™t know your encoder i canā€™t comment.

Knowing the encoder make and model would be essential.

Also, knowing the simplemotion API parameter you are using now, that reads 0, would be be nice.

The sensor is supposedly absolute, and power-cycling the sensor does not change the position reading. The (optical) sensor is from Renishawā€™s Absolute series at the moment.

I havenā€™t tried power-cycling the IONI but not the sensor; it takes some wiring changes but I shall try it.

Here is an extract of the code to read the position. It returns the same data as Granity does, AFAIK.

printf("Monitoring actual position...\n");
while (elapsedTime < TIMEOUT_MS) {
    // Read the actual position
    result = smRead1Parameter(bus, DRIVE_ID, SMP_ACTUAL_POSITION_FB, &actualPosition);
    if (result != SM_OK) {
        fprintf(stderr, "Error: Unable to read the actual position.\n");
        break;
    }

How about this one (source: simplemotion_defs.h)

#define SMP_ACTUAL_POSITION_FB_NEVER_RESETTING 906 /*this is same than SMP_ACTUAL_POSITION_FB but does not reset to 0 on homing or init (it is always the original counter value at power-on)*/```
1 Like

Iā€™ll try this ASAP :dash:

This kind of seem to work :heart_eyes: (subject to further testing).

However, is there a similar way to set the target setpoint in absolute ? Or shall I do the math ?

rel_target = abs_target + rel_position - abs_position

(Then after this, Iā€™ll have more questions :cowboy_hat_face:)

That I donā€™t know right away. I will need to check examples or documentation.

Any clue ?

I have to say that I find this ā€œrelativeā€ behaviour of the IONI PRO quite :thinking: surprising. You do not use a digital absolute sensor without a reason (they are more expensive and require a sophisticated interface), so my understanding is that :straight_ruler: position reading and :dart: setpoint should also be absolute.

I think most of industrial applications do use some type of limit switches, if not for any other reason than safety.

I didnā€™t have time to look at this yet.

Hey, long time :sweat_smile:

Any idea ?

Sorry, I havenā€™t had time to look into this.

Any idea on when you have time to get an idea ?

Well, according to documentation at

https://granitedevices.com/wiki/SimpleMotion_V2_API_documentation#smSetParameter

the smSetParameter() function allows to write a 32 bit value to any parameter. Does this 32 bit value not work if you write your desired setpoint to

#define SMP_ABSOLUTE_SETPOINT 551

parameter?

If this parameter is in reference to the position at power on, I think it would be trivial to calculate the offset just once from the power-on position vs. the never resetting position and then continue from there.

Well, contrary to what its name suggests, SMP_ABSOLUTE_SETPOINT is absolutely relative to the power-on position.

Of course, I did the math relTarget = relPosition - absPosition + absTarget and it works.

but this looks somewhat weird (especially after I told the project team that thanks to our costly absolute sensor, we could aim at a setpoint the same way :face_with_hand_over_mouth:)

Also, for reading the absolute, then the relative position, it takes two non-simultaneous SM calls and the result will be impaired if the sensor is (even unintentionally) in motion. (ok, make a reading before, a reading after, take average value :grimacing:)

result = smRead1Parameter(bus, DRIVE_ID, SMP_ACTUAL_POSITION_FB_NEVER_RESETTING, &absPosition);
if (result != SM_OK) {
    fprintf(stderr, "Error: Unable to get the absolute position.\n");
    smCloseBus(bus);
    return EXIT_FAILURE;
}
result = smRead1Parameter(bus, DRIVE_ID, SMP_ACTUAL_POSITION_FB, &relPosition);
if (result != SM_OK) {
    fprintf(stderr, "Error: Unable to get the relative position.\n");
    smCloseBus(bus);
    return EXIT_FAILURE;
}
relTarget = relPosition - absPosition + absTarget;
result = smSetParameter(bus, DRIVE_ID, SMP_ABSOLUTE_SETPOINT, relTarget);
if (result != SM_OK) {
    fprintf(stderr, "Error: Unable to set the target point.\n");
    smCloseBus(bus);
    return EXIT_FAILURE;
}

You could use smRead2Parameters() to combine the first two calls.

1 Like