1

Topic: Управление Сервоприводом

Добрый день, есть код управления сервоприводами и двумя моторами, как в коде прописать ограничения по управлению сервоприводами, начальный угол выставляется везде одинаково, ВОПРОС: Как установить мин и максимальный угол работы сервомашинок?
например: необходимо чтобы первая серва отклонялась от исходного положения 10 гр влево и 30 гр вправо

// RemoteXY select connection mode and include library 


#define REMOTEXY_MODE__HARDSERIAL

#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 9600


// RemoteXY configurate   
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,8,0,0,0,60,0,8,13,0,
  4,0,48,2,5,41,2,26,4,0,
  61,2,5,41,2,26,4,0,76,2,
  5,41,2,26,4,0,88,2,5,41,
  2,26,4,160,46,46,49,5,2,26,
  4,160,46,54,49,5,2,26,5,0,
  10,16,30,30,2,26,31 };
   
// this structure defines all the variables of your control interface 
struct {

    // input variable
  int8_t slider_1; // =0..100 slider position
  int8_t slider_2; // =0..100 slider position
  int8_t slider_3; // =0..100 slider position
  int8_t slider_4; // =0..100 slider position
  int8_t slider_5; // =-100..100 slider position
  int8_t slider_6; // =-100..100 slider position
  int8_t joystick_1_x; // =-100..100 x-coordinate joystick position
  int8_t joystick_1_y; // =-100..100 y-coordinate joystick position

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

#include <Servo.h>   

Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;


/* определяем пины управления правым мотором */
#define PIN_MOTOR_RIGHT_UP 8
#define PIN_MOTOR_RIGHT_DN 9
#define PIN_MOTOR_RIGHT_SPEED 10

/* определяем пины управления левым мотором */
#define PIN_MOTOR_LEFT_UP 12
#define PIN_MOTOR_LEFT_DN 13
#define PIN_MOTOR_LEFT_SPEED 11




/* определяем два массива с перечислением пинов для каждого мотора */
unsigned char RightMotor[3] = 
  {PIN_MOTOR_RIGHT_UP, PIN_MOTOR_RIGHT_DN, PIN_MOTOR_RIGHT_SPEED};
unsigned char LeftMotor[3] = 
  {PIN_MOTOR_LEFT_UP, PIN_MOTOR_LEFT_DN, PIN_MOTOR_LEFT_SPEED};

/*
   управление скоростью мотора
   motor - ссылка на массив пинов
   v - скорость мотора, может принимать значения от -100 до 100
*/
void Wheel (unsigned char * motor, int v)
{
  if (v>100) v=100;
  if (v<-100) v=-100;
  if (v>0) {
    digitalWrite(motor[0], HIGH);
    digitalWrite(motor[1], LOW);
    analogWrite(motor[2], v*2.55);
  }
  else if (v<0) {
    digitalWrite(motor[0], LOW);
    digitalWrite(motor[1], HIGH);
    analogWrite(motor[2], (-v)*2.55);
  }
  else {
    digitalWrite(motor[0], LOW);
    digitalWrite(motor[1], LOW);
    analogWrite(motor[2], 0);
  }
}
void setup() 
{
  RemoteXY_Init (); 
     
  // TODO you setup code 
  myservo1.attach(2);
  RemoteXY.slider_1 = 50;
  myservo2.attach(3);
  RemoteXY.slider_2 = 50;
  myservo3.attach(4);
  RemoteXY.slider_3 = 50;
  myservo4.attach(5);
  RemoteXY.slider_4 = 50;
  myservo5.attach(6);
  RemoteXY.slider_5 = 100;
  myservo6.attach(7);
  RemoteXY.slider_6 = 100;

  /* инициализация пинов */
  pinMode (PIN_MOTOR_RIGHT_UP, OUTPUT);
  pinMode (PIN_MOTOR_RIGHT_DN, OUTPUT);
  pinMode (PIN_MOTOR_LEFT_UP, OUTPUT);
  pinMode (PIN_MOTOR_LEFT_DN, OUTPUT);


}

void loop() 

  RemoteXY_Handler ();
   
