How to use Servos without Servo.h library

Hi, how can I use a Servo without using the Servo.h or the ServoTimer2.h libraries? I'm working on a project on the Arduino Esplora, and I need the Servo to work without the library because of a conflict that it has with another library (PalatisSoftPWM.h). What should I do? Thank you

Do you know why the Servo library has a conflict with your PalatisSoftPWM.h library?

The reason I ask is that writing code to operate a servo without using one of the Hardware Timers is probably not practical.

...R

"multiple definition of _vector_17"

Vector 17 seems to be for Hardware Timer1.

If you were using an Uno I would expect ServoTimer2 to work, but perhaps it does not work with the 32U4 MCU on an Esplora.

Sorry, I don't have any other suggestion.

...R

ok.. is it possible to control a servo without the library?

It is possible to control a servo using direct digitalWrite()s. You need to generate a pulse of between 0.6 and 2.4 microseconds and keep repeating it roughly every 20ms. It's fairly practical if you only need to control a single servo without too much else going on in the Arduino.

Steve

slipstick:
It's fairly practical if you only need to control a single servo without too much else going on in the Arduino.

That's what I intended to convey in Reply #1 - but you have said it more clearly.

...R

There is a motor controlled by two switches and the servo which is controlled by the joystick. The motors are controlled with the PalatisSoftPWM.h library. I need to control the servo like using analogRead(servoPin, xxx); or something like this because of the conflict between the two libraries. I don't know if you need more informations

nicolopadovandev:
I need to control the servo like using

analogRead(servoPin, xxx);

or something

Well you're not going to control anything with a read, so I assume that's a typo and you mean write :wink:

But as pointed out, to control a servo you need a specific width of pulse, and a specific repeat frequency. You can't control that on a pwm pin, which has a frequency of either 490Hz or 980Hz (if my memory's correct) and all analogWrite() does is vary the on-time percentage.

You would need to come up with a scheme of discrete digitalWrite()s to make the pin high, time it to be on for whatever microseconds you need for the position, then go low. Then subtract your on time from the total cycle time, and turn it on again that much later.

You would almost certainly want to make all that timing delay()-less with millis().

nicolopadovandev:
There is a motor controlled by two switches and the servo which is controlled by the joystick. The motors are controlled with the PalatisSoftPWM.h library.

Maybe it would be simpler to find an alternative to the PalatisSoftPWM library. Maybe the regular analogWrite() would be just as good for controlling your motors.

...R

There's a lot of context in the other thread:
http://forum.arduino.cc/index.php?topic=589595

The only broken out hardware PWM pins on the Esplora are on the TinkerKit connectors but nicolopadovandev doesn't currently have an easy way to connect to those pins.

I also suggested an alternative software PWM library and haven't heard back yet on whether that ended up being compatible with the Servo library.

pert:
There's a lot of context in the other thread:

If I had known there was another Thread I would not have wasted my time.

...R

The other thread is about something else: PWM pins
This is on the servo running without library. I don't think that they are the same thing :3

There is nothing at all preventing you from coding this with some cunning use of digitalWrite() and millis():

servo attached.jpg

You might need to cater for the time taken by the digitalWrite() command itself, which according to this adafruit tutorial on a related subject, is 3us.

That may or may not be significant with pulses and intervals up in the order of 1000us.

Thanks

Willpatel_Kendmirez:
cunning use of digitalWrite() and millis():

Actually you would need micros() not millis().

For proof of concept I'm sure you could use delayMicroseconds() and not worry about blocking.

This code shows the concept of moving a servo without the library.

Button on pin 14 (= A0, I just happened to have that available) and servo on pin 10. Press or release button moves servo to the other side. During the while(), the servo gets it repeat pulse on a cycle of 20000.

// https://forum.arduino.cc/index.php?topic=590442

byte servoPin = 10;
byte buttonPin = 14;

void setup()
{
  Serial.begin(9600);
  Serial.println("poor man's servo sweep");

  //turn off L13
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  pinMode(servoPin, OUTPUT);
  digitalWrite(servoPin, LOW);

  pinMode(buttonPin, INPUT_PULLUP);

} //setup

void loop()
{
  Serial.print("one side...");
  while (digitalRead(buttonPin) == HIGH)
  {
    digitalWrite(servoPin, HIGH);
    delayMicroseconds(1900);    //position
    digitalWrite(servoPin, LOW);
    delayMicroseconds(18100);   //balance of 20000 cycle
  }

  Serial.println("other side");
  while (!digitalRead(buttonPin) == HIGH)  //oops... that said HIGH by mistake, no wait, HIGH is correct, I forgot I had the ! there for not
  {
    digitalWrite(servoPin, HIGH);
    delayMicroseconds(1100);    //position
    digitalWrite(servoPin, LOW);
    delayMicroseconds(18900);   //balance of 20000 cycle
  }


} //loop