Приветствую. Это мое первое сообщение на этом форуме. В первую очередь хочу выразить благодарность Алексу за его просветительскую работу! Я совсем начинающий ардуинщик и очень многое почерпнул из из его публикаций. Еще раз огромное спасибо!
Для моего проекта сейчас требуется обеспечить наиболее плавное (с ускорением и замедлением) вращение серв. Несколько дней курил сеть и не обнаружил ни одного решения кроме библиотеки от AlexGyver. В проекте используются сервы SG90, MG996R, DS3230mg, RDS5160
Протестировав, выявил некоторые непонятки
/*
*/
// c SG90 работает удовлетворительно, даже хорошо не считая недоворот 1градус.
// с MG996 и DS3230 при движении от большего угла к меньшему эффект торможениея есть, эффект ускорения не заметен.
// при движении от меньшего угла к большему ускорение еле заметно, замедление отсутствувет.
// со всеми испытанными сервами при движении от меньшего угла к большему не доворачивает 1градус.
// от большего угла к меньшему доворачивает полностью.
// изменение диапазона широты импульсов проблему не решает, или не те диапазоны, или баг библиотеки.
// не хватает настройки длинны разгона и торможения.
#include "ServoSmooth.h"
ServoSmooth servo_name;
int new_angle;
int carrent_angle;
int v;
float g;
void setup() {
Serial.begin(9600);
servo_name.attach(7, 544, 2400, 0);
// 7-номер пина, 600 и 2400 - длины импульсов, 0-начальный угол.
// по умолчанию 544-2400 мкс
// DS3230 500-2500 мкс
// длины импульсов при которых серво поворачивается максимально в одну и другую сторону, зависят от самой серво
// и обычно указываются производителем
servo_name.setAutoDetach(false); // отключить автоотключение (detach) при достижении целевого угла (по умолчанию включено)
delay(1000); // для наглядности
}
void turn_smooth(int new_angle, int v, float g)
// желаемая позиция задаётся методом setTarget (импульс) или setTargetDeg (угол), далее
// при вызове tick() производится автоматическое движение сервы
// с заданным ускорением и ограничением скорости
{
servo_name.setSpeed(v); // ограничить скорость (условные единицы, 1 – 200)
servo_name.setAccel(g); // установить разгон и торможение (0.01 – 1)
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
//почему-то не доходит 1 градус до new_angle, если carrent_angle < new_angle.
//для решения проблемы отнимаем 1,
if (carrent_angle < new_angle)
{
while (carrent_angle != new_angle-1)
{
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
Serial.println(carrent_angle); // для наглядности
servo_name.tick(); // здесь происходит движение серво по встроенному таймеру!
servo_name.setTargetDeg(new_angle); // и отправляем на серво
}
}
if (carrent_angle > new_angle)
{
while (carrent_angle != new_angle)
{
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
Serial.println(carrent_angle); // для наглядности
servo_name.tick(); // здесь происходит движение серво по встроенному таймеру!
servo_name.setTargetDeg(new_angle); // и отправляем на серво
}
}
}
void loop()
{
new_angle = 180; // задаваемый угол поворота (0-180)
v = 150; // макс скорость (1 – 200)
g = 0.1; // ускорение/торможение (0.01 – 1)
turn_smooth(new_angle, v, g); // дергаем функцию поворота сервы
delay (1000);
new_angle = 0; // задаваемый угол поворота (0-180)
v = 30; // макс скорость (1 – 200)
g = 0.1; // ускорение/торможение (0.01 – 1)
turn_smooth(new_angle, v, g); // дергаем функцию поворота сервы
delay (1000);
}
Для моего проекта сейчас требуется обеспечить наиболее плавное (с ускорением и замедлением) вращение серв. Несколько дней курил сеть и не обнаружил ни одного решения кроме библиотеки от AlexGyver. В проекте используются сервы SG90, MG996R, DS3230mg, RDS5160
Протестировав, выявил некоторые непонятки
- со всеми испытанными сервами при движении от меньшего угла к большему не доворачивает 1градус, от большего угла к меньшему доворачивает полностью. Почему?
- c SG90 работает удовлетворительно, даже хорошо не считая недоворот 1градус в большую сторону.
- с MG996 и DS3230 при движении от большего угла к меньшему эффект торможениея есть, эффект ускорения не заметен. В чем причина?
- есть ли возможность изменения длин (углов) разгона и торможения в идеале раздельного?
/*
*/
// c SG90 работает удовлетворительно, даже хорошо не считая недоворот 1градус.
// с MG996 и DS3230 при движении от большего угла к меньшему эффект торможениея есть, эффект ускорения не заметен.
// при движении от меньшего угла к большему ускорение еле заметно, замедление отсутствувет.
// со всеми испытанными сервами при движении от меньшего угла к большему не доворачивает 1градус.
// от большего угла к меньшему доворачивает полностью.
// изменение диапазона широты импульсов проблему не решает, или не те диапазоны, или баг библиотеки.
// не хватает настройки длинны разгона и торможения.
#include "ServoSmooth.h"
ServoSmooth servo_name;
int new_angle;
int carrent_angle;
int v;
float g;
void setup() {
Serial.begin(9600);
servo_name.attach(7, 544, 2400, 0);
// 7-номер пина, 600 и 2400 - длины импульсов, 0-начальный угол.
// по умолчанию 544-2400 мкс
// DS3230 500-2500 мкс
// длины импульсов при которых серво поворачивается максимально в одну и другую сторону, зависят от самой серво
// и обычно указываются производителем
servo_name.setAutoDetach(false); // отключить автоотключение (detach) при достижении целевого угла (по умолчанию включено)
delay(1000); // для наглядности
}
void turn_smooth(int new_angle, int v, float g)
// желаемая позиция задаётся методом setTarget (импульс) или setTargetDeg (угол), далее
// при вызове tick() производится автоматическое движение сервы
// с заданным ускорением и ограничением скорости
{
servo_name.setSpeed(v); // ограничить скорость (условные единицы, 1 – 200)
servo_name.setAccel(g); // установить разгон и торможение (0.01 – 1)
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
//почему-то не доходит 1 градус до new_angle, если carrent_angle < new_angle.
//для решения проблемы отнимаем 1,
if (carrent_angle < new_angle)
{
while (carrent_angle != new_angle-1)
{
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
Serial.println(carrent_angle); // для наглядности
servo_name.tick(); // здесь происходит движение серво по встроенному таймеру!
servo_name.setTargetDeg(new_angle); // и отправляем на серво
}
}
if (carrent_angle > new_angle)
{
while (carrent_angle != new_angle)
{
carrent_angle = servo_name.getCurrentDeg(); // текущий угол
Serial.println(carrent_angle); // для наглядности
servo_name.tick(); // здесь происходит движение серво по встроенному таймеру!
servo_name.setTargetDeg(new_angle); // и отправляем на серво
}
}
}
void loop()
{
new_angle = 180; // задаваемый угол поворота (0-180)
v = 150; // макс скорость (1 – 200)
g = 0.1; // ускорение/торможение (0.01 – 1)
turn_smooth(new_angle, v, g); // дергаем функцию поворота сервы
delay (1000);
new_angle = 0; // задаваемый угол поворота (0-180)
v = 30; // макс скорость (1 – 200)
g = 0.1; // ускорение/торможение (0.01 – 1)
turn_smooth(new_angle, v, g); // дергаем функцию поворота сервы
delay (1000);
}
Изменено: