AS5047P SPI failed

I’m currently using ODrive v3.6.

But I have no idea about how can I use an AS5047P which has a different layout from other’s.

This is my encoder and…

this is the pinout instruction from the manufacture.
unnamed

Can someone help me with wiring this thing and configurating my ODrive?

(I have no budget left. so buying a ODrive S1 can’t be a solution for me.)

Hi! Have you read the docs? Encoders — ODrive Documentation 0.5.6 documentation

1 Like

Yes, I have. But the dump says
“AXIS_ERROR_ENCODER_FAILED”
and
“ENCODER_ERROR_ABS_SPI_COM_FAIL”.

I soldered the
Encoder CS to Odrive GPIO4,
Encoder CLK to Odrive SCK,
Encoder MISO to Odrive MISO,
Encoder MOSI to Odrive MOSI,
Encoder GND to Odrive GND, and
Encoder 5V to Odrive 5V

And I this is what have run :

odrv0.axis0.encoder.config.abs_spi_cs_gpio_pin = 4
odrv0.axis0.encoder.config.mode = ENCODER_MODE_SPI_ABS_AMS
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.save_configuration()
odrv0.reboot()
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

But there a SPI communication error. And The motor never moved during the calibration.

In [33]: odrv0.axis0.error
Out[33]: 257
In [27]: dump_errors(odrv0)
axis0
  axis: Error(s):
    AXIS_ERROR_INVALID_STATE
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_ABS_SPI_COM_FAIL
  controller: no error
axis1
  axis: Error(s):
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_ABS_SPI_COM_FAIL
  controller: no error

After completely turned off and on the power, I got this different error:

In [34]: odrv0.axis0.error
Out[34]: 256
In [35]: dump_errors(odrv0)
axis0
  axis: Error(s):
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_ABS_SPI_COM_FAIL
  controller: no error
axis1
  axis: Error(s):
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_ABS_SPI_COM_FAIL
  controller: no error

Can you send some images of your wiring?

Yes, here’s the picture.

unnamed

Do you have an oscilloscope or logic analyzer? Are you using a ferrite ring on the motor phases?

I’m sorry, I don’t have any of them…
and the motor is directly connected to the ODrive.

Oh I replaced the encoder, resoldered it, erased the configuration, and re configured using this commands :

odrv0.erase_configuration()
odrv0.config.brake_resistance = 2.0
odrv0.config.dc_bus_undervoltage_trip_level = 8.0
odrv0.config.dc_bus_overvoltage_trip_level = 56.0
odrv0.config.dc_max_positive_current = 20.0
odrv0.config.dc_max_negative_current = -3.0
odrv0.config.max_regen_current = 0
odrv0.axis0.motor.config.pole_pairs = 14
odrv0.axis0.motor.config.calibration_current = 5
odrv0.axis0.motor.config.resistance_calib_max_voltage = 2
odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
odrv0.axis0.motor.config.current_lim = 15
odrv0.axis0.motor.config.requested_current_range = 20
odrv0.axis0.encoder.config.abs_spi_cs_gpio_pin = 4
odrv0.axis0.encoder.config.mode = ENCODER_MODE_SPI_ABS_AMS
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.axis0.encoder.config.bandwidth = 1000
odrv0.axis0.config.calibration_lockin.current = 5
odrv0.axis0.config.calibration_lockin.ramp_time = 0.4
odrv0.axis0.config.calibration_lockin.ramp_distance = 3.141592
odrv0.axis0.config.calibration_lockin.accel = 20
odrv0.axis0.config.calibration_lockin.vel = 40
odrv0.axis0.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL
odrv0.axis0.controller.config.vel_limit = 50
odrv0.axis0.controller.config.pos_gain = 30
odrv0.axis0.controller.config.vel_gain = 0.02
odrv0.axis0.controller.config.vel_integrator_gain = 0.2
odrv0.axis0.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ
odrv0.axis0.trap_traj.config.vel_limit = 30
odrv0.axis0.trap_traj.config.accel_limit = 5
odrv0.axis0.trap_traj.config.decel_limit = 5
odrv0.save_configuration()
odrv0.reboot()
odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

Most of the errors disappeared while this processes.

