STM32F103 USB powered AIO simpleFOC board bringup

Yes, I was using KiCad 7.99 for this project (have since gone back since I had a bug with grid sizing). However, I put a .pdf of the schematic in the hardware folder, and you can still open the .kicad_pcb file with KiCad 7.0, so you should still be able to see all the info you need.

edit: I don’t have any 1.5k pullup to 3v3 on D+. I never had to do this with rp2040, atmega32u4, so I am a bit confused why we need this, but I have some of these 0603 in my little pile of parts, so I will tack one on later.

edit: this is to signal that it is full-speed device. I guess it’s built-in the other chips, but maybe since STM32 applications can be more complicated they leave it to the designer to put in the pull-up.

This is a good page with clear information.

1 Like

Wow! That was it! Thank you @JorgeMaker , I already read that link but didn’t think that it applied… a second look was really great.

1.5k to 3.3 on D+ and now it identifies… I will update my schematic to reflect this. I wish D+ and D- was swapped, I need to run a small bus-wire to fix this for each board now instead of just tacking a resistor across…

for anyone curious, it is not mentioned on the chip datasheet, but this STM32 USB app note does mention this, on pg. 12
https://www.st.com/resource/en/application_note/an4879-usb-hardware-and-pcb-guidelines-using-stm32-mcus-stmicroelectronics.pdf

2 Likes

Hmm…
Closed loop seems not go be working right, but I’m not sure what. I have this build flag:

-D SIMPLEFOC_STM32_DEBUG

and in the setup() in code:

SimpleFOCDebug::enable();

But when initializing the motor, the only code dumped to serial log is this:

Reconnecting to /dev/cu.usbmodem6D74228552691    Connected!
MOT: Align sensor.
MOT: Index search...
MOT: Init FOC failed.
Motor initalized. (string inserted by me, that runs at end of setup, it is not initialized)

But this order seems wrong if referring to this page:

I put in a compiler directive to check defined constant MOTOR_CW, then swap U and V phases. When I have it set to clockwise, it produces the above output and will spin smoothly in one or two rotations. If I set it to CCW, then it “fails to notice movement” after index search and moves jerkily back and forth (no full rotation). This was caused by my wonky “I2C / ABZ” shared lines thing that I was trying. Take off the pullup resistor and it spins fine in both directions. Actually, after index search, it will always put the motor in the same orientation, which is a good sign, but it still fails.

Maybe my serial console is connecting too late and missing the first few debug messages…

edit: with delay(1000); in top of setup function after enable debug and create serial interface, it produces the same output. Maybe it’s not waiting?

That’s strange although at least one other user has reported not seeing the STM32 debug messages…

I wonder what’s up? Are you enabling serial and debug right at the start of the setup?

Yes, in my setup() the first line is SimpleFOCDebug::enable() and the following line SerialUSB.begin(), with this swapped it gives the same results. Maybe I should try over STLink serial?

If not using the standard Serial object, it should be:

SerialUSB.begin(115200);
SimpleFOCDebug::enable(&SerialUSB);

It doesn’t make any difference, it produces the same output.
Actually, I think there might be something weird going on with the sensor.

In the SmartKnob discord someone noted that the default resolution of MT6701 is supposed to be 4096cpr but mine seems to be not producing the right amount of pulses. When running this demo code from step 1:

the only PPR resolution that gives me 6.28 rad for one turn is a PPR of 2. I’m going to go poke around with an oscillscope and see what I can find. I tried with a few different magnets, and they all produce the same effect, so I think it’s the sensor.
I might scrap together an I2C driver to read the resolution out too…

?? This is a scope trace of 1 rotation by hand of the motor:

So the resolution is set very low… very strange. This behavior is the same on both boards, the calibration is stored as EEPROM so maybe the person reporting the default resolution had previously programmed it?

I don’t have MT6701 on 5V rail on this board so I might be sunk for programming … it will be an open loop board :slight_smile:

or, it’s an exercise to write the I2C driver…

OK, I’m not sure why, but the default MagneticSensorI2C class does not work right for this sensor.
I think the problem is with how it stacks the angle register bytes. I think the masks might not work right, instead of spending some more time to analyze the issue, I just wrote a little fix.

I managed to make it work, I just modified the function to ‘hard code’ it for this sensor. I just created a duplicate of MagneticSensorI2C but change the class to MT6701_Serial_I2C so that I can keep all the same functions of the regular class.

int MT6701_Serial_I2C::read(uint8_t angle_reg_msb) {
  // read the angle register first MSB then LSB
    byte angle_raw[2];
    uint16_t readValue = 0;
    wire->beginTransmission(chip_address);
    wire->write(angle_reg_msb);
    wire->endTransmission(false);
    wire->requestFrom(chip_address, (uint8_t)2);

    for(byte i=0; i<2; i++){
      // Read the two sequential registers
      angle_raw[i] = wire->read();
    }

    // Stack the upper and lower bits, remove 2 random bits at end.
    // Could be implemented in the regular code like this instead of masking?
    readValue = angle_raw[0] << 8;
    readValue = (readValue | angle_raw[1]) >> 2;
	return readValue;
}

Now the read value stays within 2^14 (and such that getSensorAngle always return within 2pi radians.

And now:

MOT: Align Sensor.
MOT: sensor_direction==CW
MOT: PP Check: OK!
MOT: No current sense.
MOT: Ready.

woohoo!

I moved away from using PlatformIO serial monitor, instead just using screen and discovered that if I connect fast enough, I will see all the debug messages (checking timers, etc). So I think the issue in this case was that since I am using USB serial instead of STlink, it has to create and open the COM port every time, but it’s already started printing stuff to the port by that point, and it just connects too late. When you are using STlink it never has to create/disconnect the port, because the STlink doesn’t reset after programming. I still did not get STlink serial working for this board yet, because I was just happy with USB for now, but I should revisit this.

For tuning now, I did a pretty OK job of this manually. I was hoping to use commander, this is an interesting thread, especially web interface for RTT via STlink:

But actually just by putting -flto as a build flag, I can fit commander on with SerialUSB (within 65kb). I think standard serial should be similar size.
@dekutree64 @Anthony_Douglas @Valentine @runger that might be valuable to you for Lepton use!

edit: on https://webcontroller.simplefoc.com/ it seems like if I scroll the window down for too long ( not viewing the terminal) then something locks up and the motor gives up. Not sure what is going on but it’s a pretty cool way to visualize the motor tuning!

I 3d printed a mounting plate for the backside and frontside, with 1mm spacing from front of MT6701 on the front, and with .1mm spacing from the backside of PCB (~1.7mm from back of MT6701). The motor works on both front and back! Obviously it will depend on your magnet strength but it seems reliable to do magnetic sensing through PCB, you don’t need to place sensor on the backside if your PCB can be placed very near the magnet, like I saw on most designs here. This is great for single-sided assembly! I even have some traces that run very near the rear side of the sensor (no large current ones though).


I think as far as simpleFOC this board is done, now to write some application code and mechanical design… thanks everyone!

2 Likes