logo elektroda
logo elektroda
X
logo elektroda

ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues

madiz08 4188 21
Best answers

How do I correctly read an AS5048A encoder over SPI with an ESP32 so I don’t get only zeros?

To read the AS5048A correctly on an ESP32, you must use the right SPI bus/pins and the AS5048A read sequence: send the command frame with the read bit set, then send a second dummy 0x0000 transfer to clock out the response [#18389303][#18390155][#18409773][#18412478] The original sketch used HSPI by default while the wiring matched the ESP32 VSPI defaults, so the bus/pin mapping had to match the code [#18389303] `beginTransaction()` sets the SPI settings, and `transfer()` sends bytes while returning the received bytes in the same buffer, so SPI is not like I2C with addresses/registers in one step [#18390155] The user eventually got valid readings after tying MOSI permanently to 3.3 V, which puts the AS5048A into read-only mode [#18409773][#18412478] If motor noise still corrupts the data, shield the motor cables too and connect the signal cable shield to ground only on the ESP32 side; grounding the shield on both ends of a measurement cable can turn it into an antenna [#18443203][#18443628][#18445327]
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 18389149
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    I recently bought some AS5048A encoders, communicating with the master over SPI. I assembled a connection like this:

    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .

    and uploaded the example I found:
    Code: C / C++
    Log in, to see the code
    .

    Unfortunately after uploading the code to the ESP32 dev Module, I get the same zeros whether I apply the magnet or not. When I get home with this the first thing I'll check is that I have an SCL signal on the oscilloscope and that I have a low state on pin 27 every second, but I'd also like to ask if maybe something is wrong with the code or pinology?
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
  • ADVERTISEMENT
  • #3 18389552
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    I also tried from HSPI pins before and there was no difference either. At the moment I have shortened the code from the link just to handle HSPI.
    Code: C / C++
    Log in, to see the code
    .
    However, I don't really understand how it works.
    When I was using I2C I knew that first you have to establish a connection, give the address, register address, how many bytes etc....
    With SPI I know that when picking up data from the slave, the CS pin is supposed to be in the low state, SCL is the clock, and MoSI and MISO are something like RX TX.

    In the loop I have a call to the communication function:
    Code: C / C++
    Log in, to see the code
    .
    Could you please explain what is contained in beginTransaction, and what is behind the transfer(stuff) command;

    https://www.mouser.com/datasheet/2/588/AS5048_DS000298_3-00-522570.pdf

    Added after 11 [minutes]:

    I'm looking for information on how to receive two bytes of encoder position information

    Added after 16 [minutes]:


    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    Above I have the position read address, but how do I use this in code to read the contents of the register at address 0x3FFE?
  • ADVERTISEMENT
  • Helpful post
    #4 18390155
    Anonymous
    Level 1  
  • #5 18409524
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    I was about to give up on it. I tried it on UNO and MEGA and got zero readings. Finally, using the link:
    https://forum.arduino.cc/index.php?topic=155238.0
    I noticed that MOSI is permanently connected to 3V3 and suddenly everything started to work. Below I am uploading the ready-to-read AS5048A on ESP32
    Code: C / C++
    Log in, to see the code
    .
    Thanks for the links to the SPI, a lot of news it gave me
  • Helpful post
    #6 18409773
    Anonymous
    Level 1  
  • #7 18410863
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    Of course I would like to be able to program it, or a more apt word is to be able to. I would be most interested in setting the zero position. I understand the Transfer function as sending the appropriate byte, and in response the function returns a response in place of that byte.
    I don't understand why this response comes after sending two bytes with a value of 0? I know the value is 14-bit, so we are not looking at the two oldest bits, but why are we sending 0?
    Is it not really a 0, just the first byte of the array?
    The register address I'd like to read the position from is 0x3FFE. I thought it would work on the principle that I split this value into two bytes, add a 1 to the older one in the 15th bit to let it know it's a read, and send that to the encoder. I've also tried Transfer(Val16), but also nothing.
  • ADVERTISEMENT
  • #8 18412039
    Anonymous
    Level 1  
  • #9 18412478
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    I now understand everything. Tracing
    Code: C / C++
    Log in, to see the code
    made everything clear to me. That is, we send the appropriate command + a 1 in front and then send 0 as a read. I had sent the former before, but didn't know that you then have to send a 0 to get the response. I'm ordering 6-wire shielded cables and when they arrive I'll try to fit these encoders to my robot instead of the AS5600. I hope that if they are connected directly to the ESP32 there will be no interference.
    Thank you.
  • #10 18413850
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #11 18415794
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    the one from the furthest axle 180cm
  • #12 18429302
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    Today I soldered the encoders to the shielded cable
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .

    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    and I temporarily connected 2 of the 5 encoders on a test basis in a "3 Wire Mode (read only)" connection.
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    Tomorrow or the day after tomorrow (if I don't have trips at work), I will try to assemble the encoders on the individual axes and see how it works.
    I'm just asking for input on whether this kind of reading is optimal?
    Code: C / C++
    Log in, to see the code
    .

    Code: C / C++
    Log in, to see the code
    .
  • #13 18429426
    Anonymous
    Level 1  
  • #14 18442128
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    Today I quietly connected everything, separated the 5V control voltage from the motors supply voltage. After switching on the control and moving the axes freely, 0 reading errors, but unfortunately after switching on the power supply to the motors automatically erroneous readings.
    Well, I don't know where the interference comes from anymore. The same encoders are used in professional applications by Boston Dynamisc who use them in their motors doing such wonders:
    https://www.youtube.com/watch?v=NR32ULxbjYc
    Perhaps my problem is that the encoders and magnets are not in a metal box forming a Faraday shield and the magnetic field of the motors affects their reading, or perhaps the ESP32 itself is too susceptible to interference.
    Overall communication with AS048A resolved, but it's a shame not with positive results :) .
  • #15 18442596
    Anonymous
    Level 1  
  • #16 18442881
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    Well, an oscilloscope indeed! Unfortunately it is of the lower regiment, but it shows something:

    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    Above, the MISO signal at intervals with the engines switched off

    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues
    and here approximately. Unfortunately my oscilloscope does not give a full view of the whole frame
    Below please see what the signal looks like when the power supply is switched on:
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    and approximately:
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    I am also sending a short video where it is shown what it looks like before and after the engines are switched on.



    https://www.youtube.com/watch?v=qlD52KkkEK8&feature=youtu.be if the video does not fire
    I have in the program that if the reading is 300 position units higher or lower than the previous reading, it is supposed to fire an error with an alarm. Sreial.print here has no effect on anything. I tried controlling the robot without serial and also position errors unfortunately.
    I'm having a temporary problem flipping pictures from my phone, but on the picture with the previous I2C multiplexer it looked similar:
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    Now there is a board where the shielded encoder wires are plugged in and connecting all of them:
    +Vcc
    GND to which the shield is connected
    MISO
    SCK
    these 4 above wires at the output of the board go about 10cm by wires to the ESP32. Each CS wire also goes loosely to the ESP32. I won't be able to do any more today as I'm leaving the house, but tomorrow I'd like to try hooking up the encoder board to an Arduino Mega with a read only program uploaded and see if it's the same. Thanks for the hint with checking the signal on the oscilloscope
  • #17 18443036
    Anonymous
    Level 1  
  • Helpful post
    #18 18443203
    Slawek K.
    Level 35  
    Posts: 3015
    Help: 259
    Rate: 1299
    The motor cables should also be shielded, a subject well known from 3D printers, for example, where the proximity of motor cables and e.g. tap wires caused the stop to be switched on due to the interference generated.


    Regards
  • #19 18443422
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    This is how it looks when it comes to the encoder wires
    Regarding the motor cables, I somewhat regret that I did not use shielded cables right away. If it would have helped then I will definitely replace them with shielded ones.
    I'm about to get round to switching everything over to reading the position from the Arduino Mega, just out of curiosity as to whether changing the microcontroller here will have any effect on the correctness of the reading.
  • #20 18443628
    Anonymous
    Level 1  
  • #21 18443662
    madiz08
    Level 14  
    Posts: 517
    Help: 4
    Rate: 172
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    I quickly assembled something like the one above and it's the same, admittedly now only misreading from one encoder (I'll ditch it later), but there it is.

    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues .
    ESP32 SPI with AS5048A Encoder: Troubleshooting Connection and Code Issues

    SCK signal seems ok, CS signals are 100% perfect. Regarding the MISO, I wonder why the signal doesn't drop instantly to zero after readings, but often goes down slowly to ground potential.
    I have the MOSI pin on the Arduino side unconnected

    Added after 2 [minutes]: .

    I see, I will also try disconnecting the screen from the encoder side

    Added after 4 [hours] 32 [minutes]:

    Hmmm... All I did was isolate the screen from ground at each encoder according to the guidelines and to my surprise (as I've always been told the screen should be wherever it goes) complete lack of erroneous readings. I typed in the code to count the erroneous readings and display the status of this counter every second and for over an hour the counter status was 0, also great, thank you for such a guideline. For now I have this result for the Arduino Mega, tomorrow I'll try to get the wires in order in conjunction with the ESP32 and hopefully eventually get the robot "driving" :) .
    But I'm puzzled as to why isolating the ground from the shield at the encoder resulted in better interference cancellation?
  • #22 18445327
    Anonymous
    Level 1  

Topic summary

✨ The discussion revolves around troubleshooting issues with the AS5048A encoder connected to an ESP32 via SPI. The user initially faced problems with the encoder not providing readings, despite following example code and wiring diagrams. Key points included the need to ensure correct SPI bus configuration (VSPI vs. HSPI), proper handling of the MOSI pin, and the importance of sending a zero byte after the command to receive data. The user discovered that interference from motors affected readings, leading to erroneous outputs. Solutions discussed included using shielded cables, isolating the ground connection of the shield, and ensuring proper SPI transaction handling. Ultimately, the user achieved successful communication with the encoder after addressing these issues.
Generated by the language model.

FAQ

TL;DR: 1 MHz bus, 14-bit(16 384 counts) angle, and “shield on both ends acts like an antenna” [Elektroda, khoam, post #18445327] → unground the encoder side to erase read errors. Field test: 0 faults in 60 min after change [Elektroda, madiz08, post #18443662]

Why it matters: Simple wiring tweaks often fix SPI dropout without changing code.

Quick Facts

• ESP32 VSPI pins 18/19/23/5; HSPI pins 14/12/13/15 [Elektroda, khoam, post #18389303] • AS5048A uses SPI Mode 1, up to 10 MHz (tested stable at 1 MHz) [AMS Datasheet, 2019][Elektroda, madiz08, post #18409524] • Angle resolution: 14-bit (0–16383) [AMS Datasheet, 2019] • Read-only mode when MOSI > 2 V (tied high) [Elektroda, khoam, post #18409773] • Shielded cable ≤ 1.8 m works when grounded one side only [Elektroda, madiz08, post #18415794][Elektroda, khoam, post #18443628]

What ESP32 pins should I use to talk to an AS5048A over SPI?

For the default VSPI bus connect SCLK → GPIO 18, MISO → 19, MOSI → 23, and CS → 5. If you prefer HSPI, use SCLK 14, MISO 12, MOSI 13, CS 15 [Elektroda, khoam, post #18389303]

Which SPI mode and clock rate work reliably with the encoder?

Set SPI MODE1 (CPOL = 0, CPHA = 1). The thread shows clean transfers at 1 MHz; the datasheet allows up to 10 MHz, but noise margin falls above 5 MHz on long cables [AMS Datasheet, 2019][Elektroda, madiz08, post #18409524]

How do I read the 14-bit angle from register 0x3FFE?

  1. Pull CS low.
  2. transfer16(0xBFFE) → dummy, raises read bit.
  3. Pull CS high, then low again and call transfer16(0x0000). Mask result with 0x3FFF and right-shift two bits: angle = (data & 0x3FFF) >> 2 [Elektroda, madiz08, post #18429302]

What do beginTransaction() and transfer() actually do?

beginTransaction() locks the SPI bus and applies SPISettings: clock, bit order, data mode [Elektroda, khoam, post #18390155] transfer() sends a byte/word while simultaneously reading the returned byte/word; transfer16() handles two bytes. Data replace the buffer you pass in “like a full-duplex shift register.” [Arduino Ref].

Can I connect five encoders to one ESP32?

Yes. Share the MISO, MOSI, and SCLK lines. Give each encoder its own CS pin and toggle them one at a time. The posted loop reads five devices in ≈0.5 ms at 1 MHz without loss [Elektroda, madiz08, post #18429302]

How should I shield and route the cables?

Use twisted, shielded 6-wire cable. Connect the shield to ESP32 ground only; leave the encoder end floating. Keep SCLK away from motor wires and add 100 nF decoupling at each sensor. "One-ended shielding stops interference currents" [Elektroda, khoam, post #18445327]

Can I still program the encoder if MOSI is high?

No. High MOSI (> 2 V) puts the AS5048A into Read-Only mode. Pull MOSI low through the ESP32 pin and issue write commands (bit 15 = 0) to change zero position or AGC settings [Elektroda, khoam, post #18409773][AMS Datasheet, 2019].

Is there a ready-made library for Arduino or ESP32?

Yes. The open-source AS5048A library on GitHub handles read, write, and CRC checking. It supports ESP32 and simplifies angle reads to one call [GitHub eborghi10/AS5048A][Elektroda, khoam, post #18412039]

Edge case: what if MISO floats?

A floating MISO line injects random bits, producing angles that jump hundreds of counts. Always enable the ESP32’s internal pull-up or add a 10 kΩ resistor to 3.3 V when the bus is idle [Elektroda, madiz08, post #18442881]

3-step how-to: read angle in 25 µs

  1. hspi.beginTransaction(settings);
  2. digitalWrite(CS, LOW); uint16_t val = hspi.transfer16(0);
  3. digitalWrite(CS, HIGH); hspi.endTransaction(); angle = (val & 0x3FFF) >> 2;
Generated by the language model.
ADVERTISEMENT