In [1]: odrv0.axis0.encoder
Out[1]:
error = 0x0000 (int)
is_ready = False (bool)
index_found = False (bool)
shadow_count = 0 (int)
count_in_cpr = 0 (int)
interpolation = 0.5 (float)
phase = 0.002684354782104492 (float)
pos_estimate = 0.0 (float)
pos_estimate_counts = 0.0 (float)
pos_cpr = 0.0 (float)
pos_cpr_counts = 0.0 (float)
pos_circular = 0.0 (float)
hall_state = 7 (int)
vel_estimate = 0.0 (float)
vel_estimate_counts = 0.0 (float)
calib_scan_response = 0.0 (float)
pos_abs = 0 (int)
spi_error_rate = 0.0 (float)
config:
  mode = 257 (int)
  use_index = False (bool)
  find_idx_on_lockin_only = False (bool)
  abs_spi_cs_gpio_pin = 4 (int)
  zero_count_on_find_idx = True (bool)
  cpr = 16384 (int)
  offset = 0 (int)
  pre_calibrated = False (bool)
  offset_float = 0.0 (float)
  enable_phase_interpolation = True (bool)
  bandwidth = 1000.0 (float)
  calib_range = 0.019999999552965164 (float)
  calib_scan_distance = 50.26548385620117 (float)
  calib_scan_omega = 12.566370964050293 (float)
  idx_search_unidirectional = False (bool)
  ignore_illegal_hall_state = False (bool)
  sincos_gpio_pin_sin = 3 (int)
  sincos_gpio_pin_cos = 4 (int)
set_linear_count(count: int)
In [48]: dump_errors(odrv0)
axis0
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error

But sometimes, the error ‘AXIS_ERROR_INVALID_STATE’ appears in the axis section.
I tried those commands to verify.

In [25]: odrv0.axis0.encoder.config.phase_offset
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File <ipython-input-25-82bec0f1045f>:1
----> 1 odrv0.axis0.encoder.config.phase_offset

File c:\users\bluej\appdata\local\programs\python\python38\lib\site-packages\fibre\remote_object.py:245, in RemoteObject.__getattribute__(self, name)
    243     return attr
    244 else:
--> 245     return object.__getattribute__(self, name)

AttributeError: 'RemoteObject' object has no attribute 'phase_offset'

In [26]: odrv0.axis0.encoder.config.direction
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File <ipython-input-26-a77ffd9810f9>:1
----> 1 odrv0.axis0.encoder.config.direction

File c:\users\bluej\appdata\local\programs\python\python38\lib\site-packages\fibre\remote_object.py:245, in RemoteObject.__getattribute__(self, name)
    243     return attr
    244 else:
--> 245     return object.__getattribute__(self, name)

AttributeError: 'RemoteObject' object has no attribute 'direction'

Well, It’s not working.
After running this command :

odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE

The dump says this errors :

In [30]: dump_errors(odrv0)
axis0
  axis: Error(s):
    AXIS_ERROR_MOTOR_FAILED
  motor: Error(s):
    MOTOR_ERROR_PHASE_RESISTANCE_OUT_OF_RANGE
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error
axis1
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error

That seems like a normal error for gimbal motor calibration :slight_smile: you will need to change calibration current and voltage. Which motor are you using this with?

1 Like

I’m using a GIM4310. I don’t have much information but here’s the website.
http://shop.smc-powers.com/GIM4310-Motor.html

I’m currently running the ODrive at 14V, but I’d like to go to any higher one like 24V, under 30V.

Is this the 70KV GIM4310 or the 110KV GIM4310?

Oh, sorry again. I had no idea so I measured the resistance between two wires.

I don’t know whether it’s a right method or not, but my multimeter says, It’s 2.7ohm. I think it’s the 110kV one.
(Because the 70kV one has 4.8ohm and the 110kV one has 2.0ohm in the specification.)

Oh after I ran

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

the dump says

axis0
  axis: Error(s):
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_NO_RESPONSE
  controller: no error

and the shadow count is fixed at 0 regardless to my manual rotation.

In [82]: odrv0.axis0.encoder.shadow_count
Out[82]: 0

The ODrive doesn’t says SPI COM ERROR but the encoder is still not responding.

To summarize, When I run encoder offset calibration, the dump says encoder no response,
and when I run axis state full calibration, the dump says motor phase resistance out of range.

I tried the MOTOR_TYPE_GIMBAL and it started to move when I run the calibration. Thank you. :innocent:
(Umm I don’t know how to use the phase_resistance_valid command so annotated it, and don’t know if it a right setting or not. Can you tell me?)

odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_GIMBAL
odrv0.axis0.motor.config.pole_pairs = 14
odrv0.axis0.motor.config.torque_constant = 8.27 / 110
odrv0.axis0.motor.config.phase_resistance = 2.0
# odrv0.axis0.motor.config.phase_resistance_valid = True
odrv0.save_configuration()

But there’s still ENCODER_ERROR_NO_RESPONSE remaining.

In [120]: dump_errors(odrv0)
axis0
  axis: Error(s):
    AXIS_ERROR_ENCODER_FAILED
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: Error(s):
    ENCODER_ERROR_NO_RESPONSE
  controller: no error
axis1
  axis: no error
  motor: no error
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error

ODrive uses phase-neutral resistance not phase-phase resistance so the given phase resistance value should be 1. Otherwise, looks correct.

Do you have an oscilloscope or logic analyzer to debug the SPI communication issues? Did you set odrv0.config.gpio4_mode = GPIO_MODE_DIGITAL ?