Troubleshooting Arduino Servo Startup with ServoTimer2 Library

It’s fantastic to hear that the “while” function helped resolve your previous issue! It sounds like you’re making great progress with your Arduino servo project. Now, let’s tackle this new challenge you’re facing with the servo’s startup behavior when using the ServoTimer2 library.

You’re describing a situation where you expect your servo to perform a “cleaning process” – moving from 0 to 180 degrees – every time your Arduino resets. However, it seems to be stubbornly staying in its last position instead. Let’s dive into why this might be happening and explore some solutions to ensure your servo consistently performs the desired startup sequence.

Understanding the Code and the Startup Issue

Here’s the Arduino code you’re currently using, which incorporates the ServoTimer2 and FreqMeasure libraries for servo control based on frequency input:

#include <ServoTimer2.h>
#include <FreqMeasure.h>

ServoTimer2 servo1;
int YPVS = 3;
int angle;          // angle in degrees
int anglem;         // angle in servotimer2 value 750 to 2200
float frequency;
int rpm;
unsigned long Timeout;

void setup() {
  Serial.begin(57600);
  pinMode(YPVS, OUTPUT);
  servo1.write(2200); // called cleaning process, first closes valve to 0 degrees, and then goes full open
  delay(800);
  servo1.write(750);
  delay(800);
  servo1.attach(YPVS);
  FreqMeasure.begin();
}

double sum = 0;
int count = 0;

void loop() {
  if (FreqMeasure.available()) {
    Timeout = millis();
    // average several reading together
    unsigned long value;
    while ((value = FreqMeasure.read()) != 0xFFFFFFFF ) { // clear out all readings in the buffer
      sum = sum + value ;
      count = count + 1;
    }
    if (count > 5) {
      frequency = FreqMeasure.countToFrequency(sum / count);
      rpm = frequency * 60;
      angle = (18. / 500.) * (rpm - 4500.); // equation to find valve position in degrees, based in rpm input

      if (rpm < 1700) {
        angle = 180;
      }
      if (rpm > 1700 && rpm < 4500) {
        angle = 0;
      }
      if (rpm > 9500) {
        angle = 180;
      }
      sum = 0;
      count = 0;
    }
  }
  if ((millis() - Timeout) >= (200)) { // After 200 MS has passed without a reading taking place set angle to 180.
    angle = 180;
  }

  static unsigned long ServoWriteDelayTimer;
  if ((millis() - ServoWriteDelayTimer) >= (20)) { // a 20 ms delay between servo writes should be appropriate
    ServoWriteDelayTimer = millis();
    anglem = 2200 - angle * (145. / 18.); //equation to convert degrees to sertimver2 value
    servo1.write(anglem);
  }

  // Serial print becomes an issue if you try to spam the serail port.
  static unsigned long SpamTimer;
  if ((millis() - SpamTimer) >= (20)) {
    SpamTimer = millis();
    Serial.print("frequency - ");
    Serial.print(frequency);
    Serial.print(" - RPM -");
    Serial.print(rpm);
    Serial.print(" - angleval - ");
    Serial.print(anglem);
    Serial.print(" - Timeout Timer- ");
    Serial.println(millis() - Timeout);
    Serial.println();
  }
}

In your setup() function, you’ve included the commands to move the servo:

servo1.write(2200); // called cleaning process, first closes valve to 0 degrees, and then goes full open
delay(800);
servo1.write(750);
delay(800);
servo1.attach(YPVS);

This code block should indeed command the servo to move to a position corresponding to a value of 2200 (likely close to 0 degrees for many servos, often considered “closed”), pause for 800 milliseconds, then move to 750 (likely near 180 degrees or “fully open”), and pause again before attaching the servo to the specified pin.

The fact that your servo isn’t moving during setup suggests a few potential areas to investigate.

Potential Causes and Solutions for Servo Startup Problems

Here are some reasons why your servo might not be performing the startup sequence in void setup() as expected, along with troubleshooting steps:

  1. Power Supply Issues: Servos, especially larger ones, require adequate power. If the servo isn’t receiving enough power, it might not move reliably, especially during startup when it might be trying to overcome inertia.

    • Solution: Ensure your servo has a dedicated and sufficient power supply. If you’re powering it directly from the Arduino, try using an external power supply that meets the servo’s voltage and current requirements. A separate power supply is often recommended for servos to avoid drawing too much current from the Arduino’s regulator.
  2. servo1.attach(YPVS); Placement: While your code has servo1.attach(YPVS); after the write() commands in setup(), it’s generally good practice to attach the servo before you attempt to control it.

    • Solution: Try moving servo1.attach(YPVS); to the very beginning of your setup() function, before any servo1.write() commands. This ensures the ServoTimer2 library is properly associated with the servo pin before you send any signals.
     void setup() {
       Serial.begin(57600);
       pinMode(YPVS, OUTPUT);
       servo1.attach(YPVS); // Attach servo FIRST
       servo1.write(2200);
       delay(800);
       servo1.write(750);
       delay(800);
       FreqMeasure.begin();
     }
  3. Interference or Code Execution Timing: Although less likely in this simple code, there’s a very slight chance that something else in your code or external factors could be interfering with the execution of the setup() function during reset.

    • Solution: For testing purposes, simplify your setup() function to only include the servo initialization and cleaning process. Comment out FreqMeasure.begin() and Serial.begin(57600); temporarily. This isolates the servo code and helps rule out any potential interference. If the servo works correctly in this simplified setup, you can gradually reintroduce other parts of your code to pinpoint any conflicts.
     void setup() {
       // Serial.begin(57600); // Comment out for testing
       pinMode(YPVS, OUTPUT);
       servo1.attach(YPVS);
       servo1.write(2200);
       delay(800);
       servo1.write(750);
       delay(800);
       // FreqMeasure.begin(); // Comment out for testing
     }
  4. ServoTimer2 Library Behavior (Less Probable): It’s less likely, but there could be a subtle behavior within the ServoTimer2 library itself that’s preventing immediate movement during setup().

    • Solution: Double-check the ServoTimer2 library documentation or examples to see if there are any specific recommendations for startup sequences or initialization. While the provided code should work according to typical servo library usage, reviewing the library’s specifics is always a good step. You could also try a very basic example from the ServoTimer2 library examples to confirm your wiring and basic servo control are working correctly outside of your main project code.
  5. Servo Hardware Issue (Least Probable): While less likely, there’s a very small chance the servo itself might have a minor issue that prevents it from reliably moving at startup, although this is usually accompanied by other erratic behavior.

    • Solution: Test with a different servo if you have one available. This helps rule out the possibility of a hardware problem with the specific servo you’re currently using.

Step-by-Step Troubleshooting

To systematically diagnose and fix the issue, try these steps in order:

  1. Power Check: Ensure your servo has adequate power. Use a separate power supply if necessary.
  2. attach() Placement: Move servo1.attach(YPVS); to the very beginning of setup().
  3. Simplified setup(): Simplify your setup() function as shown in the “Solution 3” code example above.
  4. Basic ServoTimer2 Example: Test a very basic ServoTimer2 example code to confirm basic servo operation and wiring.
  5. Library Documentation: Review the ServoTimer2 library documentation for any startup-related information.
  6. Servo Swap: If possible, test with a different servo.

By systematically working through these steps, you should be able to pinpoint the reason why your servo isn’t performing the startup “cleaning process” and get it working reliably on Arduino reset.

Let me know the results of these troubleshooting steps, and we can further refine the solution!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *