Breville
10 mW
Hi everyone--longtime lurker, first time poster. I eventually want to create my own motor controller for an eBike, but have decided to start out learning the fundamentals of motor control using a development board and a motor controller add-on board, in this case an ST Nucleo-F401RE and X-NUCLEO-IHM07M1 combination. I chose these because they were available and because I'm already very familiar with STM32 from other, non-motor control related projects (I mostly use high-end STM32F7 and STM32H7 parts for those applications). I also have a small PMSM motor to use in this project. It's only 15 watts, but I figure with a motor this small I'm not likely to blow up the output MOSFETs on my board. I have the whole thing powered by a lab power supply and have the current limit set to prevent catastrophes. Yes, I know I can buy a motor controller, but I'm doing this as a learning experience.
My first project was to get this motor working in six-step mode. The motor has both Hall sensors and a 1000 count per revolution incremental quadrature encoder with index. This part went really well and I can spin the motor in both directions, ramp the RPMs up and down, and control the whole thing with PID.
My next step was to implement full-blown FOC. I read up on this and have succeeded in getting basic FOC to work with all of the basics (Clarke/Park transforms, space vector PWM, etc.) At this point, I'm running the motor by manually controlling Iq and Id -- I don't have them under PID control yet due to my first issue--current measurement.
The IHM07M1 board has shunt resistors on the low-side of the three output MOSFETs and there are opamps on the board to amplify the voltage drops across the shunts. I'm not an electrical engineer, so I think my first problem is that I'm not using the right gain for the opamps. I say this because when I read the shunt voltages and calculate the currents, they add up to about double what the power supply is showing for the entire board. Here's a diagram of one of the opamps (the other two are the same):
Based on my limited understanding of opamps, I came up with this for the input and output voltages:
Vout = m*Vin + b
where:
m = (R1/(R1+R2))*(1 + R5/R4)
b = Vref * (R2/(R1+R2)) * (1 + R5/R4)
So with the resistor values shown in the schematic, I get:
Vout = 1.5278Vi + 1.5583
Vin = (Vout - 1.5583)/1.5278
Another question: When to measure motor phase currents? Since the shunt resistors are between the low-side MOSFETs and ground, I assume I want to measure current when the low-side MOSFETS are on and the high-sides are off? Is this correct? Right now I'm measuring them at the beginning of a PWM cycle during the t0 time when all three low-side MOSFETs are on. Unfortunately, the STM32F401 only has one ADC, so I'm reading the three phases sequentially.
The current measures seem to have several problems. In addition to adding up to more than the total power output by the power supply, they're very noisy. I mean really noisy! Some of this may be due to my tiny motor drawing very little current (about 75 mA at 1000 RPM) so that it's spanning only a small part of the ADC's input range. I can filter it to make it less noisy, but I'm concerned that this will introduce lag that will affect the FOC calculations.
Another issue with the phase current measurements is that when I use the full form of the Clarke transform (Iαβ0), the "0" term is non-zero most of the time. Since this is a balanced system and the phase currents should sum to zero, I'd expect I0 to be zero (at least most of the time anyway). Is this more likely due to the noise in my current measurements, or an issue with how I'm measuring and calculating the currents?
Another issue I'm having is motor direction. I can only get the motor to spin in one direction. For an FOC implementation using SVPWM, how do I get it to spin the other way? I know this probably should be obvious, but I can't figure it out.
Yet another issue is finding the motor's magnet poles to set the initial angle at startup. Is there a preferred way to do this? At the moment I'm energizing the U-phase high-side MOSFET and the V and W low-side MOSFETs, waiting for the rotor to settle down, and then zeroing the encoder's position. This seems to work much of the time, but sometimes the motor doesn't start spinning--it just gives a little jerk and stops.
Lastly, when I look at the controller's output waveforms on a scope, they look nice and pretty, just like in a textbook, but they always seem to have an 8V DC offset. My power supply maxes out at 16V, so the DC offset of the waveforms seems to sit at exactly half of that. I can vary the peak-to-peak height of the waveforms, but they are always centered at 8V. Is this normal with SVPWM? Will it affect the motor, perhaps making it less efficient? If it's not normal, how do I fix it?
Any help/advice would be greatly appreciated! Sorry for the long, rambling post.
My first project was to get this motor working in six-step mode. The motor has both Hall sensors and a 1000 count per revolution incremental quadrature encoder with index. This part went really well and I can spin the motor in both directions, ramp the RPMs up and down, and control the whole thing with PID.
My next step was to implement full-blown FOC. I read up on this and have succeeded in getting basic FOC to work with all of the basics (Clarke/Park transforms, space vector PWM, etc.) At this point, I'm running the motor by manually controlling Iq and Id -- I don't have them under PID control yet due to my first issue--current measurement.
The IHM07M1 board has shunt resistors on the low-side of the three output MOSFETs and there are opamps on the board to amplify the voltage drops across the shunts. I'm not an electrical engineer, so I think my first problem is that I'm not using the right gain for the opamps. I say this because when I read the shunt voltages and calculate the currents, they add up to about double what the power supply is showing for the entire board. Here's a diagram of one of the opamps (the other two are the same):
Based on my limited understanding of opamps, I came up with this for the input and output voltages:
Vout = m*Vin + b
where:
m = (R1/(R1+R2))*(1 + R5/R4)
b = Vref * (R2/(R1+R2)) * (1 + R5/R4)
So with the resistor values shown in the schematic, I get:
Vout = 1.5278Vi + 1.5583
Vin = (Vout - 1.5583)/1.5278
Another question: When to measure motor phase currents? Since the shunt resistors are between the low-side MOSFETs and ground, I assume I want to measure current when the low-side MOSFETS are on and the high-sides are off? Is this correct? Right now I'm measuring them at the beginning of a PWM cycle during the t0 time when all three low-side MOSFETs are on. Unfortunately, the STM32F401 only has one ADC, so I'm reading the three phases sequentially.
The current measures seem to have several problems. In addition to adding up to more than the total power output by the power supply, they're very noisy. I mean really noisy! Some of this may be due to my tiny motor drawing very little current (about 75 mA at 1000 RPM) so that it's spanning only a small part of the ADC's input range. I can filter it to make it less noisy, but I'm concerned that this will introduce lag that will affect the FOC calculations.
Another issue with the phase current measurements is that when I use the full form of the Clarke transform (Iαβ0), the "0" term is non-zero most of the time. Since this is a balanced system and the phase currents should sum to zero, I'd expect I0 to be zero (at least most of the time anyway). Is this more likely due to the noise in my current measurements, or an issue with how I'm measuring and calculating the currents?
Another issue I'm having is motor direction. I can only get the motor to spin in one direction. For an FOC implementation using SVPWM, how do I get it to spin the other way? I know this probably should be obvious, but I can't figure it out.
Yet another issue is finding the motor's magnet poles to set the initial angle at startup. Is there a preferred way to do this? At the moment I'm energizing the U-phase high-side MOSFET and the V and W low-side MOSFETs, waiting for the rotor to settle down, and then zeroing the encoder's position. This seems to work much of the time, but sometimes the motor doesn't start spinning--it just gives a little jerk and stops.
Lastly, when I look at the controller's output waveforms on a scope, they look nice and pretty, just like in a textbook, but they always seem to have an 8V DC offset. My power supply maxes out at 16V, so the DC offset of the waveforms seems to sit at exactly half of that. I can vary the peak-to-peak height of the waveforms, but they are always centered at 8V. Is this normal with SVPWM? Will it affect the motor, perhaps making it less efficient? If it's not normal, how do I fix it?
Any help/advice would be greatly appreciated! Sorry for the long, rambling post.