SPI Troubles with B-G431B-ESC1 and MA730

I’m trying to use the B-G431B-ESC1 with a MA730 sensor (TBMA730-Q-LT-01A)

I remapped UART2 to UART1 on pins
WEAK const PinMap PinMap_UART_TX[] = {
{PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
WEAK const PinMap PinMap_UART_RX[] = {
{PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},

I changed the SPI pins as follows:
WEAK const PinMap PinMap_SPI_MOSI[] = {
{PB_5, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
WEAK const PinMap PinMap_SPI_MISO[] = {
{PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
WEAK const PinMap PinMap_SPI_SCLK[] = {
{PB_3, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
WEAK const PinMap PinMap_SPI_SSEL[] = {
{PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},

I’ve reviewed the approaches listed here:
https://community.simplefoc.com/t/b-g431b-esc1-beginner-guide-i2c-guide/

When I tried to use the BEMF GPIO pin, the serial output wasn’t right and didn’t change even if I disconnected the sensor. I tried setting the BEMF outputs low and that didn’t make a difference For that reason, I used PC11 instead.

Using the pins listed above, the serial output is always 0.00 (even when I move a magnet near it) but does change if I remove power from the sensor.

I’ve tried quite a few different code approaches such as:

  • MagneticSensorSPI class: MagneticSensorSPI sensor = MagneticSensorSPI(SSEL)
  • MA730-specific driver: MagneticSensorMA730 sensor(PA15)
  • Using SPI.set with SPI.begin to set the SPI Pins
  • Using SPIClass SPI_3(PB5, PC11, PB3); to set the SPI Bus
  • Using sensor.init(&SPI_3); to initialize the sensor on SPI3

I did notice a few inconsistencies such as:

  • The MA730-specific driver page says to use: sensor1.init(SPI2); that returns an error. Instead sensor1.init(&SPI_2) appears to be the correct format.
  • The MA730-specific driver page says to use: MagneticSensorMA730 sensor1(SENSOR1_CS, true, mySPISettings); that returns an error because of the “true, mySPISettings” sections. I’ve only been able to run it with “true, mySPISettings” omitted.
  • MagneticSensorSPIConfig_s doesn’t appear to be compatible with the MagneticSensorSPI sensor when using MA730_SPI. It’s not clear whether that is intentional or not.
  • The MA730-specific driver page says that it gives access to the other registers of the MA730 but the “Here’s how you can use it” section doesn’t provide any examples of how to set the registers.

Any support or guidance would be very much appreciated.

Hi @ben549 , welcome to SimpleFOC!

Thanks a lot for reporting these issues, and sorry they caused so much trouble!

The reason is that I wrote quite a few of these sensor drivers, so I copied the documentation from one to the next, and I didn’t do such a good job of updating it, it would seem.

I’ve corrected all the points you mentioned in the code and they will be fixed in the next release of the library - thanks for this!

you’re right!

The bool parameter ‘true’ is from another sensor, but the settings can be passed in. I’ve corrected the docs.

Really? What’s not working?
You should be able to write something like:

MagneticSensorSPIConfig_s myconfg = {
  .spi_mode = SPI_MODE0,
  .clock_speed = 10000000,  // 10 MHz!!
  .bit_resolution = 14,
  .angle_register = 0x0000,
  .data_start_bit = 15,
  .command_rw_bit = 0,  // not required
  .command_parity_bit = 0 // parity not implemented
};
MagneticSensorSPI sensor = MagneticSensorSPI(myconfg, SSEL);

Does that not compile? Or just not working?

That’s a fair point, and I have now added a couple of examples. But the disclaimers for our drivers library do say it isn’t as well documented or tested… so in this case we expect users to look at the file MA730.h (here on GitHub, or in the library code) and there you will find all the supported functions to get/set the registers…

You mean you changed them in the library files? or you redefined them in your code?
Are you using ArduinoIDE or PlatformIO?

Are you following this guide? B-G431B-ESC1: Beginner guide + I2C guide - #88 by Magneon

using SPI on this ESC board isn’t so easy… they didn’t consider this use case in the design.
So if you have not done so I would urge you to verify that your sensor setup and the code works using another MCU, where you can easily attach the sensor. Once you know it’s working, combine it with the hacks on the G431B-ESC1. Otherwise there’s a lot of “moving parts” to check at the same time.

Do you have an oscilloscope or logic analyser? This will be invaluable in debugging the signals to see what’s going on…

HI! @ben549 and Welcome to the Community.

I can confirm that every MA/MAQ of MPS with SPI bus that i was able to test is working with SimpleFOC SPI Sensor driver.

I personally use three MPS sensors MAQ430, MA710 and MA730

This was tested on

  • Arduino Uno
  • Arduino Mega
  • ESP32’s
  • STM32 F* and G*

MagneticSensorSPIConfig_s myconfg = {
.spi_mode = SPI_MODE0,
.clock_speed = 10000000, // 10 MHz!!
.bit_resolution = 14,
.angle_register = 0x0000,
.data_start_bit = 15,
.command_rw_bit = 0, // not required
.command_parity_bit = 0 // parity not implemented
};
MagneticSensorSPI sensor = MagneticSensorSPI(myconfg, SSEL);

I just tried this using your code and it compiles and runs, maybe I had the order after MagneticSensorSPI incorrect or something.

That’s a fair point, and I have now added a couple of examples. But the disclaimers for our drivers library do say it isn’t as well documented or tested… so in this case we expect users to look at the file MA730.h (here on GitHub, or in the library code) and there you will find all the supported functions to get/set the registers…

That’s awesome! I’ll have to play around with that more. I know this is all opensource so documentation might not be complete. Code isn’t my strong suit so examples are very much appreciated.

set pulses per turn for encoder mode
sensor1.setPulsesPerTurn(999); // set to 999 if we want 1000 PPR == 4000 CPR

This gets added to the setup section, not the loop section. Correct?

You mean you changed them in the library files? or you redefined them in your code?
Are you using ArduinoIDE or PlatformIO?

I’m using the ArduinoIDE. I’ve tried it a few different ways; in the PeripheralPins_B_G431B_ESC1.c
and variant_B_G431B_ESC1.h files and using SPI.set with SPI.begin to set the SPI Pins

Are you following this guide? B-G431B-ESC1: Beginner guide + I2C guide - #88 by Magneon

yes


I did finally get it working. It’s strange, I should be able to use PB4 or PC11 for SPI3_MISO but for some reason, it only works when using PC11. I assume this is a mistake somewhere on my part.

This is ultimately a test setup with the goal of evaluating the STM and MPS chips before making a custom board with the STSPIN32G4 and a MPS sensor. Since the sensor will be reading the rotor magnets, I wanted to be able to test different positions of the MPS sensor and compare the performance to the output from the MPS simulation tool.

1 Like

Do you have any takeaways from those three sensors? Is there one you prefer over the others?

Yes, normally you’d only change it at the beginning and use the value throughout. But you never know what use cases people come up with, so there is no reason you can’t change it during operation as well. But it’s not necessary (or advisable) to call it once per loop iteration!

I think we have a hard to track bug here that might be the cause of your problems. When you declare the variable yourself in this way it always works. But using our pre-defined config seems to cause problems sometimes.

yeah, changing the board files is definately an advanced topic!
As a note, and I am not sure it will work for you, but in theory these PinMaps are defined with “WEAK”. This means you should be able to copy the whole PinMap structure into your sketch (at the top) and remove the “WEAK”. Then you can make changes in your copy in your sketch, and in theory it should prefer the non-weak version of the PinMap.
You can probably even create a file “mypinmap.cpp” in your sketch folder and put it there, to keep things tidy.

Using it is a combination of having the PinMap with the correct assignments of SPI peripherals to pins, and then initializing an SPI object that uses those pins.

Awesome plan! There’s a couple of us here working on designs with the STSPIN32G4, including myself :slight_smile: let us know how it goes!

1 Like

yeah, changing the board files is definately an advanced topic!
As a note, and I am not sure it will work for you, but in theory these PinMaps are defined with “WEAK”. This means you should be able to copy the whole PinMap structure into your sketch (at the top) and remove the “WEAK”. Then you can make changes in your copy in your sketch, and in theory it should prefer the non-weak version of the PinMap.
You can probably even create a file “mypinmap.cpp” in your sketch folder and put it there, to keep things tidy.
Using it is a combination of having the PinMap with the correct assignments of SPI peripherals to pins, and then initializing an SPI object that uses those pins.

That’s pretty cool, I’ll have to give that a try. I was using this code to set the pins at one point.

SPI.setSCLK();
SPI.setMISO();
SPI.setMOSI();
SPI.setSSEL();
SPI.begin();

Awesome plan! There’s a couple of us here working on designs with the STSPIN32G4, including myself :slight_smile: let us know how it goes!

Have you shared your design anywhere? I’ve mostly been using the reference designs for the B-G431B-ESC1, STSPIN32G4, EVSPIN32G4, and MA730 along with the information here:
https://community.simplefoc.com/t/stspin32g4-support/2027

It’s going to be tight since this if for a 35mm OD motor.

Just a quick question, looking at the image you plan to use a motor with a hollow shaft to pass something though. If that’s indeed the case how do you plan to mount the magnetic encoder and its magnet? I think the magnet mounting will need to occlude the hollow shaft which would be a problem if you want to pass something through it.

Ma/maq can be mounted also off axis at cost of resolution