This is a short animation I made to try and convey what I want the servo motors to be doing. (Starting point being 180 degrees and lowest point being 90 degrees)
I'm new to coding so was wondering if anyone knew how to do this
Thanks
A better way to describe how you want the servos to move would be to draw a chart or graph. The horizontal axis would be time in seconds. The vertical axis would be angle of the servo, with 90 degrees at the bottom and 180 Deg at the top. Draw lines in 4 different colours showing how you want the different servos to move over one complete cycle of time.
arrays can be used to apply some action to a sequence of servos.
looks like you want to move a servo arm forward and back with a delay in that action between each servo, starting with the servo on the left and then starting with the servo on the right.
millis() can be used to time the actions. looks like there an action to move the arm forward and then move it back after the next servo has been moved. a table (array) can be used to specify the servo, position and time of each action
Have you coded moving one servo?
Have you looked at the servo examples?
Have you taken a look at File|Examples|Digital|02.BlinkWithoutDelay?
Have you used this thing
and the words "servo" to take a look at what has been done before?
Yes.
Now that the question has been answered mark your post as solved.
Power the servos from their own power source and not from the MCU's power.
Don't run the servo's power through a breadboard.
@gcjr 's suggestion is good. Another way would be to write a function that returns the angle at a given time. For example:
int servoAngle(unsigned long t) {
if (t < 1000) return 180;
if (t < 1500) return map(t, 1000, 1500, 180, 90);
if (t < 2000) return 90;
... etc ...
}
Is this what you meant by an array? And if so, do I program the board with for loops under every timed action?
Sorry for the trouble but if it's possible, can you elaborate more on this?
Also, this is the chart and graph you've mentioned earlier.
The sequence can be put in an array and with a millis timer, the sequence can be done for many servo motors. That is a good and nice solution. I don't have a example for that.
A quick way is to program the sequence in code with math. A millis timer to update the positions every 10 ms or 20 ms is still needed. A simulation is here: ServoShowcase.ino - Wokwi Arduino and ESP32 Simulator
The advantage of the math is, that the motions are smooth regardless of the speed.
Do you want the maximum speed of the servo motors to go to a position or do you want to slow them down ?
I think that I would choose this option. Your graph is a interpolation, that is confusing, since the data-points are linear.
When the servo motors do not need to operate individually, but are somehow attached to a combined motion, then a delay is good enough. The simulation for that is this: ServoOverdone.ino - Wokwi Arduino and ESP32 Simulator
However, you must be sure that the sketch has nothing else to do, and will not do other things in the future.
The motion on ServoOverdone.ino - Wokwi Arduino and ESP32 Simulator at around the 12th second is exactly what I want to accomplish! May I know which part specifically is that on the code?
Sure! Study the code until you understand what each part is doing, and the part in question will become obvious.
This will be good instruction and practice for writing your own code. You usually can't take a piece out of someone else's code and expect it to "just work".
I don't think so
Look for:
// Sequence three.
// A rotating wave.
I rotate a single servo motor. But then I calculate the distance of nearby servo motors to that servo motor and move them also a little. The result is the wave. You need to control the servo motors and not this kind of fuzzy clownesque silly thing
Yes, I was going to isolate that specific part to study it and apply it to what I was going for. Thank you for the advice, I appreciate it!
OP, post your code and best efforts, post a schematic and post images of your project.
Read about state machines.
Thank you! This helps a lot. I appreciate it so much
I'm still trying to study up on these codes to further get a better understanding while testing. I've only been studying Arduino boards for a month and have been tasked with a project that's way beyond my skill level. So I don't really have a strong basis on what I have to do yet.
This is a newbie question but what does a and j specify in your code;
for( int a=0; a<6; a++)
{
for( int i=0; i<NUM_SERVOS; i++)
{
for( int j=0; j<NUM_SERVOS; j++)
{
// Calculate distance to active servo
int d = j - i;
if( d < 0)
d = -d;
if( d > (NUM_SERVOS / 2))
d = NUM_SERVOS - d;
int angle = 90 - (10 * d);
if( angle < 0)
angle = 0;
myServo[j].write( angle);
}
delay(40);
}
}
I can assume that i is the servo motor input number and d is the distance but I don't know what to think about the other two
I'm currently trying for loops but thinking of a way to code the other servos to follow with a delay (which I think the difficult part is) since the board is single threaded.
Have you read up on using millis() for timing and state machines?
Me, I'd use an esp 32 and have each task trigger another task upon task motor drive completion.
An ESP32 comes with freeRTOS as an OS. A built in multi tasking multiprocessing OS.
I think that's too complex for me at my current level.
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
int pos = 180;
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 200; //the value is a number of milliseconds, ie 1 second
void setup() {
// put your setup code here, to run once:
int pos = 180;
servo1.attach(1);
servo2.attach(3);
servo3.attach(5);
servo4.attach(7);
servo5.attach(9);
servo1.write(pos);
servo2.write(pos);
servo3.write(pos);
servo4.write(pos);
servo5.write(pos);
startMillis = millis();
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long currentMillis = millis();
servo5.write(0);
for (pos = 180; pos >= 80; pos -= 1){
if (currentMillis - startMillis >= period)
{
servo2.write(pos);
}
servo1.write(pos);
delay(20);
}
for (pos = 80; pos <= 180; pos += 1){
servo1.write(pos);
delay(20);
}
This is the code I have right now and I'm trying to get the second servo motor to do the same action but about 500 ms later