Arduino pushbutton servo rotation

Would I need to put in an else between the two if statements? I didn’t think I needed one because the switches are independent of each other, meaning that one switch doesn’t need the other to perform its own command. Then again I am probably wrong.

Nope, you are correct, the else is not needed. The test on position already makes the 2 cases mutually exclusive (it can’t be at 0 and 90 at the same time).

That does make you wrong about being wrong though … :think:

here is some more code I just wrote, let me know how it looks. I have an idea of what you are talking about regarding the “little bug”.

#include <Servo.h>
int button1 = 4;
int press1 = 0;
int button2 = 5;
int press2 = 0;
servo servo1;
int pos = 0;

void setup()
 {
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(9);
  Serial.begin(9600);

 }

void loop()
 {
  if ( (digitalRead(button1) == HIGH) && (pos == 0) )
   {
    for (pos = 0; pos <= 90; pos +=1)
     {
      servo1.write(pos);
      Serial.println(pos);
      delay(20);
     }
   }

  if ( (digitalRead(button2) == HIGH) && (pos == 90) )
   {
    for (pos = 90; pos >=0; pos -=1)
     {
      servo1.write(pos);
      Serial.println(pos);
      delay(20);
     }
   }
 }

I used your idea and moved the digitalRead into the if (), that will work right?

As for the “little bug”, does it have to do with the int pos =0 in the beginning? I was thinking that the line assigns it to 0, and then each if statement reassigns it to either 90 or 0. So should it be an equal to (==) in the for statements. I won’t be able to run it in the IDE until later so I don’t know if this code is going to compile.

You have 1 typo (caps matter!) but otherwise it should work. And if it doesn’t, the “printed” pos data should tell you why.

I would recommend that you actually command/write to the servo and put it to it’s initial position, pos = 0. Right now the servo only gets commanded after a button push.

The bug was the = vs == in the if(…) statements.

Beware of accidentally using the single equal sign (e.g. if (x = 10) ). The single equal sign is the assignment operator, and sets x to 10 (puts the value 10 into the variable x). Instead use the double equal sign (e.g. if (x == 10) ), which is the comparison operator, and tests whether x is equal to 10 or not. The latter statement is only true if x equals 10, but the former statement will always be true.

I wrote in notepad, so I didn’t notice that I missed the caps. I may get a chance to try it on the uno tonight. If I do I will post how it worked (or not ). I’ve never tried the serial monitor before, when it prints the line will it stay on the screen long enough to see what the code is doing or will it disappear before I can read it?

Wheeler exactly would I command/ write the pos position to 0? Isn’t that being done in the first half of the first for statement?

jc27:
Isn’t that being done in the first half of the first for statement?

Yes, but what happens before any button is pressed ? Can you guarantee where the servo will point once it gets power but before either button is pressed ?

jc27:
Wheeler exactly would I command/ write the pos position to 0?

It can't be in your loop(), as presently written. It would conflict w/the 'button' code. It really only needs to happen once, after power-up and before any button pushing. Where in your code, now, will a servo.write() (or anything else) only happen one time ?

http://arduino.cc/en/Tutorial/BareMinimum

Ok it should go in the void setup() then right? And the wheeler was a typo, I’m using my phone and it’s easy to fat finger stuff.

Bingo !

Yeah! Now I just need to try it. I will rewrite the code with that in it and post it later. I probably won’t get a chance to try it out tonight but definately this weekend. Thank you so much for the help, I really can’t stress how much you helped me out. Thank you. If it doesn’t work I will post it here as well.

Here is the newest code

#include <Servo.h>
int button1 = 4;
int press1 = 0;
int button2 = 5;
int press2 = 0;
Servo servo1;
int pos = 0;


void setup()
 {
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(9);
  Serial.begin(9600);
  servo1.write(10);
  

 }

void loop()
 {
  if ( (digitalRead(button1) == HIGH) && (pos == 10) )
   {
    for (pos = 10; pos < 100; pos +=1)
     {
      servo1.write(pos);
      Serial.println(pos);
      delay(15);
     }
   }

  if ( (digitalRead(button2) == HIGH) && (pos == 100) )
   {
    for (pos = 100; pos > 10; pos -=1)
     {
      servo1.write(pos);
      Serial.println(pos);
      delay(15);
     }
   }
 }

