Servo control not working

I have done a search across the internet for info on servo.h Arduino library and my issue but have not found anything that answers my question.

Background:
I am building a larger project for friend to control his project car HVAC unit with an LCD and Arduino Mega. I have completed the full project and been using high torque servos to control the heater temperature and the interior/dash interior lights. The unit has been working well and servos have been responding to inputs but recently stopped working. I have no idea why so I took the core functions from the HVAC code and set up a test project to run the servo to see if I can isolate the issue.

Test code is below and essentially replicates the calls and functionality of the functions I have in the other project.

I created a test bed with 110-6V power reducers per my HVAC unit, and that is confirmed to be running correctly and producing 6 v to the servo per specs.
I connected the output control pin to pin 7 and then pin 9 and then pin 11 on an Arduino Uno so it is confirmed digital output. I also added printouts to see what the values are at each step of the process and al that seems to be wat is expected from the coding.

When I input a 1 into the Serial Monitor, it will read it and confirm the value and when correct, calls the temp_Set() function. In the temp_Set() function, I map the temp input value to servo sweep. In the HVAC code, the sweep values are from 20-86 as the temp door has a fairly small sweep. Map works fine and increments the position value properly.

The code then writes to the servo object per design and the code moves on. For some reason, the write no longer seems to work but there are no outputs from the servo code to confirm whether the write was successful or not. Or at least what I can find.

When testing power output on the pin, I get the value of the servo angle mapped in the line on the signal line.

As an additional item, I found a servo test project that sweeps the servo on the internet and ran that and the servo sweeps per that code base. It uses a for loop though to sweep the servo 180* but uses single angle for the other two tests so it uses both methods to show the functionality. I am using angle method.

Are there different ways to control a servo that is more reliable or different so I can try that?

Any help would be greatly appreciated as I am at a complete loss at this point.

/* Servo test
 by Don O
 March 16 2024
 This code created to test the servo library for another project that manages temperature control with a servo.
 The code receives a specific input (I used a 1 for simplicity in the test) and if it is the correct input, calls temp_Set() function
 temp_Set reads the memory value and if in range, maps the memory value to an angl esweep between 20 and 180 and then writes to the servo motor
 If successful, return success and if not, sends error from temp_Set() back to calling function
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

String temp_Set();
int mem[1] = {19};
String input = "";
String rtn = "";
int tempPos = 0;

Servo tempServo;

void setup() {
  pinMode(11, OUTPUT);  //sets pin 11 to output.  Not sure I need this with attaching myservo below....
  myservo.attach(11);  // attaches the servo object on pin 11
  Serial.begin(9600);
}

void loop() {
 if (Serial.available() > 0){
    input = Serial.readString();
    Serial.println("Input '" + String(input) + "'");

    if (input == "1") {
      Serial.println(String(input));
      Serial.println("mem  < if =" + String(mem[0]));
      // Step the motor in incremnents to reduce by 1 degree C:
      if ((mem[0] >= 19) && (mem[0] < 30)){
        //Increase temperature by 1 degree.
        mem[0] ++;
        Serial.println("mem=" + String(mem[0]));
        rtn = temp_Set();
        Serial.println("Success =" + rtn);
      } else {
        Serial.println("Error =" + rtn);
      }
    } else {
      Serial.println("not entering Up function");
    }
 }
}

String temp_Set(){
  // Step the motor in increments by 1 degree:
  if ((mem[0] >= 19) && (mem[0] <= 30)){
    //increment temperature by 1 degree and servo position
    tempPos = map(mem[0], 19, 30, 20, 180);
    //Move temp servo by mapped increment
    tempServo.write(tempPos);
    delay(20);
    Serial.println("tempPos = " + String(tempPos));
   return "success in Temp_Set";
  } else {
    return "Err temp_Set";
  }
}

Rather than counting inside a loop to move the servo, try creating and adjustable pulse width corresponding to the radians/angle you need. Here is a simulation that creates the pulse using two events. First event begins the pulse, second event ends the pulse at the desired pulse width/angle/radian.

I guess the main problem is
you attached myServo and then try to control

tempServo which is not attached to anything

Here is a WOKWI-Simulation that uses the SafeString-library and the non-blocking SafeString-reader to receive bytes

/* Servo test
  by Don O
  March 16 2024
  This code created to test the servo library for another project that manages temperature control with a servo.
  The code receives a specific input (I used a 1 for simplicity in the test) and if it is the correct input, calls temp_Set() function
  temp_Set reads the memory value and if in range, maps the memory value to an angl esweep between 20 and 180 and then writes to the servo motor
  If successful, return success and if not, sends error from temp_Set() back to calling function
*/

#include <Servo.h>
#include <SafeString.h>
#include "SafeStringReader.h"

// create an sfReader instance of SafeStringReader class
// delimited by space, comma or CarrageReturn or NewLine
// the createSafeStringReader( ) macro creates both the SafeStringReader (sfReader) and the necessary SafeString that holds input chars until a delimiter is found
// args are (ReaderInstanceName, expectedMaxCmdLength, delimiters)
createSafeStringReader(sfReader, 32, " ,\r\n");

cSF(myRcvString, 32);
cSF(myPrintStr, 32);

boolean receivedBytesAndDelimiter;

const byte myServoPin = 11;

byte mem = 19;
byte tempPos = 0;

Servo tempServo;

void setup() {
  Serial.begin(9600);
  Serial.println("Setup-Start");
  tempServo.attach(myServoPin);   // attaches the servo object
  Serial.println();
  Serial.println(F(" Set the Arduino IDE monitor to Newline, or Carriage return or Both NL & CR"));
  Serial.println(F(" See the SafeStringReader_CmdsTimed.ino for an example using a struct to hold the commands and their functions."));

  SafeString::setOutput(Serial); // enable error messages and SafeString.debug() output to be sent to Serial
  sfReader.connect(Serial); // where SafeStringReader will read from
  //sfReader.echoOn(); // echo back all input, by default echo is off
}

void loop() {

  receivedBytesAndDelimiter = sfReader.read();

  if (receivedBytesAndDelimiter) {
    myRcvString = sfReader;
    Serial.print("myRcvString#");
    Serial.print(myRcvString);
    Serial.println("#");
  }

  if (myRcvString == "1") {
    myRcvString = "";
    if ( (mem >= 19) && (mem < 29) ) {
      //Increase temperature by 1 degree.
      mem++;
      myPrintStr  = "mem=";
      myPrintStr += mem;

      Serial.println(myPrintStr);
      temp_Set();
    }
    else {
      Serial.println("mem not between 19 ans 29");
    }
  }
  else {
    //Serial.println("not entering Up function");
  }

}


void temp_Set() {
  // Step the motor in increments by 1 degree:
  if ( (mem >= 19) && (mem <= 30) ) {
    //increment temperature by 1 degree and servo position
    tempPos = map(mem, 19, 30, 20, 180);
    //Move temp servo by mapped increment
    tempServo.write(tempPos);
    Serial.println("tempPos = " + String(tempPos));
    Serial.println("success in Temp_Set");
  }
  else {
    Serial.println("Err temp_Set");
  }
}

Ah for the love of....... :rofl:

A testament to staring at code for too long... Thank you StefanL38 for pointing out the obvious on my test code that I completely missed for way too long... Thanks again on that. Unfortunately for me though, my original HVAC code does actually have the correct servo attaching. I can at least see if the Uno and the test code works and then I would go back into the main HVAC code and also confirm something is not wrong with the Mega....

I will also read through both responses on not using the servo.h library and the reading functions. Both look very interesting.
I very much appreciate the replies folks
Don

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