Motor driver ST IHM08M1 (6PWM)

I’ve dug out my STM32G431 discovery kit for drones after @MrAnderson reminded me that it has an opamp on it. I’d forgotten it had current sensors on the back! The datasheet is worth a read if you are into 6pwm or shunt resistors.

I got put off using this kit last month because it can only be controlled through 6PWM and simplefoc doesn’t support 6pwm yet. I spent an hour tonight and knocked up some simple code to do 6 step commutation as per page6 of this stm application note.

A quick 2 minute video:

And the very simple code (not yet using simplefoc) that I used in the video

#include <Arduino.h>

#define STATUS_LED PC6
#define POT PB12

#define TX PB3
#define RX PB4

#define MOT1_OUT_H PA8
#define MOT2_OUT_H PA9
#define MOT3_OUT_H PA10
#define MOT1_OUT_L PC13
#define MOT2_OUT_L PA12
#define MOT3_OUT_L PB15

#define MOT1_SENSE_H PA1
#define MOT2_SENSE_H PA7
#define MOT3_SENSE_H PB0
#define MOT1_SENSE_L PA3
#define MOT2_SENSE_L PA5
#define MOT3_SENSE_L PB2


HardwareSerial Serial1(RX, TX);

int duty_cycle = 80;

void setup() {
  Serial1.begin(115200);

  pinMode(MOT1_OUT_H, OUTPUT);
  pinMode(MOT2_OUT_H, OUTPUT);
  pinMode(MOT3_OUT_H, OUTPUT);
  pinMode(MOT1_OUT_L, OUTPUT);
  pinMode(MOT2_OUT_L, OUTPUT);
  pinMode(MOT3_OUT_L, OUTPUT);

  pinMode(STATUS_LED, OUTPUT);
  pinMode(POT, INPUT);
}

void setPWM(int m1_h, int m2_h, int m3_h, int m1_l, int m2_l, int m3_l) {
  Serial1.printf("%d\t%d\t%d\t%d\t%d\t%d\t", m1_h, m2_h, m3_h, m1_l, m2_l, m3_l);
  analogWrite(MOT1_OUT_H, m1_h);
  analogWrite(MOT2_OUT_H, m2_h);
  analogWrite(MOT3_OUT_H, m3_h);
  analogWrite(MOT1_OUT_L, m1_l);
  analogWrite(MOT2_OUT_L, m2_l);
  analogWrite(MOT3_OUT_L, m3_l);
}

void steps(int delayMillis) {
  digitalWrite(STATUS_LED, HIGH);
  
  setPWM(duty_cycle, 0, 0, 0, duty_cycle, 0);
  Serial1.println("M2- M1+");
  delay(delayMillis);
  
  setPWM(duty_cycle, 0, 0, 0, 0, duty_cycle);
  Serial1.println("M1+ M3-");
  delay(delayMillis);

  setPWM(0, duty_cycle, 0, 0, 0, duty_cycle);
  Serial1.println("M3- M2+");
  delay(delayMillis);

  digitalWrite(STATUS_LED, LOW);
  setPWM(0, duty_cycle, 0, duty_cycle, 0, 0);
  Serial1.println("M2+ M1-");
  delay(delayMillis);

  setPWM(0, 0, duty_cycle, duty_cycle, 0, 0);
  Serial1.println("M1- M3+");
  delay(delayMillis);

  setPWM(0, 0, duty_cycle, 0, duty_cycle, 0);
  Serial1.println("M3+ M2-");
  delay(delayMillis);

}

int step = 0;

void loop() {
  int pot = analogRead(POT);
  int delaySpeed = map(pot, 0, 1023, 10,500);
  Serial1.println();
  Serial1.print("delay: ");
  Serial1.println(delaySpeed);

  steps(delaySpeed);
}

I coded in platformio using nucleo_g431rb board variant. Not sure if this is also available in arduino IDE. What I don’t know and will have to research is how to safely use 6PWM with proper foc. I suspect the stm32 can be put in some pwm synchronised mode. Phase 1+ pin output is using TIM1_CH1 and Phase 1- is using TIM1_CH1N - so I’m guessing this is a clue as to how to eNsure the stm32 doesn’t open high/low gates at the same time.

1 Like