  /* управляем правым мотором */
  Wheel (RightMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
  /* управляем левым мотором */
  Wheel (LeftMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x); 

  // TODO you loop code
  // use the RemoteXY structure for data transfer

    int ms1 = RemoteXY.slider_1*20+500; 
  myservo1.writeMicroseconds(ms1);

    int ms2 = RemoteXY.slider_2*20+500; 
  myservo2.writeMicroseconds(ms2);

    int ms3 = RemoteXY.slider_3*20+500; 
  myservo3.writeMicroseconds(ms3);

    int ms4 = RemoteXY.slider_4*20+500; 
  myservo4.writeMicroseconds(ms4);

    int ms5 = RemoteXY.slider_5*20+500; 
  myservo5.writeMicroseconds(ms5);

    int ms6 = RemoteXY.slider_6*20+500; 
  myservo6.writeMicroseconds(ms6);



 
}

2

Re: Управление Сервоприводом

Дополнение к предыдущему посту

вот приблизительно что я хочу получить от этой программы





// RemoteXY select connection mode and include library 


#define REMOTEXY_MODE__HARDSERIAL

#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 9600


// RemoteXY configurate   
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,8,0,0,0,60,0,8,13,0,
  4,0,48,2,5,41,2,26,4,0,
  61,2,5,41,2,26,4,0,76,2,
  5,41,2,26,4,0,88,2,5,41,
  2,26,4,160,46,46,49,5,2,26,
  4,160,46,54,49,5,2,26,5,0,
  10,16,30,30,2,26,31 };
   
// this structure defines all the variables of your control interface 
struct {

    // input variable
  int8_t slider_1; // =0..100 slider position
  int8_t slider_2; // =0..100 slider position
  int8_t slider_3; // =0..100 slider position
  int8_t slider_4; // =0..100 slider position
  int8_t slider_5; // =-100..100 slider position
  int8_t slider_6; // =-100..100 slider position
  int8_t joystick_1_x; // =-100..100 x-coordinate joystick position
  int8_t joystick_1_y; // =-100..100 y-coordinate joystick position
 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

#include <Servo.h>   

Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;

const float myservo1_L_ANGLE = 145; // Максимальные угл поворота налево
const float myservo1_R_ANGLE = 25;  // Максимальные угл поворота направо
const float myservo1_DEF_ANGLE = 85; // Дефолтный угол (центровка)
const float myservo2_U_ANGLE = 55;  // Максимальные угл поворота вверх
const float myservo2_D_ANGLE = 0; // Максимальные угл поворота вниз
const float myservo2_DEF_ANGLE = 25; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float myservo2_STEP = 0.01; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float myservo1_STEP = 0.02; // Шаг - знаение отвечающее за скорость вращения по горизонтали
float curmyservo2Angle = myservo2_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curmyservo1Angle = myservo1_DEF_ANGLE; //Переменная текущего угла гор. сервы
bool moveServomyservo2Up = false; //Флаг движения верт. сервы вверх
bool moveServomyservo1Down = false; //Флаг движения верт. сервы вниз
bool moveServomyservo2Left = false; //Флаг движения гор. сервы влево
bool moveServomyservo1Right = false; //Флаг движения гор. сервы вправо
const int TIMEOUT_TIME_MS = 150;
unsigned long lastPilotSymbolTime;
char symbol;

/* определяем пины управления правым мотором */
#define PIN_MOTOR_RIGHT_UP 8
#define PIN_MOTOR_RIGHT_DN 9
#define PIN_MOTOR_RIGHT_SPEED 10

/* определяем пины управления левым мотором */
#define PIN_MOTOR_LEFT_UP 12
#define PIN_MOTOR_LEFT_DN 13
#define PIN_MOTOR_LEFT_SPEED 11




/* определяем два массива с перечислением пинов для каждого мотора */
unsigned char RightMotor[3] = 
  {PIN_MOTOR_RIGHT_UP, PIN_MOTOR_RIGHT_DN, PIN_MOTOR_RIGHT_SPEED};
unsigned char LeftMotor[3] = 
  {PIN_MOTOR_LEFT_UP, PIN_MOTOR_LEFT_DN, PIN_MOTOR_LEFT_SPEED};

/*
   управление скоростью мотора
   motor - ссылка на массив пинов
   v - скорость мотора, может принимать значения от -100 до 100
*/
void Wheel (unsigned char * motor, int v)
{
  if (v>100) v=100;
  if (v<-100) v=-100;
  if (v>0) {
    digitalWrite(motor[0], HIGH);
    digitalWrite(motor[1], LOW);
    analogWrite(motor[2], v*2.55);
  }
  else if (v<0) {
    digitalWrite(motor[0], LOW);
    digitalWrite(motor[1], HIGH);
    analogWrite(motor[2], (-v)*2.55);
  }
  else {
    digitalWrite(motor[0], LOW);
    digitalWrite(motor[1], LOW);
    analogWrite(motor[2], 0);
  }
}
void setup() 
{
  RemoteXY_Init (); 
     
  // TODO you setup code 
  myservo1.attach(2);
  RemoteXY.slider_1 = 60;
  myservo2.attach(3);
  RemoteXY.slider_2 = 60;
  myservo3.attach(4);
  RemoteXY.slider_3 = 50;
  myservo4.attach(5);
  RemoteXY.slider_4 = 50;
  myservo5.attach(6);
  RemoteXY.slider_5 = 100;
  myservo6.attach(7);
  RemoteXY.slider_6 = 100;

  /* инициализация пинов */
  pinMode (PIN_MOTOR_RIGHT_UP, OUTPUT);
  pinMode (PIN_MOTOR_RIGHT_DN, OUTPUT);
  pinMode (PIN_MOTOR_LEFT_UP, OUTPUT);
  pinMode (PIN_MOTOR_LEFT_DN, OUTPUT);


}

void loop() 

