What's going on guys? Vlad with EEEnthusiast.com here.
In today's video we're going to be looking at a very interesting project which was inspired by a Facebook message
along with a video of a robot arm which could essentially be taught a specific motion.
The robot arm would repeat the motion in cycles until it is reset or you teach it a different motion.
I'm going to give you a quick demonstration. What I have here is a potentiometer hooked up to the Arduino as well as a servo.
As you can see, I can freely move the servo back and fourth within a 180 degree cycle.
As soon as I press the button, my program starts learning the motion of the servo.
As you see, I can move it fast or I can move it really slow.
Once I press the button a second time, the servo is going to go into this memory state where it is going to go back and fourth repeating the same motions.
As you can see, it is going through the cycles every single time, until I reset the Arduino or I go back into the original (first) state
This is a very cool Arduino potentiometer servo control application and I am going to be walking you through the hardware as well as all of the software you need
in order to implement something like this. Obviously, you can expand this at your own leisure once you've learned how to build this.
You can recreate the "robot arm" application. Without any further delay, lets get started.
You will need a few components for this build. Obviously you will need your Arduino.
a push button, a pull down resistor. It can be anything from 10k and up.
In my case, I believe that this is a 22k ohm resistor, and I'm using a 470nF capacitor in order to debounce in hardware
I'm also going to be using a potentiometer. This is a 20k ohm variable potentiometer. A servo motor; this is a very cheap servo motor; you can get a more powerful one if you desire to do so.
Obviously, a lot of jumper cables.
Without any further delay, lets take a look at the actual assembly.
The first thing is break out the power rails of the Arduino. Obviously, we take the 5 volts
and break it out onto the breadboard. Similarly, the ground bus is going to go onto our second rail.
We will follow-up with the potentiometer.
The potentiometer essentially acts as an analog input into the Arduino
All I'm doing is creating a voltage divider between the lowest point and the highest point of the potentiometer.
Lets use the white cable for the middle pin.
It will be going into A0 on the Arduino
White cable to A0.
And then, like I said, this is going to be the mid point. One side of the potentiometer is going to be pulled up
one side is going to be pulled down to low.
One goes to the high rail, one goes to the ground.
Next is our servo.
I'm going to land one of the pins on an empty breadboard and then I am going to be landing
ground and 5 volts accordingly.
What I'm also going to need is obviously the servo control pin.
That's going to an analog or PWM output pin, so that's pin number 11.
Lastly, lets take the input of the button. Right now, as you can see, it is being pulled down to the ground.
I'm using pin 12 for the button, so the blue cable is going to pin 12 on the Arduino.
In the case that the button is pressed, this is going to go to HIGH.
I'm going to need to put the second cable of the button to the high rail.
As you can see, my circuit is very well color coded. Hopefully, you can follow. I'm going to post a schematic on my website (EEEnthusiast.com)
You will have a link in the description. Make sure to check it out. That's pretty much the build that we're going to be using for this project.
Lets go through the software I have written for this application. In the first line, as you can see, I'm including the Servo.h Arduino library.
This is telling the compiler that I'm going to be using the functions within that library.
I create a new "Servo1" on the next line. I have an int AnalogOut as well as a NewAnalogOut
set to 0. These are used to read the value from the potentiometer.
The button is on pin 12 as I had showed you earlier in the hardware
The state as well as the last state are stored in an integer as a 0. This could have also been created as a boolean.
The storage array which currently has 800 ints stored in it, is initialized in order to store the value
at each time recording for the position of the servo.
You have the storage location set to 0. This is used as sort of a pointer for the array.
The "recording" is essentially a counter for the number of button presses that we're going to be seeing in the program.
The void setup function is going to have a Serial dot begin 9600.
I used it purely for troubleshooting purposes.
I don't believe it is still used in the logic as of right now. I'm declaring a Servo one dot attach on pin 11.
It tells the library that I have a servo on that particular pin.
Pinmode for the button is an input.
Next, we have the main loop function. The first check that I'm doing is a digital read on the button; I'm checking for the state.
If the state that I've just read is different than the last state, meaning that they are both initialized at 0 and this one has changed to 1.
I execute the following logic. If the state is high, I'm going to add 1 to the recording.
If recording is equal to 2, I'm going to essentially...
jump and set 777 at the current storage location.
This is done in order to seal the sweep of the servo so to speak.
If we aren't going through all of the 800 elements inside of the array, we will have a certain end point.
Which will be indicated by the 777.
It can be indicated by anything else, as long as it is an integer and as long as you can identify it within your array.
Closing the function, closing the function. I'm using a 50 millisecond delay. Last, outside of that whole big function, I set the last state
to the current state in order to keep track of the toggling. If you keep holding down the button it's not going to keep toggling.
This is a reapplication of the code from the Arduino library.
Next we have the "if no presses have been done". This is the initial state; as you remember, I am just going back and fourth with the servo.
I read the analog
pin from the potentiometer, that's the middle pin on our breadboard.
The NewAnalogOut is equal to the new sensor value map of 0 to 1023.
to 1 - 180. What I'm doing here is essentially..
Checking the analog value which is going to be from 0 to 1023
going to 0 -180 which is going to be
degrees of the servo sweep that I'm going to be using throughout the rest of the application
AnalogRead returns you a value from 0 to 1023 if you're reading directly through an analog read instruction.
IF! I'm checking that if the absolute difference between the NEWAnalogOut
and AnalogOut is greater than two. This is done purely for debouncing purposes.
The analog read tends to fluctuate up and down a little bit.
Give it a little buffer and it won't be jumping as much.
I'm going to set the Servo 1 dot write to AnalogOut which is just sending the information
from the potentiometer as an analog out.
And then the AnalogOut is set to the NewAnalogOut. This is once again done for debouncing purposes of the servo itself.
Closing both of those functions, a delay of one millisecond.
Next we have if recording is equal to 1, which means that one
you have pressed the button once, recording is set to 1.
If storage location is small than 1000, this can actually be changed to 800
As you can see, I've reduced the size of my array above.
The storage at the storage location is equal to the NewAnalogOut
What I'm doing is essentially recording the current position at the array position.
I'm giving it a delay of 100 milliseconds and then I'm doing a serail print line
of storage ( storage location). I'm just printing out the NewAnalogOut to my console.
This was done purely for debugging purposes.
And then I'm incrementing the storage location. If you haven't caught onto what I'm doing here
essentially, every 100 milliseconds, I'm recording the position of the servo.
The current position to the current array called storage.
And I'm incrementing the storage location by one. Essentially, this creates chunks of 100 milliseconds.
Every 100 milliseconds, I memorize the servo position.
If recording is greater than 1, this means 2 and above.
You can keep clicking the button; it will keep going 2, 3, 4, 5...
This is what is going to happen, it will go into an infinite loop.
While 1 equals to 1, this is just creating an infinite loop inside of Arduino.
The storage location goes back to zero. This is sweeping through the storage array.
If storage location is smaller than 800. Let me quickly correct that code.
or. So an OR instruction. Storage at storage location is NOT equal to 777
Again, as I had explained to you
It's either going to go through all of the 800 element of the array
Or it's going to stop at 777
Imagine if you wanted to stop within 3 seconds, while your whole recording could last up to for example thirty seconds.
You could press the button, store the 777 in your array and then essentially sweep only up to this 777.
It's going to write this Servo 1 dot write storage, storage location.
And then give it a delay of 100 milliseconds.
Going back through the same array that we've stored up here in the logic.
Sweeping through it, every one hundred milliseconds.
That's pretty much the whole program.
As I've mentioned earlier, you will have access to this through my website.
I'm going to post a link to my GitHub page which is going to contain this whole code.
I know that a lot of you have been requesting code for the previous files. Lets verify the program.
It's already loaded on the arduino, so lets do a quick demonstration.
Lets take a look at the demo of the program. One quick note is that I ended up removing the capacitor.
This was actually used on the rails instead of the button. It has too large of a value
for this particular application. I didn't have any debouncing issues with the button.
It should be working fine for you as well.
Lets take a look at the servo in the first state of the program
As you can see, I can control it back and fourth.
sweeping one hundred and eighty degrees.
If I press the button, I go into the learning state as I've mentioned.
I can create any sort of motion. Lets do a very slow sweep.
back and fourth. Once I press the button a second time, the servo is going to go into its routine.
It is going to be doing this for the rest of its lifetime.
or until you press the reset button on the Arduino.
Lets go through it once again. Press the reset and wait a second.
As you can see, I can freely control the servo.
I have absolutely no obstructions.
Once I press the button, I can teach it any kind of motion that I want.
Lets see a very small gitter and then a sweep.
all the way back and a quick sweep back again.
press the button and lets take a look.
That's our very short gitter
short sweep and should be a faster sweep.
There we go. The servo is going to repeat that motion over and over again.
As I've mentioned earlier, you can do a lot of applications with something like this.
You can create a robot arm with three or more servos and have it essentially learn
the positions based on your inputs.
That is one of the projects I would be very interested to work on.
It will be something I will showcase in one of the later videos.
As I said, all of the code will be available on my github as well as my website.
I will have some extra photos of the project of the website, so make sure to visit, leave me some comments and subscribe.
if you want me to showcase specific projects or if you want me to reverse engineer something.
Thank you guys for watching and supporting my channel.