Ticking on ESP32 but not ATMEGA2560

Hi All

I have been working with SimpleFOC for a while now to develop a custom PCB motor. After a few iterations I’m getting closer to what I want but ran into an issue that I have been struggling with. I have the following boards ArduinoMega2560 and ESP32 and DRV8311H. Running my code on the Arduino works exactly as I want with no issues. However the same code on the ESP32 produces a clicking sound. The time between clicks is dependent on the target velocity. I bought a cheap oscilloscope to try and diagnose the issue further but I’m not sure I’m using it properly. I plan to move to a STM32 chip in the future but I worry that this issue will continue. My question for the clever folks out there: what differences between the ATMEGA2560 and ESP32 could be causing this discrepancy? I tried the driver pwm frequency setting at both 40k,32k, and 400hz with no luck. Thank you in advance.

// Open loop motor control example
#include <SimpleFOC.h>




// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(11);
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(11, 10, 9, 8);//Arduino pins
//BLDCDriver3PWM driver = BLDCDriver3PWM(25, 26, 27, 33);//ESP32 pins
//BLDCDriver3PWM driver = BLDCDriver3PWM(PA10, PA9, PA8, PA11);



// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6,  8);


//target variable
float target_velocity = 3.0;

float reverse = 1.0;
//Start timer to follow millis()
unsigned long myTime;
//Create point to start a duration
unsigned long resetTime;
//Time since last reset point
unsigned long duration;

//Create floating point time variable
float timer;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }

void setup() {

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 5;
  // limit the maximal dc voltage the driver can set
  // as a protection measure for the low-resistance motors
  // this value is fixed on startup
  driver.voltage_limit = 5;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);
  driver.pwm_frequency = 500;//added this to try and fix the issue, did not help
  // limiting motor movements
  // limit the voltage to be set to the motor
  // start very low for high resistance motors
  // current = voltage / resistance, so try to be well under 1Amp
  motor.voltage_limit = 5;   // [V]
 
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

  // add target command T
  command.add('T', doTarget, "target velocity");
  command.add('L', doLimit, "voltage limit");

  Serial.begin(115200);
  Serial.println("Motor ready!");
  Serial.println("Set target velocity [rad/s]");
  _delay(1000);

  myTime = millis();
}

void loop() {

  // open loop velocity movement
  // using motor.voltage_limit and motor.velocity_limit
  // to turn the motor "backwards", just set a negative target_velocity
  myTime = millis();
  //convert time to floating point
  //timer = myTime*1.0;
  duration = myTime - resetTime;
  timer = duration*1.0;
 target_velocity = 0.5;

//  if(duration < 15000)
//   {

//     //Use floating point timer to increase target velocity
//     target_velocity = 4.5*(timer/15000.0)*(reverse);
//   }
//   if(duration>30000 && duration<45000)
//   {
//     target_velocity = 4.5 * (reverse);
//   }
//   if(duration>45000)
//   {
//     target_velocity = 0;
//     reverse = reverse * (-1.0);
//     resetTime = millis();
//     //target_velocity =4.5 - (4.5*((timer-45000.0)/30000.0));


//   }

  motor.move(target_velocity);

  // user communication
  command.run();
  Serial.println(target_velocity);
  //Serial.println(reverse);
}

There was a recent over-flow issue, could that be it? Every time some internal counter overflows, you hear a clicking. Reason is probably difference in the internal esp32 and atmega number formats.

I’m citing from memory, could be wrong. It’s annoying but harmless. I think @runger fixed it, or may be that’s a new one?

Cheers,
Valentine

Did you set lib_archive=false build flag? this is required for the PWM hardware to be selected properly, that could by why changing the PWM frequency did not adjust anything for you.

Hi. Unfortunately I still have my “Arduino IDE” training wheels on. Are build flags a feature of PlatformIO? Is it possible to achieve the same thing using Arduino IDE?

Hi. The ticking is important since the project will hopefully wind up on my desk in a quiet office. Any sounds would be noticeable.

Hi @Rosewill2 !

Please remove the print statement from your main loop - does that affect the sound?

1 Like

Heh heh heh… didn’t see that.

Cheers,
Valentine

Hello @runger

Unfortunately not. The sound is still present. However I did notice that unplugging coils individually changed the sound. All 3 motor windings connected to the driver produced the fastest clicking. Only 2 motor windings connected produced a slower clicking. 1 motor winding connected produced no clicking. It is not anything to do with the rotation. I can get the clicking sound just buy holding a single magnet on top of a coil with my finger.

Ok, I’d hoped that would be the cause of the clicks, you can’t print once per main loop iteration, it will cause blocking IO and slow things down.

This sounds really bizarre… could you share a video perhaps?

Here we go…

Cheers,
Valentine

2 Likes

I tried my best to get a video of the offending ESP32 clicking. The video is hard to hear but I managed to isolate it better with audacity. Here is the YouTube link to the videoVideoLink. Clicking happens at 0:30. I tried to isolate and amplify the audio the best I could. I also attached the waveform output from audacity. I think that the bars seen at regular intervals show the clicking.

Oh wow, I’m really baffled by this one also.

To recap:

  • it’s a self made axial flux motor
  • it runs on ATMega without sound
  • on ESP32 it develops clicking as above
  • the clicking only happens in the presence of a magnet

The clicking sounds to me like it’s of a mechanical nature, like as if the stator PCB is vibrating on the table? Because the PCB is light, maybe it’s lifting itself off the table?

Does it go away when you tape it down?

But why is it only happening with the ESP32?

Which board definition are you using for this MCU board?

-Yes. I am on my 3rd prototype. I tried to design for 5v and 1 amp.

-Much less sound at least. There is still some whining with the ATMEGA. But it is much quieter.

-Yes. I am using the board I linked earlier. I use almost the exact same code except for new pin definitions

-There is no sound at all when the magnet is removed. Disconnecting a motor wire from the PCB has the effect of slowing the rate of clicking. Disconnecting a second wire removes the clicking entirely since the circuit cannot close now.

-I can still get the sound when holding the PCB in my hand. I think any sounds are between the magnet and the PCB not the table. I am holding the magnet to the PCB quite firmly. I don’t think it is strong enough to jump around under my finger.

-I would like to try it on STM32. Unfortunately I misjudged the file size and cannot upload to my board with limited flash.

-I am using the Esspressif board library “ESP Dev Module”

I would like to try changing the PWM frequency to see if that changes anything. A previous comment from “VIPQualityPost” seems to imply that I missed a step when trying this previously. Unfortunately I am not familiar with the use of build flags. I assumed that I could just include the line “driver.pwm_frequency = 500;” into my setup to change the frequency. I am not sure if it is working properly and the oscilloscope I bought doesn’t seem up to the task.