Failing to use D5 D6 & D9 pins to control ESC/Motor, only works with D10

Hello,
I am trying to run a motor through an ESC on an arduino UNO or NANO. The ESC is connected either to D10, D9, R6 or D5. I can only master the motor speed on D10 (same behavior on UNO and NANO, no other pin works). The ESC is connected to the arduino on GND & D10 (or D9, D6, D5). I use the servo library to choose the speed.
I tried both write (with speed between 0 & 180) & writeMicroseconds (with speed between 1000 and 2000). Both code bring the same expected behavior on D10 and failing on D5, 6 or 9. You can also see I use a wifi connection to the controler, I would think this does not matter.
The ESC is also connected to a battery. Initialization sequence (with expected beeps) only happens on D10. On D5, D6 or D9, I get beeps every second or so, indicating failure.
If anyone could help to get the ability to run on any of D5, D6, D9 (or other) pins as I intend to run 4 motors.
Thank you

Here is the code

#include <SPI.h>
#include <RF24.h>
#include <Servo.h>

#define pinCE   7             // On associe la broche "CE" du NRF24L01 à la sortie digitale D7 de l'arduino
#define pinCSN  8             // On associe la broche "CSN" du NRF24L01 à la sortie digitale D8 de l'arduino

#define pinPwmNW 5
#define pinPwmNE 6
#define pinPwmSE 9
#define pinPwmSW 10
#define thrustMin 0
#define thrustMax 180

// WIFI
RF24 radio(pinCE, pinCSN);

// ESC & MOTOR
Servo mtrNW, mtrNE, mtrSE, mtrSW;
int impulse = thrustMax;

const byte adresse[6] = "YLDRN";       // Mise au format "byte array" du nom du tunnel

struct {
  unsigned int forward, backward, right, left, up, down, clockwise, counterclockwise; 
} msgToDrone;

void setup() {
  // point pour le moteur
  mtrNW.attach(pinPwmNW, thrustMin, thrustMax);
  mtrNW.attach(pinPwmNE, thrustMin, thrustMax);
  mtrNW.attach(pinPwmSE, thrustMin, thrustMax);
  mtrNW.attach(pinPwmSW, thrustMin, thrustMax);
  mtrNW.write(impulse);
  mtrNE.write(impulse);
  mtrSE.write(impulse);
  mtrSW.write(impulse);

  // Initialisation du port série (pour afficher les infos reçues, sur le "Moniteur Série" de l'IDE Arduino)
  Serial.begin(9600);
  Serial.println("NRF24L01 recepteur");

  // Partie NRF24
  if( radio.begin() )
    Serial.println("radio hardware responding");
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(0, adresse);
  radio.startListening();
}

