The attached sketch is running on a Nano mounted on a shield
The servo is on position 3, with the input pin connected to 0v with a switch and there is a 10k pullup resistor connected to the same pin and to 5v.
The monitor always shows the same value:
0
0
60
0
0
60
it never goes HI regardless of the switch setting
[code]
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
bool previousButtonState;
void setup()
{
Serial.begin(9600);
pinMode(13, INPUT);
myservo.attach(3); // attaches the servo on pin 3 to the servo object
myservo.write(90); // tell servo to go to the home position
}
void loop()
{
const bool State = digitalRead(13);
Serial.println(State);
Serial.println(previousButtonState);
Serial.println(pos);
if (State == 0)
pos = 60 ; // set left position
else
pos = 120 ; // set right position
if (State != previousButtonState)
previousButtonState = State;
Serial.println(State);
Serial.println(previousButtonState);
Serial.println(pos);
myservo.write(pos);
delay(5000);
}
[/code]
Properly indented, this is what your loop function looks like:
void loop() {
const bool State = digitalRead(13);
Serial.println(State);
Serial.println(previousButtonState);
Serial.println(pos);
if( State == 0 )
pos = 60; // set left position
else
pos = 120; // set right position
if( State != previousButtonState )
previousButtonState = State;
Serial.println(State);
Serial.println(previousButtonState);
Serial.println(pos);
myservo.write(pos);
delay(5000);
}
Your if( State != previousButtonState ) statement only has previousButtonState = State; as its then clause.
So if before the if, State and previousButtonState are the same, they will be the same after. If they are different, the assignment will make them the same.
Therefore, your Serial.println statements will always print the same value.
Use {...} around all those following statements if you only want to print the state when it changes, and don't assign previousButtonState until after you've printed it.
The Serial.println() and myservo.write(pos) functions are outside the if block that checks if the button state has changed. Try to edit your code like this:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
bool previousButtonState;
void setup()
{
Serial.begin(9600);
pinMode(13, INPUT_PULLUP); // Use INPUT_PULLUP to activate the internal pullup resistor
myservo.attach(3); // Attach the servo on pin 3 to the servo object
myservo.write(90); // Move the servo to the home position
previousButtonState = digitalRead(13); // Initialize with the current state of the button
}
void loop()
{
const bool State = digitalRead(13); // Read the current state of the button
Serial.println(State); // Print the current state of the button
Serial.println(previousButtonState); // Print the previous state of the button
Serial.println(pos); // Print the current servo position
if (State != previousButtonState) { // Check if the button state has changed
if (State == LOW) // Button pressed (since INPUT_PULLUP is used)
pos = 60; // Set left position
else
pos = 120; // Set right position
myservo.write(pos); // Update the servo position
delay(5000); // Wait for 5 seconds
previousButtonState = State; // Update the previous state with the current state
}
}
any pin from 2 to 12, or 14-19,(aka A0 to A5) can be used as digitals. You're using one for the servo output, so pick another. You got unlucky with D13 is all.
It's a known problem with the Nano, because folks start with the Uno, then move to the Nano, but the Uno has a buffer for the onboard LED which they sacrificed on the Nano.
Buffer can be seen in grid B4 of the Uno schematic, if you're interested:
That's why the Uno can have a button on the D13 and be used as an input, but Nano, not so much.
Heres a schematic I was given, forgive my ignorance as I'm not in any way experienced with this technology. My ground connection is to pin1 which I'm told relates to a servo on no 3 on the digital servo pins. What I don't get is why this is referred to as 13 in the sketch and if I change it to (say) 14, where would I now put the ground connection and/or pullup
Okay. Ouch, you're a newb. Sorry, just a statement of fact.
Your 13, in the code, means that the digitalRead function is checking the state of, on your shield, the blue pin with the 13 beside it. Which is digital input 13, which just happens to be the pin also used for the LED on the Nano, which is why I say it won't work.
That drawing is confusing, and not aligned with the code. If you've wired per that drawing, I think your resistor and one pole of your switch are wired to pin 8. If so, your code should always read pin 8, thusly: digitalRead(8)
As it is, you'll have to change several locations in the code; the code could be improved with a pin definition at the top, and changing all the reads to reference that definition, but that's an aside.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
const int buttonpin = 8;
const int leftpos = 60;
const int rightpos = 120;
const int centerpos = 90;
const int servopin = 3;
bool previousButtonState; //variable to track previous condition
int pos = 0; // variable to store the servo position
void setup() {
Serial.begin(9600);
pinMode(buttonpin, INPUT);
previousButtonState = digitalRead(buttonpin);
myservo.attach(servopin); // attaches the servo to the servo object
myservo.write(centerpos); // tell servo to go to the home position
}
//The servo will center, until first button press, then follow the button state left or right
void loop() {
const bool State = digitalRead(buttonpin);
if (State != previousButtonState) {
pos = State ? rightpos : leftpos; //right position if State is 1, left position otherwise
previousButtonState = State;
Serial.println(State);
Serial.println(pos);
myservo.write(pos);
}
delay(50);//poor man's debounce; should be eliminated, use millis() construct instead
}
Thank you very much, I got that installed and uploaded but nothing changed. It then occurred to me that unless deliberately pulled LO, all digital pins should be HI on power up. So, with the sketch running and the serial monitor active I started checking each digital pin on the board, starting with 7, using a multimeter, from the 5v to the digital pin. Almost immediately pin 8 went HI and the servo moved. If I removed the meter probe it stopped and the pin 8 remained LO, until I checked again and again it went HI and the servo moved.
Sounds like an intermittent, the pressure of the meter probe forcing contact. Or, resistor is fried.
Change one thing. Change "INPUT" to "INPUT_PULLUP" in the call to pinMode, and run the new version.