Servos - power up anomaly

Further update.

In the above example PIN 4 goes to 5v on power up and stays that way. It also causes a small "twitch" in the servo if it is connected.

However, if I energise the input pin with 5v it goes to 0, shows a brief low voltage then goes to zero and stays zero unless I energise it again. The energising causes the code in the sketch to "turn the servo" which it does.

PIN 3 starts at 0 and stays low unless energised.

Why do these pins behave differently?

Hi,

Can anyone shed any light on this problem please? I am at a loss to know what to try next

Thanks

David

See what kind of signal levels you get using this modified version of your sketch. I've removed all the servo.detach instructions, servo's like to have a continuous signal to hold their position correctly.

#include <Servo.h>

//constants
const byte InputPins[] = {11, 12, 13, A0, A1, A2, A3, A4};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte EndPositions[2] = {75, 105};
const byte BounceAngles[] = {7, 0, 3, 0, 1};
const byte MovementDelay = 30;
const byte BounceDelay = 180;

//Variables
Servo servo[NrServos];
bool previousButtonStates[NrServos];

void setup() {
  for (byte i = 0; i < NrServos; i++) {
    pinMode(InputPins[i], INPUT);       // set pins to INPUT
    servo[i].attach(ServoPins[i]);
    servo[i].write(EndPositions[0]);       // move servo to DOWN position
    delay(2 * BounceDelay);
    //servo.detach(); //no need to detach servo
  }
}

void loop() {
  for (byte i = 0; i < NrServos; i++) {
    //const bool State = digitalRead(InputPins[i]); //should not be declared as a constant
    bool State = digitalRead(InputPins[i]);
    if (State != previousButtonStates[i]) {
      previousButtonStates[i] = State;
      //servo.attach(ServoPins[i]); // not needed, servo was not detached

      for (byte pos = EndPositions[!State]; pos != EndPositions[State];(State ? pos++ : pos--))
      {
        servo[i].write(pos);               // move servo to position in variable 'pos'
        delay(MovementDelay);           // wait for the servo to reach the position
      }

      //make the servo 'bounce'
      for (byte n = 0; n < sizeof(BounceAngles); n++) {
        servo[i].write(EndPositions[State] + (State ? -1 : +1) * BounceAngles[n]);
        delay(BounceDelay);
      }
      //servo.detach(); //no need to detach servo
    }
  }
}

rynd2it:
To further test this I plugged a servo into pin 5 and energised it and it moved according to the program but I observed that the 'L' light on the ATMega (next to the PWR light) came on - but not on any other pin.

The board you are using appears to be the Funduino Nano expansion board. The 'L' light on a Nano is connected to pin 13, which you are using as the switch input for the servo on pin 5. If the switch is pulling the input to 5v, the light will come on.

david_2018:
The board you are using appears to be the Funduino Nano expansion board. The 'L' light on a Nano is connected to pin 13, which you are using as the switch input for the servo on pin 5. If the switch is pulling the input to 5v, the light will come on.

Thank you David I will try the revised sketch, and the explanation of the 'L' light makes total sense.

I'll report back tomorrow when I have tried the revised sketch

david_2018:
See what kind of signal levels you get using this modified version of your sketch. I've removed all the servo.detach instructions, servo's like to have a continuous signal to hold their position correctly.

#include <Servo.h>

//constants
const byte InputPins[] = {11, 12, 13, A0, A1, A2, A3, A4};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte EndPositions[2] = {75, 105};
const byte BounceAngles[] = {7, 0, 3, 0, 1};
const byte MovementDelay = 30;
const byte BounceDelay = 180;

//Variables
Servo servo[NrServos];
bool previousButtonStates[NrServos];

void setup() {
  for (byte i = 0; i < NrServos; i++) {
    pinMode(InputPins[i], INPUT);      // set pins to INPUT
    servo[i].attach(ServoPins[i]);
    servo[i].write(EndPositions[0]);      // move servo to DOWN position
    delay(2 * BounceDelay);
    //servo.detach(); //no need to detach servo
  }
}

void loop() {
  for (byte i = 0; i < NrServos; i++) {
    //const bool State = digitalRead(InputPins[i]); //should not be declared as a constant
    bool State = digitalRead(InputPins[i]);
    if (State != previousButtonStates[i]) {
      previousButtonStates[i] = State;
      //servo.attach(ServoPins[i]); // not needed, servo was not detached

for (byte pos = EndPositions[!State]; pos != EndPositions[State];(State ? pos++ : pos--))
      {
        servo[i].write(pos);              // move servo to position in variable 'pos'
        delay(MovementDelay);          // wait for the servo to reach the position
      }

//make the servo 'bounce'
      for (byte n = 0; n < sizeof(BounceAngles); n++) {
        servo[i].write(EndPositions[State] + (State ? -1 : +1) * BounceAngles[n]);
        delay(BounceDelay);
      }
      //servo.detach(); //no need to detach servo
    }
  }
}

I uploaded this sketch to my test board and found that the signal levels are in fact slightly different. I no longer see the 5v high on pins 4 & 5, instead on power up there is a tiny (< 1v) signal which then got to 3v and stays there. When I operate the pin, I see a rise in the voltage to approx 3.8v. The servo operation seems unaffected by these changes BUT I still see a power-up "twitch" when the 10k resistor is removed.

Tomorrow I will upload this sketch to the problem board with 6 servos and observe the results.

Thanks for the help so far

David

Hi,
What are you using for the 12V to 5V regulator?

Thanks.. Tom.. :slight_smile:

TomGeorge:
Hi,
What are you using for the 12V to 5V regulator?

Thanks.. Tom.. :slight_smile:

I wish I could give a good answer for that but I have two small circuit boards that take 12v in and put 5v out. They were provided by the person who originally created this project. As I am nowhere near it at the moment maybe this picture might give a clue?

12v_5v.jpg

Hi,
That looks like a linear regulator.
12v_5v.jpg
Rather than a SMPS type.
Does the heatsink on the PCB get hot?
Can you read the part number on the component bolted to the heatsink?

Have you monitored the 5V with a DMM when you are testing your project?

Where is the 12V supply coming from?

Thanks.. Tom.. :slight_smile:

TomGeorge:
Hi,
That looks like a linear regulator.
12v_5v.jpg
Rather than a SMPS type.
Does the heatsink on the PCB get hot?
Can you read the part number on the component bolted to the heatsink?

Have you monitored the 5V with a DMM when you are testing your project?

Where is the 12V supply coming from?

Thanks.. Tom.. :slight_smile:

All questions I will attempt to answer tomorrow. The 12 v supply is a small transformer, I have two, one of which is used to provide power for LEDs on the layout.

If I monitor the 5v what should/should not be seen?

What is the purpose of the delay () in setup? I would try commenting that out so the servo signals will start up faster.

david_2018:
What is the purpose of the delay () in setup? I would try commenting that out so the servo signals will start up faster.

I have no idea - as I said I didn't write it. I will try and comment out and see what happens though.

There is another problem in setup, the servos are all being set to the same initial position, but you should be reading the switch inputs and setting the initial position based on that.

Give this sketch a try, it will read the switch inputs during setup and set the servo's initial position based on the switch, instead of setting all servos to the same initial position.

#include <Servo.h>

//constants
const byte InputPins[] = {11, 12, 13, A0, A1, A2, A3, A4};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte EndPositions[2] = {75, 105};
const byte BounceAngles[] = {7, 0, 3, 0, 1};
const byte MovementDelay = 30;
const byte BounceDelay = 180;

//Variables
Servo servo[NrServos];
bool previousButtonStates[NrServos];

void setup() {
  for (byte i = 0; i < NrServos; i++) {
    pinMode(InputPins[i], INPUT);       // set pins to INPUT
    servo[i].attach(ServoPins[i]);
    byte State = digitalRead(InputPins[i]);
    if (State == LOW) {
      servo[i].write(EndPositions[0]); // move servo to DOWN position
    } else {
      servo[i].write(EndPositions[1]); // move servo to UP position
    }
    previousButtonStates[i] = State; //record initial state of input pin
    //delay(2 * BounceDelay);
    //servo.detach(); //no need to detach servo
  }
}

void loop() {
  for (byte i = 0; i < NrServos; i++) {
    //const bool State = digitalRead(InputPins[i]); //should not be declared as a constant
    bool State = digitalRead(InputPins[i]);
    if (State != previousButtonStates[i]) {
      previousButtonStates[i] = State;
      //servo.attach(ServoPins[i]); // not needed, servo was not detached

      for (byte pos = EndPositions[!State]; pos != EndPositions[State]; (State ? pos++ : pos--))
      {
        servo[i].write(pos);               // move servo to position in variable 'pos'
        delay(MovementDelay);           // wait for the servo to reach the position
      }

      //make the servo 'bounce'
      for (byte n = 0; n < sizeof(BounceAngles); n++) {
        servo[i].write(EndPositions[State] + (State ? -1 : +1) * BounceAngles[n]);
        delay(BounceDelay);
      }
      //servo.detach(); //no need to detach servo
    }
  }
}

david_2018:
Give this sketch a try, it will read the switch inputs during setup and set the servo's initial position based on the switch, instead of setting all servos to the same initial position.

#include <Servo.h>