void loop() { 
  // On vérifie à chaque boucle si un message est arrivé
  if (radio.available()) {
    radio.read(&msgToDrone, sizeof(msgToDrone));                     // Si un message vient d'arriver, on le charge dans la variable "message"

    char txt[256];
    sprintf(txt, "spd %d fwd %d, bwd %d rgt %d lft %d", msgToDrone.up, msgToDrone.forward, msgToDrone.backward, msgToDrone.right, msgToDrone.left);
    Serial.println(txt);  // … et on l'affiche sur le port série !

    // Conversion de la vitesse en ms
    impulse = map(msgToDrone.up, 0, 1023, thrustMin, thrustMax);
  }

  // Envoi du signal de commande à l'ESC
  mtrNW.write(impulse);
  mtrNE.write(impulse);
  mtrSE.write(impulse);
  mtrSW.write(impulse);
}```

Welcome to the forum

The Servo library prevents the use of PWM on pins 9 and 10 on the Uno and Nano

See Servo - Arduino Reference

Hello,
Thanks, however I tried with pin 3, 5 & 6 and only pin 6 lets one motor run. On 3 & 5 the ESC/motor continuously beeps every one second.
Do you have any other hint ?

Hello,
I removed the SPI/RF24 usage from the code, and the problem is still the same: only pin6 is enabling driving a servo. 3 & 5 are not letting the ESC/Motor run. So I'd think that there is no conflict between SPI/RF24 & Servo.
Has someone already been successful in running 2, 3 or 4 ESC/Motor on nano or uno ?

First you wrote that only pin 10 works, but one day later you changed your mind:

What did you changed that cause the moving of "the only working pin" from 10 to 6?

Hello,
Initially I thought using only PWM pins for the ESC/motors. only one was working and I tryied all ESC/Motor combination to conclude that only pin 10 was letting ESC/motor working. Then UKHeliBob pointed out that Servo library prevents the use of pin 9 & 10. So I excluded pin 9 and 10 from use. which in the PWM list leaves only 3, 5 & 6 as available. Among these 3, 5 & 6 pins, only 6 would let the ESC/motor run. searching for answers on the community I found some comments that all digital pins can be used. I tried, however that does not give other ESC/motor working. If pin 10 is in use, no other digital works, if pin 10 is not in use, only pin 6 works.
Since then I also read that analog pins could be used. That will be my next try.
I hope this clarifies,

It looks like the only one motor can be used with your code, regardless the pin used. I think it means a bug in the code. I don't see another explanation.

So I also tried analog pins A0 to A3. none is working.
about the code... it's the only difference is the pin number. I apply the same functions and the same values otherwise, as shared in the initial post.
in summary, initialization sequence

#define pinPwmNW A0
#define pinPwmNE A1
#define pinPwmSE A2
#define pinPwmSW A3
#define thrustMin 1000
#define thrustMax 2000

and the setup sequence

  mtrNW.attach(pinPwmNW);
  mtrNW.attach(pinPwmNE);
  mtrNW.attach(pinPwmSE);
  mtrNW.attach(pinPwmSW);

  mtrNW.write(impulse);
  mtrNE.write(impulse);
  mtrSE.write(impulse);
  mtrSW.write(impulse);

and then the loop sequence

  mtrNW.writeMicroseconds(impulse);
  mtrNE.writeMicroseconds(impulse);
  mtrSE.writeMicroseconds(impulse);
  mtrSW.writeMicroseconds(impulse);

I don't believe there is a code issue: the same code would be working on one pin and not the other ?

Following up on the above issue, I found following posts:
1/ about using PWM pin
2/ and this one about servo & 9°
3/ and this one about servo and uno R4
Not sure if this is related, I might give it a try and install the Servo fix, or buy a Mega,

This is the first time I see you mention an Uno R4, which is a totally different beast from an Uno R3. So which Uno did you try, and which Nano. There are also several completely different incompatible Nanos around.
Leo..

1 Like

The Uno I have is coming from the starter kit: a R3. About the Nano, it's a nano "only". It has no extension.

Tried the fix from the Servo library mentioned above. I still cannot run more than 1 ESC/motor. Anyone has a track to follow ?
Thanks

Are the Arduino and ESC grounds connected? Post a complete wiring diagram, and a link to the ESC.

Hi @perreve

If this is a quadcopter project (?) then it's better to drive the ESCs using the Arduino analogWrite() function rather than the Servo library.

On the Uno/Nano (R3) analogWrite() generates 490Hz PWM outputs on digital pins D3, D9, D10 and D11.

In the early days of drone development, it was common to operate at a higher 490Hz frequency rather than driving ESCs at the standard 50Hz. This increased update rate would cause the ESC's digital input filter (that at that time was configured for fixed wing or heli model aircraft) to converge on the desired motor speed more quickly, thereby making the multi-rotor more responsive.

A little later these standard ESCs were improved by reflashing them with multi-rotor specific Simon K or BLHeli firmware, but still at 490Hz. This was then followed by a quick succession of new ESC protocols that replaced 490Hz PWM with Oneshot125, Oneshot42, Multishot and DShot. Nowadays, are are countless drone specific ESC designs that can support a range of these protocols.

490Hz PWM is the easiest to implement using analogWrite(), provided your ESCs still support it? I guess they should do, seeing as you mention that one is working on D10 at 50Hz.

@jremington, yes arduino and ESC are ground connected. Find wiring diagram:
IMG_20240528_0001.pdf (231,3 Ko)
Here are the ESC, and motor
Thanks for your time,

As the analogWrite() function has only 8-bit resolution, it's necessary to map and constrain the input from 0 to 2000µs to 0 to 255, for example:

motorOut1 = map(motorOut1, 0, 2000, 0, 255);  // Map the output
motorOut1 = constrain(motorOut1, 0, 255);     // Constrain the output
analogWrite(9, motorOut1);                    // Output the PWM duty-cycle on D9 at 490Hz

@MartinL, thanks a lot, not all clear yet to me, but I could make 3 engines turn on pin 3 9 & 10. I need to figure out which one can be used for the 4th engine (5 & 6 are different frequencies and 11 is used for wifi).

Hi @perreve

On the Uno/Nano (R3), you've only got four 490Hz PWM pins, so you'll require D11 if you need a 4th motor.

It's not possible to change the PWM frequency on digital pins D5 and D6 without adversely affecting the Arduino timing functions: millis(), micros() and delay().

The advantage of using analogWrite() is that the PWM outputs are generated directly by the hardware timers (1 & 2) and once configured, operate independently from the CPU. This means that their outputs run like clockwork at the specified duty-cycle, irrepective of the CPU's workload, thereby allowing the motors to run smoothly at a given speed.

Hi @MartinL
As I need a 4th motor, I'll get a mega and use analogWrite.
Thanks for all,

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.