I got excited because it worked the second time it tried it, but then nothing. The serial monitor shows nothing, so I was thinking that it wasn’t getting a signal from the rf transmitter. I connected the transmitter to a couple LEDs, and they worked (but I think I need new batteries in the key fob). When I upload the code the servo starts humming and doesn’t stop, so I don’t know what’s going on with that. I am not sure how the 10k resistors should get connected to the inputs of the arduino; rf output to resistor to arduino, or resistor to ground and arduino with the rf input in series with that. I didn’t know how it should get hooked up with the resistors so I connected an input pin to a 5v source and nothing, no rotation and nothing on the serial monitor. I tried that with both input pins and neither did anything. The servo works because I can load the sweep example leaving the servo input the same as with my code (pin 9) and it works fine, so the servo is not the problem.

I was thinking that the receiver/transmitter was the problem since its so sporadic in lighting the LEDs, but why wouldn’t the servo rotate if I connected one of the arduino input pins (either 4 or 5) to a 5v source (not from the arduino but a USB breadboard kit that I bought from here)? If the pins get a 5v source, shouldn’t the servo rotate? The one time it did work the serial monitor did show it move from 0 to 90, but I didn’t look so see what it said when I got it to rotate back to 0 from 90, I was excited it was working and wasn’t paying attention, and now it does absolutely nothing, other than create a humming servo.

Is there another small RF transmitter/receiver combo that would do what I am looking for? Maybe its the current ones I’m using, like you mentioned in an earlier post. I need it to be as small as possible because this will be going into a costume helmet and they don’t provide a lot of extra room.

I was planning on running the servo off of an Adafruit trinket, but its looking like that isn’t going to work so I may have to use an arduino nano or micro. I think the code will work, I just need to figure out if its the code, my input wire connections, or the receiver/transmitter combo.

I would recommend that you only change 1 thing at a time. Look at your for() loops now vs before. The conditional tests have slightly changed (and I don’t mean pos set to 10/100 vs 0/90).

for (pos = 10; pos < 100; pos +=1)
for (pos = 100; pos > 10; pos -=1)

Before they were …

for (pos = 0; pos <= 90; pos +=1)
for (pos = 90; pos >= 0; pos -=1)

As far as button pushes being “seen” (or not), add in a couple more prints saying “button XYZ pressed” where they’ll show if the Arduino saw them. Learning to debug code will teach you how to write code.

FWIW a Trinket should work but you will need to use an older servo library and alter the loop() code ever so slightly.

ps - What 10k resistors ? I don’t see any need for resistors.

I thought that the <= and >= in the for statements didn’t allow it to rotate since the servo’s position wasn’t equal to 9 or 0. The “button x pressed” should go in after the for statements right? I will try it again tonight with the new print lines and the for statements in their original form and see what happens.

OK I now see 2 problems. Look at these statements from your last posted code;

int pos = 0;

void setup()
 {
  servo1.write(10);
 }

