Controlling a servo without library

I know there’s a very good servo library for this (which works wonderfully), but for the sake of trying I wanted to see if I could write a sketch myself to control a servo using the Arduino. Of course I couldn’t get it to work, but I don’t understand exactly why it doesn’t work. The servo expects pulses every 20ms (20.000 microseconds), and expects these to go between 900 micros (0 deg) and 2100 micros (180 deg) and ss far as I understand that’s exactly what my arduino does, but I’m obviously missing something here. Can someone please assist?

#define potPin A0  // Pin that goes to potentiometer
#define servoPin 9  // Pin that goes to servo
#define pulseCycle 20000 // Microseconds
#define shortPulse 900 // Microseconds that corresponds to 0 deg
#define longPulse 2100 //Microseconds that corresponds to 180 deg
int pulse; // Length of pulse in microseconds

unsigned long previousMicros = 0;


void setup(){
  pinMode(servoPin, OUTPUT);
  pinMode(potPin, INPUT);
}

void loop(){
  pulse = analogRead(potPin);
  pulse = map(pulse, 0, 1023, shortPulse, longPulse); // Map analoginput to pulsewidth

  while(micros() - previousMicros < pulseCycle) {
    if(micros()-previousMicros < pulse) {
      digitalWrite(servoPin, HIGH);
    }
    digitalWrite(servoPin, LOW);
  }
  previousMicros = micros();
}

Well, for a start, every time you write your servoPin HIGH, you are immediately writing it low again. You are emitting bursts of pulses in the range of megahertz.

Paul__B:
Well, for a start, every time you write your servoPin HIGH, you are immediately writing it low again. You are emitting bursts of pulses in the range of megahertz.

I thought the while-loop did so that when the pin was low it wouldn't be high untill next pulse cycle?

if(micros()-previousMicros < pulse) {
      digitalWrite(servoPin, HIGH);
    }
    digitalWrite(servoPin, LOW);

you are missing an else here.

l

Whatever you imagine it does, it repeats - very fast - comparing the current time with the end of the "pulseCycle". Until that rolls over (20 ms as you specify it, which is OK), each time the "while" is executed, it executes the "if" statement. If that statement matches, it sets the pin high but then having completed the "if" statement, it always sets it low again before the "while" loops again.

Presumably, you meant the "digitalWrite(servoPin, LOW);" to be an "else" condition of the "if" statement.

Even so, continuously re-writing the pin state with the same value, whilst harmless in this case if correctly implemented, is not the sort of thing I would naturally do.

Now on a deeper level, this is "busy waiting" code, the "while" loops prevent you doing anything else. This is more-or-less how the "delay" function executes, as we have been discussing recently, a poor way of coding for just that reason.

It is recommended to study the "Blink without delay" example in the tutorials.

Hi, I know maybe I am replying a bit late, but I was also working on the same topic trying to make servo work without the traditional Arduino Servo lib, so i developed my own quick hands-dirty code and it worked seamlessly on the micro servo sg90, so I turned it into a custom library, you can have a look into it here:

https://github.com/The-King-Slayer/ServoC

Do let me know if this helps. :slight_smile:

The_King_Slayer:
Hi, I know maybe I am replying a bit late, but I was also working on the same topic trying to make servo work without the traditional Arduino Servo lib, so i developed my own quick hands-dirty code and it worked seamlessly on the micro servo sg90, so I turned it into a custom library, you can have a look into it here:

https://github.com/The-King-Slayer/ServoC

Do let me know if this helps. :slight_smile:

Why isn't the servo pin a
a) a byte
b) private ?

(Not that it really matters, because you'll never have more than one instance...)

Well I just developed that code as a one-day hack project, so not much thought has gone inside it, that’s why, but surely I will try to refine it in the future ;D

The_King_Slayer:
Hi, I know maybe I am replying a bit late, but I was also working on the same topic trying to make servo work without the traditional Arduino Servo lib, so i developed my own quick hands-dirty code and it worked seamlessly on the micro servo sg90, so I turned it into a custom library, you can have a look into it here:

https://github.com/The-King-Slayer/ServoC

Do let me know if this helps. :slight_smile:

I finally thought to find my solution for my problem with ladyada's waveshield and a servo.... To bad the link doesn't exist :confused: