Nano, shield pin stays LOW

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]

Why use 13 as an input? It's the onboard LED as well.

Switch to another pin, avoids the confusion.

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.

1 Like

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
   }
}

Your input won't be pulled high with a pullup, check the schematic:

1 Like

The code was based on a public domain piece, I didn't know what value to set it to other than the 13 as in the original

What would you suggest? I'll using 4 pins in the final version of what I am creating
TIA

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.

Thank you for that and for understanding. I'll make some changes and report back

correction, you only need to change the one instance of digitalRead.

Give this a try:

#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.

This is weird - what can be happening?

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.

I actually removed the resistor, made the change you suggested and it works as planned. Now to build the bigger version.

Many thanks, this has been very helpful

1 Like

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