HI, I have searched for info on using servos. They are all about sweeps. I would like to do multiple different sweeps in the loop. sayt a 60 degree followed by a 45 degree followed by a 180 degree then shut it down. I haven't been able to find anything but sweeps......180 degrees, to 180 degrees. I can change it to 45 degrees, slow down the time it takes but would like to do 3 or 4 different sweeps then shut down. any suggestions? thanks, fred
If you can this, I don't understand what could prevent you from doing that as many times in series as you need
Why not just put it in setup?
Hello Fredric58
Welcome back to the worldbest forum.
What is the task of the programme in real life?
We need some additional information.
Post your sketch, well formated, with well-tempered comments and in so called code tags "< code >" and a detailed circuit diagram to see how we can help.
Have a nice day and enjoy coding in C++.
I don't no how to or what goes between the "for" loops. 1 goes clockwise, the other counter. it's from the examples/servo sweep. in other words I can't figure out how to write "sweep 60, STOP, THEN sweep 45, STOP, THEN sweep 180".and STOP. Perhaps the "for" loop is not the way to go??? Haven't found an example 1 to learn how it can be done.
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.
modified 8 Nov 2013
by Scott Fitzgerald
https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
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 15 ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach the position
}
} ```
As far as its application it's kinda like wag a dogs tail. Thanks Fred
How many sweeps? What are the START and STOP positions of each sweep? What is the speed of each sweep (smaller number = faster, minimum 2)?
@Fredric58
Here is a simulation of your description. Click the green "play" button to start.
Yet, the word "sweep" isn't even mentioned in Wikepedia: Servomotor or Servo control.
I've always thought of servo sweep as incrementally controlling the servo position through a range, rather than just one step.
Then there's easing and speed. What motion do you want the servo to take (linear or curve) and how long should it take to get there (full speed or slower)?
Well, here's the deal. I learned how to control a servo with the Arduino servo library on an Uno. I made it work rather well backwards/forwards or clockwise/counter clockwise, fast as well as slow and achieved different angles. Felt like a big shot. Sooooooo....I tried to upload it to the Attiny85 I want to use to control it only to find out, it won't work for several reasons. So I started looking for a way to control the servo with an Attiny85 without having to use a library. Which led down a path to Pulse Width Modulation, PWM and duty cycles which is a new road for sure. I found an example provided by the member mcapurso. Unfortunately he has been inactive on this forum to ask any questions for about 8 years. His latest contribution was like in 2015. I understand the concept of PWM. A "little" bit about mapping. He did write an example code using the Attiny 85 and it works as it is written. It seems a bit cumbersome but perhaps that's the way it has to be? The GOAL is to set specific angles and be able to control the speed of the sweep. In a PERFECT world it would be a s simple as.....
THIS WOULD BE REALLY COOL!!! REALLY COOL!
myServo.write(30);
delay(1000):
myServo.write(60);
delay(1000):
myServo.write(90);
delay(1000):
The most confusing part of his code is the using microseconds to achieve the angle. I have experimented with it to see what happens when you change the numbers and have noted it after the OP's original comments. It really isn't commented out enough for me to understand the process. I do believe the angles could be mapped, then called for as needed, similar to above. I don't need all 180 degrees, increments of 30 would probably work nicely I can not use a library because it will interfere with my sleep mode lib. If you would like to //comment out some of the blank stuff or clarify some that are not complete as they could be. I might be able to get a much better understanding of what is actually happening in the program. Any input greatly appreciated. Code attached. Thanks, Fred
//Author: mcapurso.Tested on attiny 85 with servo towerpro microservo 90 SG90
// 08/jan/2014 servo data on www.servodatabase.com 25
int servoPin = 0; // servo connected to digital pin 0
int MOSPWR = 1; //Sends power to MOS gate to turn on servo, add a slight delay
void setup()
{
pinMode(servoPin, OUTPUT); // sets the servoPin to be an output
pinMode(MOSPWR, OUTPUT); //sets the MOSPWR to be an output
}
void loop() // run over and over again
{
servowrite(servoPin, 0, 500, 2400); //changed middle 500 to 2000 to see what happend "it shortens the swing"
servowrite(servoPin, 90, 500, 2400); //for each independantly
servowrite(servoPin, 180, 500, 2400); //changed 2400 to 5000 to see what happens "nothing"
// servotest();
}
void servowrite(int pin, int angle, int microzero, int micro180)
{
// pin for servo, angle to move, microseconds for zero degrees, microseconds for 180 degrees
int microvalue= map(angle, 0, 180, microzero, micro180); //map angle to microseconds
int i;
for (i = 0; i < 50; i++) //Send 50 pwm pulses with width microvalue uS . (DELAY BETWEEN SWEEPS GLOBAL/FIXED)
{ //changed 50 to 1000 to see what happens "delays the time between swings"BUT MAKES THE SERVO BUZZ
analogWrite(servoPin,255); //Pulse high for microvalue uS
delayMicroseconds(microvalue);
analogWrite(servoPin,0); //Pulse low for 15mS
delay(15);
}
delay(10); //Pause
}
void servotest()
// test servo
{
int i;
for (i = 0; i < 1000; i++) //Send 50 pulses with width 500 uS - changed all to 1000 to see what happens
{
analogWrite(servoPin,255); //Pulse high for 500uS
delayMicroseconds(500); //changed 500 to 2000 to see what happens "nothing noticable"
// changed 500 to 50 to see what happens "nothing noticable"
analogWrite(servoPin,0); //Pulse low for 15mS
delay(15);
}
delay(100); //Pause for 100mS
for (i = 0; i < 50; i++) //Send 50 pulses with width 1.25mS
{
analogWrite(servoPin,255); // changed 255 to (147) to see what happens "servo FREAKS OUT"
//Pulse high for 1.4 mS
delayMicroseconds(1400);
analogWrite(servoPin,0);
delay(15);
}
delay(100);
for (i = 0; i < 50; i++) //Send 50 pulses with width 2.4ms
{
analogWrite(servoPin,255);
delayMicroseconds(2400);
analogWrite(servoPin,0);
delay(15);
}
delay(100);
}type or paste code here
I have not checked whether the code works correctly or not, but this function
void servowrite(int pin, int angle, int microzero, int micro180)
is a kind of pulse width modulation:
The delayMicroseconds(microvalue) defines the time the servoPin is set to HIGH and the delay(15) the LOW time.
microvalue is calculated by mapping the angle (0 .. 180) to a value between microzero and micro180. The values microzero and micro180 should depend on the servo parameters.
To change the servo angle one should check if the parameters as in the code allow to address angle 0 and angle 180. If this is ok, the wanted angle is addressed by setting the parameter int angle.
P.S.: I managed to run your sketch on Wokwi:
https://wokwi.com/projects/367253093348271105
Made some little changes to run your servotest() function. Therefore here the changed sketch
Wokwi Sketch
//Author: mcapurso.Tested on attiny 85 with servo towerpro microservo 90 SG90
// 08/jan/2014 servo data on www.servodatabase.com 25
int servoPin = 0; // servo connected to digital pin 0
// ************** The following pin is NOT really used in WOKWI !!!! *******************
int MOSPWR = 1; //Sends power to MOS gate to turn on servo, add a slight delay
void setup()
{
pinMode(servoPin, OUTPUT); // sets the servoPin to be an output
pinMode(MOSPWR, OUTPUT); //sets the MOSPWR to be an output
/*
servowrite(servoPin, 0, 500, 2400); //changed middle 500 to 2000 to see what happend "it shortens the swing"
servowrite(servoPin, 90, 500, 2400); //for each independantly
servowrite(servoPin, 180, 500, 2400); //changed 2400 to 5000 to see what happens "nothing"
*/
servotest();
}
void loop() // run over and over again
{
}
void servowrite(int pin, int angle, int microzero, int micro180)
{
// pin for servo, angle to move, microseconds for zero degrees, microseconds for 180 degrees
int microvalue = map(angle, 0, 180, microzero, micro180); //map angle to microseconds
int i;
for (i = 0; i < 50; i++) //Send 50 pwm pulses with width microvalue uS . (DELAY BETWEEN SWEEPS GLOBAL/FIXED)
{ //changed 50 to 1000 to see what happens "delays the time between swings"BUT MAKES THE SERVO BUZZ
analogWrite(servoPin, 255); //Pulse high for microvalue uS
delayMicroseconds(microvalue);
analogWrite(servoPin, 0); //Pulse low for 15mS
delay(15);
}
delay(10); //Pause
}
void servotest()
// test servo
{
int i;
for (i = 0; i < 50; i++) //Send 50 pulses with width 500 uS - changed all to 1000 to see what happens
{
analogWrite(servoPin, 255); //Pulse high for 500uS
delayMicroseconds(2000); //changed 500 to 2000 to see what happens "nothing noticable"
// changed 500 to 50 to see what happens "nothing noticable"
analogWrite(servoPin, 0); //Pulse low for 15mS
delay(15);
}
delay(1000);
for (i = 0; i < 50; i++) //Send 50 pulses with width 1.25mS
{
analogWrite(servoPin, 255); // changed 255 to (147) to see what happens "servo FREAKS OUT"
//Pulse high for 1.4 mS
delayMicroseconds(1400);
analogWrite(servoPin, 0);
delay(15);
}
delay(1000);
for (i = 0; i < 50; i++) //Send 50 pulses with width 2.4ms
{
analogWrite(servoPin, 255);
delayMicroseconds(2400);
analogWrite(servoPin, 0);
delay(15);
}
delay(1000);
}
Your servotest() works fine if one uses appropriate timings and a delay that gives the servo time to reach the commanded angle.
Good luck!
E, Hi, Thank you. I loaded the code with your changes and the result was nothing happens. Nothing at all. I get the 0, 90 and 180 are degrees. Is this the 500 this part? (for (i = 0; i < 50; i++) //Send 50 pulses with width 500 uS)
what does the 2400 do? Thanks, I gotta start slow
servowrite(servoPin, 0, 500, 2400);
servowrite(servoPin, 90, 500, 2400);
servowrite(servoPin, 180, 500, 2400);
I take that back, it does jitter back to 0, then it goes to 90, then it goes to 180, then it stops. might have been a loose connection
E, the "wokwi" is pretty cool. but you missed the part that I CAN'T use the Arduino library for the Attiny85. It doesn't support the 85 and it conflicts with the sleep lib. I like the concept.....but the details are important. The program has to be PWM. I need to control the angle, and I need to control the sweep speed. (various angle and 1 speed would work) SPEED SLOW. The program I presented "works", it just moves too fast, however I think I can add different angles without any problems.
" " myself...
"So I started looking for a way to control the servo with an Attiny85 without having to use a library. Which led down a path to Pulse Width Modulation, PWM " It's quite more complex than using a library, though E, I appreciate your effort.
On another note: I know there is someone out there that looks at this and thinks. "i could do that in 10 minutes. I'm an inventor, NOT a programmer. I can make each "piece" work, but I can not compile them together. I have a budget of $100.00 US for anyone who can complete this task. Payment when I receive a working model. AFTER, you review the program that it needs to assimilate with. Provided upon request. You will get PAID, otherwise you'll blacklist me on this forum and no one will want to work with me. If it doesn't work I will post the results to the forum to review to confirm why a payment wasn't made. I think that sounds more than fair. If in the event your skills are such that you can produce the code needed for my project in a relatively short amount of time (7) days with (7) days for tweaks/adjustments, my budget will increase to $150.00 US. I must add the disclosure that I am not aware of any TOS of the Arduino community that would not allow me to pay someone to help with my project.
Thank you, Fred
There is a paid consultancy section of the Forum, I suggest you request that this thread be moved there.
Thank you for that info, unfortunately we've come across a huge unexpected home repair cost so I am formally retracting the offer. Our sewer line has to be replaced and they have to tunnel under the house to do it. estimated cost is over 10K, OUCH!!! I'll have to learn this on my own. That being said lets move on.
So, in regards to PWM, I understand that a pulse changes the angle of a shaft according to the width of the pulse. For example, a 1.5 millisecond pulse sets the shaft to 0°. the pulse width from 1.5 milliseconds to 1 millisecond rotates from 0° to -90° and from 1.5 milliseconds to 2 milliseconds goes from 0° to +90°. I can accomplish this. The only challenge here is how to slow the sweep speed down. Besides changing the gear ratio inside the servo is there a way to do it with code? Thanks, Fred
An example from another thread, you'll have to make it fit your context:
void rotateMotor() {
for (pos = 0; pos <= 90; pos++) {
myservo.write(pos);
delay(15);
}
}
As you can see, the servo is moving one degree at a time in this code. One can make that slower or faster by changing delay, or faster by doubling the change in degrees per iteration.
That's about all I can contribute, you'll have to do some work now.
Thank you, can you post a link to the other thread please so I can look at the context? Fred
Maybe you could take a look at this?
And it is non blocking.
Those are very useful libraries. The issue is I can't use them with an Attiny85. I have to use PWM and map the angles of sweep in microseconds. Kinda backwards of what I wanted to do but it works though I still need to fine tune it.