hey, havn’t read all the thread but had a similar problem with stm32f446RE. here is the adc hal code i found somewhere on the forum fix the issue,it is not clean but it works as a first test, basically i chose the adc i want to read the pot with, ensuring it is a different adc than the one used by the current sensing. this way i don’t interfere with the current sensing. works great for me with the aliexpress drv8302 board. in mxadcinit you can change the adc you want to use, and you will have to change the rank also depending on the pin you use and the stm chip, you can probably find it in the datasheet:
// some sytm32duino specific code not important for understanding
// --------------------------------------------------------------------------------------
#ifndef ADC_CLOCK_DIV
#ifdef ADC_CLOCK_SYNC_PCLK_DIV4
#define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV4
#elif ADC_CLOCK_SYNC_PCLK_DIV2
#define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV2
#elif defined(ADC_CLOCK_ASYNC_DIV1)
#define ADC_CLOCK_DIV ADC_CLOCK_ASYNC_DIV1
#endif
#endif /* !ADC_CLOCK_DIV */
#ifndef ADC_SAMPLINGTIME
#if defined(ADC_SAMPLETIME_8CYCLES_5)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_8CYCLES_5;
#elif defined(ADC_SAMPLETIME_12CYCLES_5)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_12CYCLES_5;
#elif defined(ADC_SAMPLETIME_13CYCLES_5)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_13CYCLES_5;
#elif defined(ADC_SAMPLETIME_15CYCLES)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_15CYCLES;
#elif defined(ADC_SAMPLETIME_16CYCLES)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_16CYCLES;
#elif defined(ADC_SAMPLETIME_19CYCLES_5)
#define ADC_SAMPLINGTIME ADC_SAMPLETIME_19CYCLES_5;
#endif
#endif /* !ADC_SAMPLINGTIME */
// --------------------------------------------------------------------------------------
#include <SimpleFOC.h>
#include <SmoothingSensor.h>
#include “wiring_analog_adc.h”
// DRV8302 pins connections
// don’t forget to connect the common ground pin
#define INH_A PA8
#define INH_B PA9
#define INH_C PA10
#define INL_A PB13
#define INL_B PB14
#define INL_C PB15
#define EN_GATE PB3
#define M_PWM PC7
#define M_OC PB6
#define OC_ADJ PA7
#define IOUTA PA0
#define IOUTB PA1
#define IOUTC PA2
#define SIMPLEFOC_STM32_DEBUG
// Motor instance
//BLDCMotor motor = BLDCMotor(7,0.08,200);
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(INH_A,INL_A, INH_B,INL_B, INH_C,INL_C, EN_GATE);
// Hall sensor instance
// HallSensor(int hallA, int hallB , int cpr, int index)
// - hallA, hallB, hallC - HallSensor A, B and C pins
// - pp - pole pairs
HallSensor sensor = HallSensor(PA13, PA14, PA15, 7);
// Interrupt routine intialisation
// channel A and B callbacks
void doA(){sensor.handleA();}
void doB(){sensor.handleB();}
void doC(){sensor.handleC();}
SmoothingSensor smooth = SmoothingSensor(sensor, motor);
//Current sense
LowsideCurrentSense cs = LowsideCurrentSense(0.005f, 12.22f, IOUTA, IOUTB);
// commander interface
Commander command = Commander(Serial);
void onMotor(char* cmd){ command.motor(&motor, cmd); }
int i=0;
ADC_HandleTypeDef hadc2;
void setup() {
pinMode(A5,INPUT);//input pot pin
MX_ADC_Init();//init ADC for potentiometer
Serial.begin(115200);
motor.useMonitoring(Serial);
SimpleFOCDebug::enable(&Serial);
// DRV8302 specific code
// M_OC - enable overcurrent protection
pinMode(M_OC,OUTPUT);
digitalWrite(M_OC,LOW);
// M_PWM - disable 3pwm mode
pinMode(M_PWM,OUTPUT);
digitalWrite(M_PWM, LOW);
// OD_ADJ - set the maximum overcurrent limit possible
// Better option would be to use voltage divisor to set exact value
pinMode(OC_ADJ,OUTPUT);
digitalWrite(OC_ADJ,HIGH);
//SENSOR config
sensor.pullup = Pullup::USE_EXTERN;
//encoder.quadrature = Quadrature::OFF;
sensor.init();
sensor.enableInterrupts(doA, doB, doC);
//motor.linkSensor(&sensor);
// Link motor to sensor
motor.linkSensor(&smooth);
// DRIVER config
// pwm frequency to be used [Hz]
driver.pwm_frequency = 20000;
// power supply voltage [V]
driver.voltage_power_supply = 30;
driver.init();
// link the motor and the driver
motor.linkDriver(&driver);
//motor.voltage_limit=4;
cs.linkDriver(&driver);
// init current sense
if (cs.init()) Serial.println(“Current sense init success!”);
else{
Serial.println(“Current sense init failed!”);
return;
}
// link motor and current sense
motor.linkCurrentSense(&cs);
// choose FOC modulation
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
// aligning voltage [V]
motor.voltage_sensor_align = .5; // default 3V
// set control loop type to be used
motor.torque_controller = TorqueControlType::foc_current;
motor.controller = MotionControlType::torque;
// use monitoring with serial for motor init
// monitoring port
motor.monitor_downsample = 100; // set downsampling can be even more > 100
motor.monitor_variables = _MON_CURR_Q | _MON_CURR_D | _MON_VEL; // set monitoring of d and q currents
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
//motor.foc_modulation = FOCModulationType::Trapezoid_150; //after M2, drv8302 puts motor in fault state
// set the inital target value
motor.target = 0;
motor.disable();
// define the motor id
command.add(‘M’, onMotor, “full motor config”);
Serial.println(“Motor Ready”);
_delay(3000);
}
float value=0;
void loop() {
// iterative setting FOC phase voltage
motor.loopFOC();
// iterative function setting the outter loop target
// velocity, position or voltage
// if tatget not set in parameter uses motor.target variable
motor.move();
// user communication
command.run();
if (i>100){
HAL_ADC_Start(&hadc2);
HAL_ADC_PollForConversion(&hadc2, 1); // polling timeout 1ms - cannot go lower
/* Check if the continuous conversion of regular channel is finished /
if ((HAL_ADC_GetState(&hadc2) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC) {
/##-5- Get the converted value of regular channel ########################*/
value = HAL_ADC_GetValue(&hadc2);
}
HAL_ADC_Stop(&hadc2);
Serial.print(value);
i=0;
}
i+=1;
motor.monitor();
}
int MX_ADC_Init()
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_DIV;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.ScanConvMode = DISABLE;
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.NbrOfDiscConversion = 1;
// this is the important bit
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DMAContinuousRequests = DISABLE;
//nescessaire???
// AdcHandle.State = HAL_ADC_STATE_RESET;
// AdcHandle.DMA_Handle = NULL;
// AdcHandle.Lock = HAL_UNLOCKED;
// / Some other ADC_HandleTypeDef fields exists but not required */
if (HAL_ADC_Init(&hadc2) != HAL_OK) {
return 0;
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLINGTIME;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
/* Configure ADC GPIO pin */
pinmap_pinout(analogInputToPinName(A5), PinMap_ADC);
}