  RemoteXY_Handler ();
   
  /* управляем правым мотором */
  Wheel (RightMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
  /* управляем левым мотором */
  Wheel (LeftMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x); 

  // TODO you loop code
  // use the RemoteXY structure for data transfer

    int ms1 = RemoteXY.slider_1*20+180; 
  myservo1.writeMicroseconds(ms1);

    int ms2 = RemoteXY.slider_2*50+200; 
  myservo2.writeMicroseconds(ms2);

    int ms3 = RemoteXY.slider_3*20+500; 
  myservo3.writeMicroseconds(ms3);

    int ms4 = RemoteXY.slider_4*20+500; 
  myservo4.writeMicroseconds(ms4);

    int ms5 = RemoteXY.slider_5*20+500; 
  myservo5.writeMicroseconds(ms5);

    int ms6 = RemoteXY.slider_6*20+500; 
  myservo6.writeMicroseconds(ms6);



 
}

3

Re: Управление Сервоприводом

кто может помочь с этой проблемой по ограничению угла поворота сервопривода и шага? или если эта проблема в этой программе не решается, то буду использовать другую sad

4

Re: Управление Сервоприводом

olegeglit wrote:

ограничению угла поворота сервопривода и шага

Функция map() не нравится? Элемент управления - слайдер? Шаг 0.01 градуса? оО

5

Re: Управление Сервоприводом

Функция map() нравится smile, но вот менять шаг нельзя,

подскажи, как точно выставить ограничения по углу сервы?

myservo.attach(9); 
  RemoteXY.slider_1 = 20; 
   

void loop()   
{   
  RemoteXY_Handler (); 

  // TODO you loop code 
  // use the RemoteXY structure for data transfer 

  int ms = RemoteXY.slider_1;
  ms = map(ms, 0, 100, 50, 100);
  myservo.write(ms);

6

Re: Управление Сервоприводом

1. Вычисляете целевой угол сервопривода:

target_angle = map(RemoteXY.slider_1, 0, 100, myservo1_L_ANGLE, myservo1_R_ANGLE );

2. Вычисляете текущий угол сервопривода

if (target_angle > curmyservo1Angle + myservo1_STEP) curmyservo1Angle +=myservo1_STEP;
else if (target_angle < curmyservo1Angle - myservo1_STEP) curmyservo1Angle -=myservo1_STEP;
else curmyservo1Angle = target_angle;

3. Устанавливаете текущее положение сервопривода

 myservo1.write(curmyservo1Angle);

PS. В приведенном примере возможно есть тех.ошибки, но думаю суть понятна.
Кроме того для более равномерного движения сервопривода шаг изменения угла в каждом цикле контроллера желательно синхронизировать с длительностью цикла по времени.

или если эта проблема в этой программе не решается, то буду использовать другую

RemoteXY вам возвращает текущее положение слайдера, и это ее основное назначения. Как вы поступите с этим положением и как вы его будите использовать для вычислений в ваших данных - это задача которую вы должны решить сами.

7

Re: Управление Сервоприводом

Спасибо, из другой ветки разобрался с проблемой управления мотором (Библиотека Servo позволяет одновременно управлять 12-ю сервоприводами на большинстве плат Arduino и 48-ю на Arduino Mega. На контроллерах отличных от Mega использование библиотеки отключает возможность использовать выходы 9 и 10 в режиме ШИМ даже если привод не подключен к этим выводам.)

8

Re: Управление Сервоприводом

olegeglit wrote:

Спасибо, из другой ветки разобрался с проблемой управления мотором (Библиотека Servo позволяет одновременно управлять 12-ю сервоприводами на большинстве плат Arduino и 48-ю на Arduino Mega. На контроллерах отличных от Mega использование библиотеки отключает возможность использовать выходы 9 и 10 в режиме ШИМ даже если привод не подключен к этим выводам.)

На ардуино нано подключил серво на 10 канал, с мотором через l293 всё глючит и зависает, по отдельности мотор и серва работают, не знаете в чём может быть проблема?

9

Re: Управление Сервоприводом

kdn567 wrote:

На ардуино нано подключил серво на 10 канал, с мотором через l293 всё глючит и зависает, по отдельности мотор и серва работают, не знаете в чём может быть проблема?

Возможно конфликт по таймерам-счетчикам которые одновременно пытается использовать библиотека Servo и ШИМ регулятор для управления мотором.