void loop()
 {
  if ( (digitalRead(button1) == HIGH) && (pos == 10) )
    {
      for (pos = 10; pos < 100; pos +=1)

Tell how the conditions to get to increment pos will ever be met w/pos initialized as it is ?

Also a for loop checks the condition (pos < 100) at the top/start of each loop/iteration. If the condition is met, the code is run and the pos +=1 is executed, at the bottom of the loop. If the condition is NOT met, the code is not run and the pos +=1 is not executed … the for loop is just exited at it’s top.

So imagine the initialization error is fixed and pos = 10 and button1 is pushed. The for loop sets pos = 10, it passes the condition (10 < 100) and the loop is run. Pos goes to 11 and then the loop is repeated. When pos = 99 the loop is run and at the bottom pos increments to 100. At the top the condition is not met and the servo is left at 99 but pos = 100. This at least allows the later test to pass.

if ( (digitalRead(button2) == HIGH) && (pos == 100) )

My for loop condition test (pos >= 100) gets the servo commanded to 100 but leaves pos = 101 when the for loop exits. That ain’t good either !

So I’d use a different index, not pos, in each for loop (if the servo error of 1 deg matters).

if ( (digitalRead(button1) == HIGH) && (pos == 10) )
   {
    for (int i = 0; i < 99; i ++)
     {
      pos ++;  //i goes from 0 to 98 in the loop, loop runs 99 times, so pos will go from 10 to 100
      servo1.write(pos);
      Serial.println(pos);
      delay(15);
     }
   }

I will rewrite it with your suggestions. I will also put comments on things things I change that I am unsure of.

jc27:
I will rewrite it with your suggestions. I will also put comments on things things I change that I am unsure of.

Comments are good. And you read mine in the code above it'll be obvious I've got the if() conditional value wrong and what value it should be. :oops: :doh:

Here is the new code:

#include <Servo.h>
int button1 = 4;
int press1 = 0;
int button2 = 5;
int press2 = 0;
Servo servo1;
int pos = 0; // I'm resetting everything to 0-90 degree rotation

void setup()
{
  pinMode (button1, INPUT);
  pinMode (button2, INPUT);
  servo1.attach (9);
  Serial.begin(9600);
  servo1.write (0); // set start position to 0 degrees?
}

void loop()
{
  if ((digitalRead(button1)) == HIGH && (pos == 0)) // 0 to 90 rotation
  {
    for (int i = 0; i < 90; i ++) // using your recommendation but I thought the i is supposed to go in there
    {
      pos ++;
      servo1.write(pos);
      Serial.println(pos);
      delay(15);
    }
  }
  if ((digitalRead(button2)) == HIGH && (pos == 90))
  {
    for (int i = 90; i > 0; i --) // same as above not sure if its correct
    {
      pos --; // is this correct?
      servo1.write(pos);
      Serial.println(pos);
      delay(15);
    }
  }
}

I did some reading and read some posts on the Arduino forum and I thought that changing the for statement might help. It seems to work, but i think that I am drawing too much power from the computer USB plugs. I got an overcurrent message and it made my backlit keyboard crap out. I used 10k resistors to keep the pins LOW, and used the 5v from the usb unit as the high and it rotated fine. I may have to go with a stronger servo, it was a bit jerky, I’m thinking that I am pushing the torque limit, so I am going to do a little searching for a little bit stronger one that is close to the same size.

I am thinking since I had the servo,and the reciever running off of the USB board, that is why I couldn’t get it to work using the transmitter/receiver system. The only way it would rotate was when I used the straight 5v from the USB board and connected it to one of the input pins.

Now it seems I’m going to have a power problem. I found a lithium 9v that has 1400mAh, which should work, but I don’t think that it will last very long. It looks like the servo draws around 300mA, so theoretically the lithium 9v should be enough. I have a DC/DC converter that puts out 5v and 1.5a, so that should be good. Would it be better to go with a battery pack? I’m limited on space so using 1 or 2 batteries is about the most I think I can get away with. I am going to try another idea I have just to see if powering the receiver with its own 5v supply (a separate source not in the current circuit. I will need to connect that ground to the servo circuit ground though correct?)

How much space do you have and what kind of runtime do you want ?

jc27:
Now it seems I’m going to have a power problem. I found a lithium 9v that has 1400mAh, which should work, but I don’t think that it will last very long. It looks like the servo draws around 300mA, so theoretically the lithium 9v should be enough. I have a DC/DC converter that puts out 5v and 1.5a, so that should be good. Would it be better to go with a battery pack?

FWIW the 1400 mAh rating is the energy the battery contains, not the current capacity. A 9v PP3 size lithium might last 1400 hours with an average load of 1 mA. Or 140 hrs when supplying 10 mA. But I think the peak current rating is 120-150 mA. You'd be better off w/4 rechargable Nimh AAs to run your servo, etc...

Space is going to be small so a large battery pack won’t work. There are a few kits that do close to the same thing as this kit is going to do, and they run off of plain 9v (although one kit may run off of 9 connected in parallel but I’m not sure in that one).

If I can get one 9v to power everything for even a little bit ( the kit isn’t going to be used continuously, just occasionally), that may be my only option due to space constrains.