I have a question on how i would set something up. I've tried to search all over for something similar but can't seem to find it so if there's somewhere else i should be looking please just let me know!
Anyways, I'm trying make a little setup with a Arduino Uno controlling a SG90 servo on battery power. Ideally, I'd like to push a button, servo operates per code, returns to how it was and then shuts off until the button is pushed again (or it could just remain idle i guess but I'd imagine that would just burn batteries like crazy). It would be fantastic if i could include a single LED light in there too but not necessary. My question is, is this even possible and if so, how the heck do I physically set this up? I think the image below would get me started but i don't know where the physical button would go. I think i can work out the coding myself but physically setting things up and getting the right power to the board and servo is what's holding me up right now. Any help would be GREATLY appreciated.
Do you have questions about adding to this code? How is your first sketch doing?
Yes.
How much have you done?
None.
Start with adding power to the Arduino. When you connect the battery to the GND and VIN pins, do you see the ON LED? Maybe you will see the "L" LED blink once each second from a factory-loaded sketch.
Next, you will start the Arduino IDE (programming environment) to make a minimal sketch so you understand what the IDE needs to upload and run a sketch. After the IDE is open, you will see this:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
Upload this to your Arduino... and you should see the "L" LED flashing stop. At any point, ask if you have questions.
The next step is to re-load the factory "blink" sketch... so follow this in your IDE >> FILE >> EXAMPLES >> 01.Basics >> Blink... and your IDE will contain this:
/*
Blink
Turns an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your Arduino
model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products
modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
... where you can remove some comments leaving the necessities...
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // set pinMode() for the built-in LED
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Upload this sketch to your Arduino, and you should see the "L" LED blink every second again.
What position will the servo start at? When you push the button, how far will the servo move? how long will the servo remain at that position before returning? How often will that sequence occur?
Code dump time already? "We" hadn't even introduced the button, yet. Sorry, @adidab14 I wasn't posting fast enough. Nobody likes a thorough explanation.
#include <Servo.h> // import the Servo library
Servo servo; // create servo object to control a servo
int buttonPin = 2; // declare a button pin
int servoPin = 3; // declare the servo pin
int ledPin = 4; // add an LED on pin 4
bool flag; // use a FLAG to signal the servo rotated
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
servo.attach(servoPin); // attach the servo instance to the servo PWM pin
servo.write(90); // rotate the servo to 90 degrees.
}
void loop() {
if (!digitalRead(buttonPin)) { // is the button pressed?
delay(100); // this is a quck, ugly way to debounce the button ringing noise
if (flag) { // indicates if the servo rotated
flag = !flag; // change the flag to the opposite state for the next servo movement
servo.write(0); // rotate the servo to 0 degrees
digitalWrite(ledPin, HIGH); // turn LED ON
delay(15); // this lets the servo catch up after the command
} else {
flag = !flag;
servo.write(180); // rotate to opposite direction
digitalWrite(ledPin, LOW); // turn LED OFF
delay(15);
}
}
}
So far i've set up the board and just uploaded a sample "blink" sketch to it just to make sure i have the right drivers and stuff to communicate to the board, which ended up working perfectly. I hadn't started actually writing a sketch of my own yet because i wasn't sure if it would be different from the ones i've been able to find with the button/battery power stuff or not.
This wokwi thing is awesome tho, i can't wait to tinker around with it to make sure i got stuff figured out. What a cool tool!
It doesn't look like you can add batteries or power supplies in there though... so was my initial battery/power setup correct? or will everything explode when i push the button
So i'm not 100% positive on this because i'll have to do some guess and check with some stuff but my idea is the servo will start at 0 and move about 90 CW (may be a little more or less but right around there), stay there for like 5-7 seconds and then return to 0 (again may be a little different but right around there). If i can figure out an LED light, it will just be on for this duration or at least the 5-7 seconds and then turn off, but if that turns out to be too complicated for me i'm thinking i can just forego the light until i'm a little smarter
And i just need it to happen once per button press. So press button, servo moves and returns, servo doesn't move again until button is pushed again.
i appreciate the crap out of that! i'm trying to be as little of a nuisance as i can be haha so i'll try to figure out as much as i can without badgering folks. So far i got it to do exactly what i want but i'm having some trouble getting it to only do it when a button is pressed. Without a button i got the sketch below. I'm positive it's an ugly code so i apologize but everytime i try to get the button in there i get some weird results.
You need to configure the button pin in setup()... add this line:
pinMode(buttonPin, INPUT_PULLUP); // configure pin with pullup resistor. Pressed = LOW, normal = HIGH
... and * INSIDE LOOP() * when you want to read the button, do this:
if (digitalRead(buttonPin) == 0) { // read the button pin to see if it is LOW
pluto = planet9; // add whatever you need here... I like adding "function calls" but that is for later
}
Then we will need to address "button bounce"... but get your button installed first.
You can update your wokwi, but post the code here (because nothing is not forever)
i've been tinkering with this for a bit and i keep getting some sort of wonky infinite loop once i press the button. it's like parsing the code or something with the button and i don't know why. I have a feeling i'm screwing up the for loop inside the if statement for the button or something. At least the button does... something. so i'll take that as a minor win
Here's the code i mutilated:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int buttonPin = 12; // declare a button pin
int servoPin = 13; // declare the servo pin
int ledPin = 11; // add an LED on pin 11
void setup() {
myservo.attach(13); // attaches the servo on pin 13 to the servo object
pinMode(buttonPin, INPUT_PULLUP); // configure pin with pullup resistor.
// Pressed = LOW, normal = HIGH
}
void loop() {
if (digitalRead(buttonPin) == 0) { // read the button pin to see if it is LOW
delay(150); // debounce
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, HIGH); // turn LED ON
delay(5000); // servo wait for a moment at 180 degrees
for (pos = 180; pos >= 0; pos -= 1) { // returns from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, LOW); // turn LED OFF
}
}
}
}
Please, do not use slang and think you are describing technical observations, especially when you use words incorrectly.
Please, describe what you see, what part of that you want to keep, what part you want to discard, what part you want to change and in what way, and what you would like to improve upon, and in what way.
But not to loop forever. Ideally, i want to hit the button, servo goes from 0 to 180, sits at 180 for a little, and then returns to 0 and stays there until i hit the button again. If i could get a light to work it would light up from 0-180 and then shut off when the servo returns from 180 to 0. That first Wokwi does exactly that (but goes forever instead of just one loop), but when i try to incorporate the button, it doesn't quite do what i want. Everything is out of order for some reason as shown below:
And here's the code
1st wokwi code:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int buttonPin = 12; // declare button pin
int servoPin = 13; // declare the servo pin
int ledPin = 11; // declare led pin
void setup() {
myservo.attach(13); // attaches the servo on pin 13 to the servo object
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // servo from 0 degrees to 180 degrees in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, HIGH); // turn LED ON
}
delay(5000); // pause for some time at 180 degrees
for (pos = 180; pos >= 0; pos -= 1) { // returns from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, LOW); // turn LED OFF
}
}
2nd wokwi code:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int buttonPin = 12; // declare a button pin
int servoPin = 13; // declare the servo pin
int ledPin = 11; // add an LED on pin 11
void setup() {
myservo.attach(13); // attaches the servo on pin 13 to the servo object
pinMode(buttonPin, INPUT_PULLUP); // configure pin with pullup resistor.
// Pressed = LOW, normal = HIGH
}
void loop() {
if (digitalRead(buttonPin) == 0) { // read the button pin to see if it is LOW
delay(150); // debounce
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, HIGH); // turn LED ON
delay(5000); // servo wait for a moment at 180 degrees
for (pos = 180; pos >= 0; pos -= 1) { // returns from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
digitalWrite(ledPin, LOW); // turn LED OFF
}
}
}
}
Is there a way to combine the two operations on the button presses? Ideally, i'd like the servo to start at 0, go to 180 on button press (LED turns on), it pauses there for a little, and then returns to 0 (LED turns off), and then stays there until the button is pressed again. Just like this but not a never ending loop:
In the code in Post #5, the servo starts at 90, on button press it goes to 180 and stays there (LED is off). Then on another button press it goes to 0 (LED turns on) and stays there. Then it returns (LED turns off) on another button press. So it would work but would just need a button pressed for each step and someone to monitor the time required to pause which isn't a total deal breaker but would make what i'm trying to do a bit more difficult. Buuuuut every time i try to get the operation to run all in one press, i break something and it doesn't work
At what moment does the LED turn on? At button press? At 180?
At what moment does the LED turn off? After pause? At 0?
No. The servo starts at 0. Yes... i see. It does not start at 0.
Here is the update...
start at 0,
wait for button press,
rotate to 180,
LED on,
pause 5 seconds,
rotate to 0 degrees,
LED off.
Servo servo; // create servo object to control a servo
#define PAUSE 5000 // durateion of time servo will be at 180 degrees
int buttonPin = 2; // declare a button pin
int servoPin = 3; // declare the servo pin
int ledPin = 4; // add an LED on pin 4
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
servo.attach(servoPin); // attach the servo instance to the servo PWM pin
servo.write(0); // rotate the servo to 90 degrees.
}
void loop() {
if (!digitalRead(buttonPin)) { // is the button pressed?
delay(100); // this is a quck, ugly way to debounce the button ringing noise
servo.write(180); // rotate the servo to 180 degrees
digitalWrite(ledPin, HIGH); // turn LED ON
delay(PAUSE); // pausing at 180 degrees
servo.write(0); // rotate servo to 0 degrees
digitalWrite(ledPin, LOW); // turn LED OFF
}
}
That's the ticket!! It seems so simple but for the life of me i could not figure that out. Thank you so much. The only thing i can see needing now is possibly a way to slow the servo down if it moves too fast but i found a library that looks like it can do exactly that should i need it.
Now all that's left is to figure out how the heck to power this thing.