servo's presence on startup hangs sketch

I’ve got a queer problem, whereby if a servo is attached to my sketch on startup - the sketch hangs and doesn’t work.

If, however, I connect the servo after about a minute or so, the sketch works perfectly. Any ideas why this might be?

Thanks!

#include <Bounce.h>
#include <Wire.h>
#include "RTClib.h"
#include <Servo.h>
#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>	// New from IDE 1.0


byte mac[] = { 
  0x00, 0x11, 0x22, 0x33, 0xFB, 0x11 }; 
EthernetClient client;
unsigned int localPort = 8888;             
byte timeServer[] = {
  193, 79, 237, 14};    // ntp1.nl.net NTP server  
const int NTP_PACKET_SIZE= 48;             // NTP time stamp is in the first 48 bytes of the message
byte pb[NTP_PACKET_SIZE];                  // buffer to hold incoming and outgoing packets 
#if ARDUINO >= 100
EthernetUDP Udp;
#endif		
Servo servo1;
#define ledPin1 8      		// the number of the LED pin
#define buttonPin 2		// the number of the button pin
const int pinSpeaker = 7;

int buttonState = LOW;		// used to set the button state
int LedState1 = LOW;		// used to set the LED state
int LedState2 = LOW;	        // used to set the LED state if LED was already on
long LedOnDuration = 10000;	// time to keep the LED on for (10s)
long FlashRate = 400;		// time to keep the LED on for (0.4s)
long previousMillis1 = 0;	// will store last time LED was updated for press 1
long previousMillis2 = 0;       // will store last time LED was updated for press 2

//The pips
unsigned int pip1 = 0;
unsigned int pip2 = 0;
unsigned int pip3 = 0;
unsigned int pip4 = 0;
unsigned int pip5 = 0;
unsigned int pip6 = 0;
unsigned int RTCUD = 0;
unsigned int INITIALSET = 0;
Bounce nursery = Bounce( buttonPin, 500);
int nurseryvalue;

RTC_DS1307 RTC;

enum {
  OFF, ON, FLASH};

void setup() 
{
  pinMode(buttonPin,INPUT);      
  pinMode(ledPin1,OUTPUT);      
  pinMode(pinSpeaker, OUTPUT);
  digitalWrite(ledPin1, OFF);
  servo1.attach(6);
  LedState1 = OFF;
  LedState2 = OFF;
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  Serial.println("Annunciator Panel v0.6");
  Ethernet.begin(mac);	   
  Udp.begin(localPort);
  Serial.println();
  if (! RTC.isrunning()) {
    Serial.println("Error!: The RTC is NOT running/set!");

  }
}