//constants
const byte InputPins[] = {11, 12, 13, A0, A1, A2, A3, A4};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte EndPositions[2] = {75, 105};
const byte BounceAngles[] = {7, 0, 3, 0, 1};
const byte MovementDelay = 30;
const byte BounceDelay = 180;

//Variables
Servo servo[NrServos];
bool previousButtonStates[NrServos];

void setup() {
  for (byte i = 0; i < NrServos; i++) {
    pinMode(InputPins[i], INPUT);      // set pins to INPUT
    servo[i].attach(ServoPins[i]);
    byte State = digitalRead(InputPins[i]);
    if (State == LOW) {
      servo[i].write(EndPositions[0]); // move servo to DOWN position
    } else {
      servo[i].write(EndPositions[1]); // move servo to UP position
    }
    previousButtonStates[i] = State; //record initial state of input pin
    //delay(2 * BounceDelay);
    //servo.detach(); //no need to detach servo
  }
}

void loop() {
  for (byte i = 0; i < NrServos; i++) {
    //const bool State = digitalRead(InputPins[i]); //should not be declared as a constant
    bool State = digitalRead(InputPins[i]);
    if (State != previousButtonStates[i]) {
      previousButtonStates[i] = State;
      //servo.attach(ServoPins[i]); // not needed, servo was not detached

for (byte pos = EndPositions[!State]; pos != EndPositions[State]; (State ? pos++ : pos--))
      {
        servo[i].write(pos);              // move servo to position in variable 'pos'
        delay(MovementDelay);          // wait for the servo to reach the position
      }

//make the servo 'bounce'
      for (byte n = 0; n < sizeof(BounceAngles); n++) {
        servo[i].write(EndPositions[State] + (State ? -1 : +1) * BounceAngles[n]);
        delay(BounceDelay);
      }
      //servo.detach(); //no need to detach servo
    }
  }
}

The switches are all set to OFF before power up, it won't have any effect

rynd2it:
The switches are all set to OFF before power up, it won't have any effect

Did you try it.
It will set all the servos to the switch OFF position, rather than random movement.
The code will attach a servo, read the switch and set the servo to the switch position, before it has a chance to move elsewhere.
Then do the next servo, etc etc etc.
You need to look at how this bit of code works and what it will do in an attempt to remove your glitch.
The other problem is you have not written or developed this code so you along with us have to learn how it works.
Thanks.. Tom.. :slight_smile:

TomGeorge:
Did you try it.
It will set all the servos to the switch OFF position, rather than random movement.
The code will attach a servo, read the switch and set the servo to the switch position, before it has a chance to move elsewhere.
Then do the next servo, etc etc etc.
You need to look at how this bit of code works and what it will do in an attempt to remove your glitch.
The other problem is you have not written or developed this code so you along with us have to learn how it works.
Thanks.. Tom.. :slight_smile:

I tried it on my test rig - as I suspected it made no difference, neither did commenting out the delay.
I put the meter on the pin before power up both before & after the above changes and the pin never goes high until I set the operating switch to on.

Without the 10k resistor on the servo line ( +v and signal) the servo kicks several degrees on power up and then as soon as the sketch runs it sets to the required position - in all cases this is DOWN. It makes no difference if (with power off) I manually move the servo well away, it kicks a few degrees then moves to the DOWN position. With the 10k resistor it does not kick but this is not true on another board with 6 servos.

The mount of the initial kick does seem to vary between servos (or Nano shield boards) and in some cases this causes the servo to jam against it's internal stop or another servo arm. A tiny kick would be ok but a 30 degree (or more) would destroy my semaphore signals.

I will put the modified code on to the other boards this evening and see if it makes any difference there. More tomorrow

Thanks again

David

rynd2it:
All questions I will attempt to answer tomorrow. The 12 v supply is a small transformer, I have two, one of which is used to provide power for LEDs on the layout.

If I monitor the 5v what should/should not be seen?

Your 12v power supplies should be more than JUST a 12V transformers....
Do they have rectifiers and filter/smoothing capacitors.?
You should look to see if the 5V supply drops at any stage.
Thanks.. Tom... :slight_smile:

TomGeorge:
Your 12v power supplies should be more than JUST a 12V transformers....
Do they have rectifiers and filter/smoothing capacitors.?
You should look to see if the 5V supply drops at any stage.
Thanks.. Tom... :slight_smile:

Here's what is fitted into the control boxes - mainly for LEDs, tap off for the 5v regulator

Hi
Are you trying to power your contoller and servo with a LED power supply?

Neuftech 2.5A DC 12V 30W LED Transformer Power Supply 12V LED Driver Transforme for DC 12V Strip Light Bulbs


I think that may be some of your problem, they are not designed for servo type loads.
Tom... :slight_smile: