Update:
Here is my first try based on the code I found and it did not work. The first time I uploaded it, it move to the "current positional value". But did not do the void loop part. Just holds the positions.
Thanks.
//Includes
#include <Servo.h>
//Defines
#define LINEAR_1_100PIN 11 //Linear Actuator Digital Pin
#define LINEAR_2_100PIN 6 //Linear Actuator Digital Pin
String msg;
//max/min pulse values in microseconds for the linear actuators
#define LINEAR_1_100_MIN 1050 //
#define LINEAR_1_100_MAX 2000 //
#define LINEAR_2_100_MIN 1050 //
#define LINEAR_2_100_MAX 2000 //
Servo LINEAR_1_100, LINEAR_2_100; // create servo objects to control the linear actuators
//int knobValue, sliderValue; //variables to hold the last reading from the analog pins
int linear100Value_1 = 1051; //current positional value being sent to the linear actuator.
int linear100Value_2 = 1051; //current positional value being sent to the linear actuator.
int speed = 10;
void setup()
{
//initialize servos
LINEAR_1_100.attach(LINEAR_1_100PIN, LINEAR_1_100_MIN, LINEAR_1_100_MAX); // attaches/activates the linear actuator as a servo object
LINEAR_2_100.attach(LINEAR_2_100PIN, LINEAR_2_100_MIN, LINEAR_2_100_MAX); // attaches/activates the linear actuator as a servo object
//Analog pins do not need to be initialized
//use the writeMicroseconds to set the linear actuators to their default positions
LINEAR_1_100.writeMicroseconds(linear100Value_1);
LINEAR_2_100.writeMicroseconds(linear100Value_2);
}
void loop()
{
LINEAR_1_100.write(90);
delay(1000);
LINEAR_1_100.write(0);
delay(1000);
LINEAR_2_100.write(90);
delay(1000);
LINEAR_2_100.write(0);
delay(1000);
}
Old Question:
I am trying to make the code described in this tutorial:
work with PWM from an Arduino, without the additional board.
So far the Arduino Examples>Servo>Sweep works as I would like to achieve it (delay changed to 30 ms) but very slowly and it does not seem to just go 180 steps out wait 30 ms and 180 steps in again. It sometimes moves twice in one direction. If I change the steps from 1 to 5 the servo does not move anymore (I expected it to go faster).
With the code above I understand I can control the servo with a Knob or Slider, but I would like to understand how I can control this Linear Actuator Servo with PWM from an Arduino PMW Pin (e.g. 11) and change the speed. Finally I would like to make the Servo consistently go x amount of steps out, wait for x ms and the same amount back in again.
Most importantly I would like to make sure it always ends at position 0, and that it does not accumulate errors.
Thank you for any help.
1 Answer 1
About being sure about returning to position 0 this is not a problem. You are not actually controlling anything with your PWM. You are only sending a signal to the IC inside the servo to tell it where to move the actuator. That IC knows in what position the actuator is located in any moment, usually using some kind of encoder (it's called a closed loop system) and it will make sure that it will move back exactly to 0
whenever you tell it to move to 0
.
If you want to make things clearer you can use write
method to send value to the servo.
void Servo::write(int value)
{
if(value < MIN_PULSE_WIDTH)
{ // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
if(value < 0) value = 0;
if(value > 180) value = 180;
value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
Any value from 0
to 180
will set a position to which servo will move from MIN to MAX possible position. No need for manual calculation of microseconds.
You have to remember that PWM works constantly. If you write for example LINEAR_1_100.writeMicroseconds(1051)
this code will set some timers, counters and prescalers inside the ATmega chip on the Arduino board and the value of PWM will be sent constantly until you change it.
So the delay(2000)
doesn't stop the PWM signal, and servo remains in constant position.
The issue is here:
LINEAR_1_100.writeMicroseconds(1800);
LINEAR_1_100.writeMicroseconds(1051);
You set the value of 1800
and then immediatelly set value of 1051
, but the ATmega didn't even have the time to send the first value to the servo.
Add a delay(1000)
after every call of write
or writeMicroseconds
to allow the PWM to actually be sent to the servo.
-
Thank you for the clarification. But how can I integrate this into my code ? Do I just call void servo from void loop ? Do I have to define the MIN_PULSE_WIDTH, SERVO_MIN, MAX ? This sounds like the solution, but how can I change my code. Also the :: seems like C++ code to me and I am not as frequent with this. Thanks again.digit– digit2019年04月05日 10:29:02 +00:00Commented Apr 5, 2019 at 10:29
-
Sorry for confusing you. You already defined those values when you created/attached
LINEAR_1_100
andLINEAR_2_100
the code is taken from the Servo.h library. Don't look to much into it. All you need to do is writeLINEAR_1_100.write(90)
in the code and adddelay(1000)
after it to give Arduino some time to actually send the PWM value to the servo.Filip Franik– Filip Franik2019年04月05日 10:32:39 +00:00Commented Apr 5, 2019 at 10:32 -
I changed my code (see above), but it still doesn't move. I just hear it ticking, but no movement.digit– digit2019年04月05日 10:41:47 +00:00Commented Apr 5, 2019 at 10:41
-
Are you by any chance powering the servo directly from the Arduino that's connected to your PC? I simulated your code in Tinkercad and it works fine with virtual normal servos. Maybe your linear servos draw to much current and protection circuitry (in laptop) kicks in and disable power. Power them from external 5V source (not through Arduino because it can also burn)Filip Franik– Filip Franik2019年04月05日 11:51:55 +00:00Commented Apr 5, 2019 at 11:51
-
Ok, thanks for the feedback. I don't but maybe the MA is not enough.digit– digit2019年04月08日 06:54:15 +00:00Commented Apr 8, 2019 at 6:54