Push button for continuous rotation servo

Hello. Thank you for taking your time to look at my problem. I am brand new to software and hardware, with average math skills. Recently picked up Arduino to make animatronics. I have modified a servo (Hitec HS-425BB) to rotate a full a constant 360 degrees, but I would like the servo to start in an off state, and make a push button that starts the servo when pushed and just spins it clockwise, until the button is pushed again and it will stop the servo. I am using a small push button with a 10k resistor. The wiring is right I have checked both independently. Here is the code:

  #include <Servo.h>
int myServo=9;
int buttonPin=A4;
int buttonNewState; //keeps track of changing button state
int buttonOld=1; //where button position started 
int servoState=0; //starting state of servo// wanting it to start in off position
void setup() {
  Serial.begin(9600);
  pinMode(myServo, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  buttonNewState=digitalRead(buttonPin);
  Serial.println(buttonNewState);
  if(buttonOld==0 && buttonNewState==1){
  if (myServo == 0) {
    digitalWrite(myServo, HIGH);
  servoState=1;
  }
  else {digitalWrite(myServo, LOW);
  servoState=0;
}
 buttonOld=buttonNewState;
 delay(50);
}
}

The code complies and uploads but does not work. Blah.

Welcome to the forum. Nice job with the code tags on your first post.

int myServo=9;
if (myServo == 0) {

Not gonna happen.

I think you wanted

if (servoState ==0){

Thank you for the warm welcome, and the speedy reply! Oh goodness. Thank you. You're a gem. That is indeed what I wanted to write. Unfortunately it is still not working. The push button is reading in the serial monitor when the state changes from 1 to 0, and the servo will run on a different sketch. I was originally thinking since I just wanted the servo on and off I could maybe get away with just writing HIGH and LOW for on and off, and attempt to code some type of toggle switch. Now I am wondering if that is not the case and instead it requires some positional calculations to start and stop. I am unsure of how to proceed since I am fairly certain when I modified it I removed it's ability to sense where it's at, so now I don't know how to calculate for its position.

Can you write a sketch that just turns the servo on and off, reliably? No button.

-jim lee

When you say that you want to turn the servo on and off what do you mean ?

Do you mean that the servo should be :

(a) powered or not powered
or
(b) rotating or not rotating
or
(c) something else

Note that you cannot set the position of a continuous rotation "servo", if that matters. You can stop a servo by using the detach() function from the Servo library but it will remain free to move if a load is applied to it

Another consideration is power for the servo. It should be powered separately and not from an Arduino 5V pin due to the current required

Hi,
Can I suggest you google arduino continuous rotation servo

To make a servo stop you would

servo.write(90);
although you may have to trim that 90 value to get exact stop.

-if you use a value lower than 90 then the servo will rotate in one direction, the bigger the difference between your value and 90 will make the servo run faster.

-if you use a value higher than 90 then the servo will rotate in the other direction, the bigger the difference between your value and 90 will make the servo run faster.

Is this the response you want.
Please look at the Servo examples in the IDE to see how to setup the Servo library, in particular

myservo.attach(pinnumber);

Tom... :slight_smile:

Hey everyone thank you so much for all your help and support! Spent some time browsing and found inspiration in the knob sketch on Arduino examples. Where you could use a potentiometer instead of a push button, that way I could control speed, rotation direction and off and on power with a twist. Works way better then the push button. Which I managed to get working but only when I held the button down, also I could not control it's speed so it ran at full power like it was going to fly away.

#include <Servo.h>

Servo my360Servo;  //360 modified servo

int readPent = 4;  // pin for potentiometer
int readVal; //read the value from the analog pin 4
int delay360Servo=16; //servo delay
int delaySerial=100; //serial monitor delay
String msg1= " The 360 servo value is, ";
void setup() {
  Serial.begin(9600); 
  my360Servo.attach(9); // servo attached to pin 9 
}

void loop() {
  readVal=analogRead(readPent);            // reads potentiometer value which is 0 to 1023)
  Serial.print(msg1);                     //prints message in serial monitor
  Serial.println(readVal);                // value viewed in serial monitor after printed message (292 is 
                                             stop, Clockwise at 297, Counter clockwise at 288.
  delay(delaySerial);                     //serial monitor delay
  readVal= map(readVal, 0, 1023, 0, 180);     // scaling potentiometer to use with servo 0 and 180, but 
                                              180 does not matter since with 360 it will continue to spin.  
  my360Servo.write(readVal);                  // writes value to servo 
  delay(delay360Servo);                           //very small servo delay
}

I am glad that you got it working.

Using a pot to control the speed and direction of the "servo" means that there is feedback between the input (the pot turned by the user) and the speed/direction of the servo. Using up/down buttons you could increment/decrement the value written to the "servo" and hence its speed and direction, if you did it properly, which you might like to try as an exercise

Look out for line wrap in your code as it will not compile if copied directly from your post because some of your long comments have strayed into the next line and cause an error when compiling

There are a couple of things that you could tidy up in the code, such as using byte values instead of ints when the value will never be above 255 and the use of Strings (capital S) is discouraged on a microcontroller with very little RAM, although it will not matter for your small sketch. There really is no need to use a String to print your message as you could simply do

  Serial.print("The 360 servo value is, ");                     //prints message in serial monitor

or even better

  Serial.print(F("The 360 servo value is, "));                     //prints message in serial monitor

which puts the string (lowercase s) constant in program memory to save RAM

Why are you delaying between writes to the "servo" when you already have a delay() between prints ?

Hello UkHeliBob,
Thank you for your feedback, I was not aware that a capital S would take up more RAM space. Don't even know much about RAM, or the way the chips work. Still very new. I set a string variable because the Youtuber I watch and learn a lot from is always stressing you should set your variables up top, even when you're new and they're simple, even if the sketch is tiny. That way when you write longer programs if you want to change something you could always just go back up top and change it. I know my program is really tiny but I just trying to practice good habits for if I ever get to a place that I am writing more complex programs, if that makes sense. Silly I know.
As for the delays. I was using the first delay for the time between print lines in the serial monitor (which it does). I have viewed it there.
Meanwhile the second delay I was under the impression I am using it for the time in which the information is to transfer between the reading of the potentiometer to the servo. I thought it might need a small delay to process info. Maybe I assumed wrong.
Edit: Also the comment lines were changed on here, so they could be read, and not cut off. They do not look like that in the code. They are one long line.
And thank you for the exercise recommendation, I will give it a try! :slight_smile:

Kitty, please take my comments in the spirit in which they were intended, ie to provide feedback on different way of doing things. Your sketch does what you want, which is the important thing, and being so small you can get away with what would be regarded as unsatisfactory in a larger sketch

The subject of Strings and strings is much debated here

A String (capital S) is an object created by the String library, which is in itself not a problem. What can become a problem is if you do something like this

String a = "Hello";

then later in the sketch you do

a = "World !";

At first sight there is no problem and, indeed it will work, but what happens behind the scenes is insidious use of memory. String a is initially allocated just enough memory to hold it, so when you change it to something longer it won't fit in the original space so a new memory location is allocated to hold it leaving the original space unused. On a microcontroller with no Operating System to tidy things up, known as garbage collection, the original space may never be used again. Done often enough this can result in running out of memory

As C style string (lowercase s) is an array of characters terminated by a zero. When using them the programmer is in charge of memory allocation, which can be complicated. If you did

char example[] = "Hello";

then exactly 6 bytes of memory would be allocated to hold the string (5 characters plus the terminating zero). C/C++ will not allow you later to do

example = "World !";

which is just as well because there would be no space for the ! and the zero and if you could do it then you would write over the memory allocated to something else

There are, of course, ways to change a C style string but at the heart of them the programmer must allocate enough space for the array to hold the longest string that will ever be used. By doing this you can probably see that changing a string will not leave holes in the memory

Of course, you sketch needs none of this complication but it is something to be aware of if/when your sketches get larger and use more memory

As I said, this is a subject much debated on the forum and elsewhere

Your point about declaring and defining variables at the top of the sketch to allow them to be found and changed easily is a valid one but it impinges on on another memory related subject called variable scope. A variable declared at the start of a sketch has global scope, ie its value is available throughout the sketch, which sounds like a good thing and is generally not a problem with any sketches that you may write.

However, as sketches get bigger and may use components written by others, such as libraries, you may not know the names of the variables used throughout which brings the danger of using or changing a variable holding a value that must not be changed or may have been changed elsewhere in the sketch. To counter this variables can be declared within a block of code which gives it local scope and the memory that it uses (if any) is released when the function ends. Do a search for "variable scope" for more details

Your use of delay() and the reasons for it are interesting. I can understand that you want to slow down the frequency of the Serial.print() but as that already stops the program for 100 milliseconds then delaying a further 16 milliseconds is not going to make much difference to the "servo". The reason why people use a delay() between the movements of proper servos is to slow down their movement by moving in small steps with a time delay between them. Your "servo" is not doing that so the servo delay() is not needed

It almost goes without saying that the use of delay() at all in a sketch is also the subject of debate here but I will not bore you with the details

Good luck with your future projects

Thank you again UkHeliBob,
You have given me much to think about, and read up on, and to improve. Also, I did take your initial comment in good spirit, as constructive feedback. If it appears that I did not, I apologize. I was simply explaining my reasoning behind my decisions, so that you and others who might read this post could better understand my reasoning behind my coding, and be able to provide me with the most accurate feedback based on my thought process. Thank you for you time! :slight_smile:

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