Controlling direction of continuous servos over serial.

I want to be able to control the direction of a servo with serial input from the keyboard.

Such as: As long as I am pressing w move servo up
If pressing s move servo down
if pressing none of these do not move servo

The code I am using currently drives continuously in the specified direction . That is that I cannot hold the button and make it move and let go and make it stop.

Here is the code I am working with

#include <Servo.h>



Servo leftServo;
Servo rightServo;
char input;


void setup()
{
  Serial.begin(9600);
  leftServo.attach(9);
  rightServo.attach(10);
}



void loop()
{
  if (Serial.available() > 0)
  {
   input = ' ';
    input = Serial.read();
    if (input == 'w')
    {
      leftServo.write(170);
      
    }
    else if (input == 's')
    {
      leftServo.write(10);
     
      
    }
  }
}

What are you using to send the key-presses?

Oh I forgot to mention they I have a feeling that may be the issue. I was using the terminal monitor in the IDE but realized that it may be causing my problem. I tried using putty but I can't establish a connection or type anything. Not sure why :/

Assuming "the keyboard" is attached to a pc, then generally speaking you will need to write an application for the pc to monitor key presses, generate the desired data, and send it out the serial port to the arduino. There are other approaches, but if a pc is involved, you will have to do some work there.

The serial monitor won't transmit continuous key presses. Which OS are you using?

No I have to keep pressing enter in the arduino IDE. I am using Windows 7.

What problems are you having with putty?

When I choose the COM port the window comes up but it doesn't allow me to enter anything. I also double checked to make sure command echo was on and still got nothing. As of now my code doesn't support a stop state. As far as it knows it is either going CCW or CW.

I got putty to work now. I just cannot figure out how to make my code turn the motors as long as I have the key pressed and if I don't just keep them in position

Well, the key repeat rate will not be as fast as the serial line can transmit - are the ex=servos stuttering on and off?
Would a simple timeout work?

No they don’t shutter. Basically when I start the program the servos will be off. If I enter W they rotate one way. They will continue rotating that way until I press S which will make the servos immediately rotate the other and then the behavior is the same as the W state.

What if I flushed the serial data so nothing was there and if nothing is there detach the servo. Then if there is serial data there (a W or S) reattach and write to it?

No, flushing serial is almost never a good idea. What you need to do is send three different values - one for rotation in one direction, one for rotation in the other direction, and one for stop.

Basically, you are telling the servo to go left or go right, but never telling it to stop.

You could make it stop automatically after so many seconds of no input. Whether that is reasonable, or not, depends on what the servo motion is accomplishing.

While thinking about this, I adapted your loop function to make a solution that is simple, and wrong! To save you from the same mistake, here it is:

void loop()
{
if (Serial.available() > 0)
  {
  input = Serial.read();
  if (input == 'w')
    {
    leftServo.write(170);
    }    
  else if (input == 's')
    {
    leftServo.write(10);
    }
  }
else
    leftServo.write(90); //Stop may not be exactly 90, tweak as necessary
}

The problem, as AWOL and PaulS alluded to is that serial comms is slow, so even if puTTy is sending continuous 's' characters, in between each one arriving, there will be nothing available for a considerable number of iterations of loop and the code above will tell the servo to stop. It'll probably cause nasty jitter or twitching around the stopped condition. It would help to know more about what you're trying to do, but unless you really need to react to continuous keystrokes (as a learning exercise perhaps) PaulS' three character solution is simple and has the advantage over mine in that it would work.

While thinking about this, I adapted your loop function to make a solution that is simple, and wrong!

Well, it’s only wrong in that it stops immediately after all serial data is consumed. If you started a timer when there was no serial data, and stopped the motor after some reasonable time, that might be useful.

Depends on the as-yet-unexpressed needs of OP.

lawlmayne: That is that I cannot hold the button and make it move and let go and make it stop.

The only way you're going to get that to work WELL, is by writing a custom app on the PC that will allow you to respond to not just a keypress, which is inadequate to the task, but keydown and keyup events. That way you can send the appropriate start command on a keydown, and the appropriate stop command on a keyup. Terminal apps won't give you the capabilities you need to get that effect. You can attempt to emulate it with key repeat and timeouts, but it won't be nearly as smooth and responsive as a program responding to keydown and keyup events.

I'm also having problem with mine but i have a custom remote control that when i push a button it lets the servo move to a certain direction then it would stop when i unpressed the button.