void loop() {
  DateTime now = RTC.now();
  nursery.update(); 
  nurseryvalue = nursery.read();
  unsigned long currentMillis = millis();

  if (currentMillis > 30000 && INITIALSET < 1)
  {
    Serial.println("Time to set the clock initially");
    RTCUD = 1;
  }

  if (now.hour() == 21 && now.minute() == 10 && now.second() == 10)  
  {
    if (RTCUD < 1)  
    {
      Serial.print("Time to set the clock at: ");
      PrintDateTime(RTC.now());
      Serial.println();
      RTCUD = 1;
    }
  }

  if (now.hour() == 21 && now.minute() == 11 && now.second() == 10)  
  {
    if (RTCUD < 1)  
    {
      Serial.print("Time to set the clock at: ");
      PrintDateTime(RTC.now());
      Serial.println();
      RTCUD = 1;
    }
  }


  if (RTCUD == 1)
  {
    Serial.print("RTC before: ");
    PrintDateTime(RTC.now());
    Serial.println();
    sendNTPpacket(timeServer);
    delay(1000);
    if ( Udp.available() ) {

#if ARDUINO < 100
      Udp.readPacket(pb, NTP_PACKET_SIZE);
#else
      Udp.read(pb, NTP_PACKET_SIZE);      // New from IDE 1.0,
#endif	
      unsigned long t1, t2, t3, t4;
      t1 = t2 = t3 = t4 = 0;
      for (int i=0; i< 4; i++)
      {
        t1 = t1 << 8 | pb[16+i];      
        t2 = t2 << 8 | pb[24+i];      
        t3 = t3 << 8 | pb[32+i];      
        t4 = t4 << 8 | pb[40+i];
      }

      float f1,f2,f3,f4;
      f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;      
      f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;      
      f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;      
      f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;
      const unsigned long seventyYears = 2208988800UL;
      t1 -= seventyYears;
      t2 -= seventyYears;
      t3 -= seventyYears;
      t4 -= seventyYears;
      t4 += 1;               
      if (f4 > 0.4) t4++;    
      RTC.adjust(DateTime(t4));
      Serial.print("RTC after : ");
      PrintDateTime(RTC.now());
      Serial.println();
      Serial.println("Time update successful");
      RTCUD = 0;      // RTC has been set for the morning / evening    
      INITIALSET = 1;      // RTC has been set for the morning / evening    
    }
    else
    {
      Serial.println("Error: Time update unsuccessful");
    }
  }


  if (nurseryvalue == HIGH)
  {
    if (buttonState == OFF)
    {
      // button pressed
      //===============
      buttonState = ON;
      if (LedState1 == OFF)
      {
        // the button's pressed and LED is OFF
        // turn it ON
        //====================================
        Serial.println("initial press of button 1 registered @");
        PrintDateTime(RTC.now());
        Serial.println();
        digitalWrite(ledPin1, ON);
        LedState1 = ON;
        servo1.write(180);
        previousMillis1 = currentMillis;
      }
      else if (LedState1 == ON)
      { 		

        //======================================
        digitalWrite(ledPin1, OFF);
        LedState1 = FLASH;
        servo1.write(180);
        Serial.println("second press of button 1 registered @");
        PrintDateTime(RTC.now());
        Serial.println();
        previousMillis1 = currentMillis;	
      }
    }
  }
  else
  {
    buttonState = OFF;
    servo1.write(0);
  }

  if (previousMillis1 + LedOnDuration < currentMillis) 
  {		
    // If the predefined interval has elapsed for the first button press
    // turn led OFF
    //==================================================================
    digitalWrite(ledPin1, OFF);
    LedState1 = OFF;
  }

  if (LedState1 == FLASH && previousMillis2 + FlashRate < currentMillis) 
  {        	
    // If the predefined interval has elapsed for the second button press
    // make the LED 'flash' by toggling it
    //===================================================================
    digitalWrite(ledPin1, !digitalRead(ledPin1));
    previousMillis2 = currentMillis;
  }

  if (now.minute() == 59 && now.second() == 55)  {
    if (pip1 < 1)  {
      pip1 = 1;
      playTone(100, 2000);
    }
  }
  if (now.minute() == 59 && now.second() == 56)  {
    if (pip2 < 1)  {
      pip2 = 1;
      playTone(100, 2000);
    }
  }
  if (now.minute() == 59 && now.second() == 57)  {
    if (pip3 < 1)  {
      pip3 = 1;
      playTone(100, 2000);
    }
  }
  if (now.minute() == 59 && now.second() == 58)  {
    if (pip4 < 1)  {
      pip4 = 1;
      playTone(100, 2000);
    }
  }
  if (now.minute() == 59 && now.second() == 59)  {
    if (pip5 < 1)  {
      pip5 = 1;
      playTone(100, 2000);
    }
  }
  if (now.minute() == 00 && now.second() == 0)  {
    if (pip6 < 1)  {
      pip6 = 1;
      playTone(500, 2000);
    }
  }
  if (now.minute() == 00 && now.second() == 1)  {
    pip1 = 0;
    pip2 = 0;
    pip3 = 0;
    pip4 = 0;
    pip5 = 0;
    pip6 = 0;
  }
}
void playTone(long duration, int freq) {
  duration *= 1000;
  int period = (1.0 / freq) * 1000000;
  long elapsed_time = 0;
  while (elapsed_time < duration) {
    digitalWrite(pinSpeaker,HIGH);
    delayMicroseconds(period / 2);
    digitalWrite(pinSpeaker, LOW);
    delayMicroseconds(period / 2);
    elapsed_time += (period);
  }
}
void PrintDateTime(DateTime t)
{
  char datestr[24];
  sprintf(datestr, "%04d-%02d-%02d  %02d:%02d:%02d  ", t.year(), t.month(), t.day(), t.hour(), t.minute(), t.second());
  Serial.print(datestr);  
}


// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(byte *address)
{
  // set all bytes in the buffer to 0
  memset(pb, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  pb[0] = 0b11100011;   // LI, Version, Mode
  pb[1] = 0;     // Stratum, or type of clock
  pb[2] = 6;     // Polling Interval
  pb[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  pb[12]  = 49; 
  pb[13]  = 0x4E;
  pb[14]  = 49;
  pb[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
#if ARDUINO < 100
  Udp.sendPacket( pb,NTP_PACKET_SIZE,  address, 123); //NTP requests are to port 123
#else
  // IDE 1.0 compatible:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(pb,NTP_PACKET_SIZE);
  Udp.endPacket(); 
#endif	  
}

Hi,
Have you tried using the servo with external power ? it might be that with all of your other hardware connected there is too much current draw during start up. The current demands of the hardware may be less after an initial draw at start up which is why your servo then works.

Just an idea, but it should be easy for you to test with a 9v battery, just make sure that the servo has a common ground connection with you Arduino.

Duane B.

rcarduino.blogspot.com

DuaneB:
Hi,
Have you tried using the servo with external power ? it might be that with all of your other hardware connected there is too much current draw during start up. The current demands of the hardware may be less after an initial draw at start up which is why your servo then works.

Just an idea, but it should be easy for you to test with a 9v battery, just make sure that the servo has a common ground connection with you Arduino.

Duane B.

rcarduino.blogspot.com

Thanks - just tried that - no dice. And considering I have one LED, one buzzer (which hasn’t been doing anything), one switch, one TINY servo and one RTC connected, I wouldn’t have thought that would be too much draw for the USB…

Thanks - just tried that - no dice. And considering I have one LED, one buzzer (which hasn't been doing anything), one switch, one TINY servo and one RTC connected, I wouldn't have thought that would be too much draw for the USB....

Don't forget that the Arduino itself uses power, and the ethernet shield is very power hungry.

PaulS:

Thanks - just tried that - no dice. And considering I have one LED, one buzzer (which hasn't been doing anything), one switch, one TINY servo and one RTC connected, I wouldn't have thought that would be too much draw for the USB....

Don't forget that the Arduino itself uses power, and the ethernet shield is very power hungry.

It's an ethermega.

The same sketch works fine without the servo connected. It also works fine if I connect the servo after (I presume) setup() has run. It [u]doesn't[/u] work if the servo is connected from startup EVEN if the servo is powered from a 9v battery.

Hi, This is worth a quick shot, connect the servo signal wire to Arduino through a resistor, try 330 Omhs, it may well not be the problem, but its one more thing you can easily eliminate.

Sorry for asking this, but you have got a shared earth between the Arduino and Servo ?

Duane B.

rcarduino.blogspot.com

DuaneB: Hi, This is worth a quick shot, connect the servo signal wire to Arduino through a resistor, try 330 Omhs, it may well not be the problem, but its one more thing you can easily eliminate.

Sorry for asking this, but you have got a shared earth between the Arduino and Servo ?

Duane B.

rcarduino.blogspot.com

Appreciate your help, here, Duane.

I don't have a 330ohm resistor but I had a 560 which has helped some. Now the problem is intermittent. And my sketch always hangs when NTP time is queried if the servo is connected...

Would a 330 be better?

Dane: I had a 560 which has helped some. Now the problem is intermittent.

Hmm...I added one on the 5v wire as well (servo still drawing power from Arduino), and now the problem seems to be fixed...however the servo is immobilised. It emits a very low hum for about 5 seconds when I add power and then doesn't lifting a finger.

I guess the 560ohm resistor is too resistful ;) ?

Hi, You definitely don't want one on the 5V, but it might be worth trying a 1K resistor on the signal wire.

Duane.

I'm guessing that the difficulty solving this queer problem is an insufficient number of queers responding.

Let me see if I can help :grin:

I'm going to agree with the earlier assumption that this is a problem with too much power being drawn by EVERYTHING. As an earlier poster mentioned, the ethernet shields and/or boards are power hogs and servos aren't much better. That you had some success with a current limiting resistor tells me that you needed to limit your current (heh). That the problem is synchronous with ethernet activity (the NTP request) confirms it to me.

If you aren't using a 5VDC supply, get one. A 9 volt battery means you're running servo power through the power supply on the Arduino. Bad idea. If you have to use a battery, get a 7805 and wire it up, then a phat filter cap between the servo V+ and V- so the servo doesn't trash the output from the 7805 anyway. Dittos right next to the Arduino. Might help with the ethernet interface power demands.

jfhaugh: A 9 volt battery means you're running servo power through the power supply on the Arduino. Bad idea.

I'm running on USB power. I mean to get an adaptor, but they were out of stock when I bought my board.

Thanks for your help.

Dane:

jfhaugh: A 9 volt battery means you're running servo power through the power supply on the Arduino. Bad idea.

I'm running on USB power. I mean to get an adaptor, but they were out of stock when I bought my board.

Thanks for your help.

That's an even worser idea!

Primary batteries are at least stout current sources. USB, not at all!