Скетч для управления телескопом

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Скетч для управления телескопом

Сообщение Mr.Kubikus »

Ок.

п.3 - Принято.
п.4 - То есть задаем скорость в исходном коде в виде константы?
С уважением, Григорий
GitHub FB ВК
Oleg1601
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Скетч для управления телескопом

Сообщение Oleg1601 »

Mr.Kubikus писал(а): п.4 - То есть задаем скорость в исходном коде в виде константы?
Ну да. Как встречал в некоторых скетчах - путем изменения числа delay() менялась скорость.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Скетч для управления телескопом

Сообщение Mr.Kubikus »

Итак мы договорились, что нам требуется получить в результате. Приступаем к доработке программы.

Для начала надо выкинуть все что находится между строками 66 и 90 - эта часть кода отвечает за движение механизма в момент инициализации системы. У нас такого требования нет. Поэтому смело выкидываем.

Добавляем переменную nMode - в ней будем хранить номер текущего режима работы. Их у нас два:
0 = РЕЖИМ 1 - управление от джойстика
1 = РЕЖИМ 2 - движение с заданной скоростью по одной оси
Для индикации режима используется светодиод LED на выходе D1

Добавляем функции phMotorRunMode1() и phMotorRunMode2() - они будут отвечать за управление ШД в разных режимах.

Еще нам понадобится конечный автомат, который будет переключать режимы каждый раз при нажатии кнопки BTN1. Переключение происходит после отпускания кнопки.
ВНИМАНИЕ! Вам надо перенести кнопку с входа A5 на вход D0.

Код: Выделить всё

/*
* PACPAC.RU 2015
*
* Для управления ШД в программе используется библиотека AccelStepper
* http://www.open.com.au/mikem/arduino/AccelStepper/index.html
*
*/


#include <AccelStepper.h>

// Назначение входов/выходов
// Шаговые двигатели

#define MOTOR1_DIR_PIN  8
#define MOTOR2_DIR_PIN  11

#define MOTOR1_STEP_PIN 9
#define MOTOR2_STEP_PIN 10

#define MOTOR1_SPR 200  // Кол-во шагов на 1 оборот вала двигателя
#define MOTOR2_SPR 200  

#define MOTOR1_MAX_SPEED 1000.0
#define MOTOR2_MAX_SPEED 1000.0

// Органы управления и индакация

#define MOTOR1_JOY_IN 0 // Ось Y джойстика
#define MOTOR2_JOY_IN 1 // Ось X джойстика
#define BTN1          0  // Кнопка РЕЖИМ 2 СТАРТ/СТОП
#define LED_MODE      1  // Индикатор режима:
                         // 0=РЕЖИМ 2 (светодиод горит)
                         // 1=РЕЖИМ 1 (светодиод не горит)


int     nMotor1SP, nMotor2SP;       // Задание направления от джойстика
int     nMode2SP;                   // Задание скорости для работы в РЕЖИМ 2
int     nMotor1MV, nMotor2MV;       // Задание скорости после ограничителя
int     nModeControllerState = 0;   // Текущее состояние конечного автомата ModeController
int     nMode = 0;                  // Текущий номер режима
                                    // 0=РЕЖИМ 1. Управление от джойстика
                                    // 1=РЕЖИМ 2. Движение с заданной скоростью по одной оси
bool    bBTN1Value;                 // Состояние кнопки BTN1

AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
AccelStepper stpMotor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);

void setup() {                
    phInit();
}

void loop() {
    static int nBTN1Counter;
    
    phGetCommand();
        
    switch (nModeControllerState) {
    
    case 0:
        if (bBTN1Value == false) {
          nBTN1Counter++;
        } else {
          nBTN1Counter = 0;
        }
        
        if ((bBTN1Value == false) && (nBTN1Counter > 30)) {
          nModeControllerState = 1;
          nBTN1Counter = 0;
        }
        break;
    
    case 1:
        if (bBTN1Value==true) {
            nModeControllerState = 2;
            nMode = 1;
            digitalWrite(LED_MODE, 0);            
        }
        break;

    case 2:
        if (bBTN1Value == false) {
          nBTN1Counter++;
        } else {
          nBTN1Counter = 0;
        }
        
        if ((bBTN1Value == false) && (nBTN1Counter > 30)) {
          nModeControllerState = 3;
          nBTN1Counter = 0;
        }
        break;
    
    case 3:
        if (bBTN1Value==true) {
            nModeControllerState = 0;
            nMode = 0;
            digitalWrite(LED_MODE, 1);
        }
        break;
        
    default:
        break;
    }
    
    switch (nMode) {
    case 0:
      phMotorRunMode1();
      break;
    case 1:
      phMotorRunMode2();
      break;
    default:
      break;
    }
}


void phInit()
{
    pinMode(MOTOR1_DIR_PIN, OUTPUT);
    pinMode(MOTOR2_DIR_PIN, OUTPUT);
    pinMode(MOTOR1_STEP_PIN, OUTPUT);
    pinMode(MOTOR2_STEP_PIN, OUTPUT);
    
    pinMode(BTN1, INPUT_PULLUP);
    pinMode(LED_MODE, OUTPUT);
    
    nMotor1MV = 0;
    nMotor2MV = 0;
    stpMotor1.setMaxSpeed(MOTOR1_MAX_SPEED);
    stpMotor2.setMaxSpeed(MOTOR2_MAX_SPEED);
    stpMotor1.setAcceleration(10.0);
    stpMotor2.setAcceleration(10.0);
    stpMotor1.setSpeed(0);
    stpMotor2.setSpeed(0);
    
    digitalWrite(LED_MODE, 1);
    
    return;
}

void phGetCommand()
{
    bBTN1Value = digitalRead(BTN1);
    
    nMotor1SP = analogRead(MOTOR1_JOY_IN) - 512; // Ось Y джойстика
    nMotor2SP = analogRead(MOTOR2_JOY_IN) - 512; // Ось X джойстика
    nMode2SP = 100;                              // Задание скорости для режима 2
    
    if ((nMotor1SP < -100) || (nMotor1SP > 100)) {
        nMotor1MV = nMotor1SP;
    } else {
        nMotor1MV = 0;
    }
    nMotor1MV = nMotor1MV * 1;  // Поменять на -1 если требуется реверс
    
    if ((nMotor2SP < -100) || (nMotor2SP > 100)) {
        nMotor2MV = nMotor2SP;
    } else {
        nMotor2MV = 0;
    }
    nMotor2MV = nMotor2MV * 1;  // Поменять на -1 если требуется реверс
    
}

void phMotorRunMode1()
{
    stpMotor1.setSpeed(nMotor1SP);  // Задаем скорость для мотора 1
    stpMotor2.setSpeed(nMotor2SP);  // Задаем скорость для мотора 2
    
    stpMotor1.runSpeed(); // Выполняем движение с заданной скоростью
    stpMotor2.runSpeed();
}

void phMotorRunMode2()
{
    stpMotor1.setSpeed(nMode2SP);   // Задаем скорость для мотора 1  
    stpMotor1.runSpeed(); // Выполняем движение с заданной скоростью
}
С уважением, Григорий
GitHub FB ВК
Oleg1601
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Скетч для управления телескопом

Сообщение Oleg1601 »

Супер!!! Спасибо огромное!
Одно только жаль, буду дома и смогу проверить работу только завтра, сейчас в отьезде.
Последний раз редактировалось Oleg1601 29 апр 2015, 16:02, всего редактировалось 1 раз.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Скетч для управления телескопом

Сообщение Mr.Kubikus »

Напишите потом - удалось запустить или нет. Я на самом деле не проверял на реальной железке.
С уважением, Григорий
GitHub FB ВК
Oleg1601
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Скетч для управления телескопом

Сообщение Oleg1601 »

Здравствуйте.
Сегодня проверил Вашу программу - заработало!
Работает как управление с джойстика, так и с кнопки - 1-го мотора с одной скоростью, индикации этого режима также работает.
Как я понял, скорость режима "ведения" (когда работает 1 мотор с заданной скоростью) регулируется изменением данных в пункте 149 nMode2SP

Теперь возникшие вопросы:
1. Меняя в пунктах 156 nMotor1MV = nMotor1MV * 1 и 163 nMotor2MV = nMotor2MV * 1 значения с 1 на -1 направление вращения моторов не менялось. Может я не так понял, но мне может понадобиться, в режиме "ведения" (когда работает 1 мотор с заданной скоростью) сменить направление на обратное, т.к. вращение с оси мотора будет идти через редуктор и может смениться на противоположное.
2. Светодиод горит когда режим ведения одним мотором выключен и гаснет когда включен, хотелось бы наоборот.
3. Также, как и ранее, заметил, что моторы ( в режиме стоп - джойстик в нейтральном положении) всё-же медленно вращаются - 1-ый -против часовой стрелки (за 1,5 минуты - четверть оборота), 2-ой -по часовой (четверть оборота - за 5минут). Как устранить это?
4. Можно ли увеличить максимальную скорость вращения моторов при управлении от джостика, сейчас на полный оборот, на максимуме, секунды за 4-е?
Жду Вашего ответа!
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Скетч для управления телескопом

Сообщение Mr.Kubikus »

Привет!

Очень рад, что заработало сразу. Теперь по порядку.

1. Тут все верно. Реверс вращения можно задать в строках 158 и 165. Просто поставьте -1 там где это требуется. В предыдущей версии это не работает т.к. в мой программе ошибка в строках 169-170. Вместо переменных nMotor1SP и nMotor2SP надо использовать nMotor1MV и nMotor2MV. По этой же причине сейчас происходит то, что вы описали в п . 3. Ошибки я исправил в коде, который приведен ниже.
2. Подключите анод светодиода к +5V, а катод через резистор 330 Ом к пину D1. В алгоритме предполагается такая схема подключения.
3. См. п. 1.
4. Я изменил программу. Теперь максимальную скорость моторов в режиме 1 можно увеличить в строках 24 и 25
5. Скорость в режиме 2 можно изменить в строке 27.

Код: Выделить всё

/*
* PACPAC.RU 2015
*
* Для управления ШД в программе используется библиотека AccelStepper
* http://www.open.com.au/mikem/arduino/AccelStepper/index.html
*
*/


#include <AccelStepper.h>

// Назначение входов/выходов
// Шаговые двигатели

#define MOTOR1_DIR_PIN  8
#define MOTOR2_DIR_PIN  11

#define MOTOR1_STEP_PIN 9
#define MOTOR2_STEP_PIN 10

#define MOTOR1_SPR 200  // Кол-во шагов на 1 оборот вала двигателя
#define MOTOR2_SPR 200  

#define MOTOR1_MAX_SPEED 1000.0
#define MOTOR2_MAX_SPEED 1000.0

#define MODE2_MAX_SPEED 100.0

// Органы управления и индакация

#define MOTOR1_JOY_IN 0 // Ось Y джойстика
#define MOTOR2_JOY_IN 1 // Ось X джойстика
#define BTN1          0  // Кнопка РЕЖИМ 2 СТАРТ/СТОП
#define LED_MODE      1  // Индикатор режима:
                         // 0=РЕЖИМ 2 (светодиод горит)
                         // 1=РЕЖИМ 1 (светодиод не горит)


int     nMotor1SP, nMotor2SP;       // Задание направления от джойстика
int     nMode2SP;                   // Задание скорости для работы в РЕЖИМ 2
int     nMotor1MV, nMotor2MV;       // Задание скорости после ограничителя
int     nModeControllerState = 0;   // Текущее состояние конечного автомата ModeController
int     nMode = 0;                  // Текущий номер режима
                                    // 0=РЕЖИМ 1. Управление от джойстика
                                    // 1=РЕЖИМ 2. Движение с заданной скоростью по одной оси
bool    bBTN1Value;                 // Состояние кнопки BTN1

AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
AccelStepper stpMotor2(AccelStepper::DRIVER, MOTOR2_STEP_PIN, MOTOR2_DIR_PIN);

void setup() {                
    phInit();
}

void loop() {
    static int nBTN1Counter;
    
    phGetCommand();
        
    switch (nModeControllerState) {
    
    case 0:
        if (bBTN1Value == false) {
          nBTN1Counter++;
        } else {
          nBTN1Counter = 0;
        }
        
        if ((bBTN1Value == false) && (nBTN1Counter > 30)) {
          nModeControllerState = 1;
          nBTN1Counter = 0;
        }
        break;
    
    case 1:
        if (bBTN1Value==true) {
            nModeControllerState = 2;
            nMode = 1;
            digitalWrite(LED_MODE, 0);            
        }
        break;

    case 2:
        if (bBTN1Value == false) {
          nBTN1Counter++;
        } else {
          nBTN1Counter = 0;
        }
        
        if ((bBTN1Value == false) && (nBTN1Counter > 30)) {
          nModeControllerState = 3;
          nBTN1Counter = 0;
        }
        break;
    
    case 3:
        if (bBTN1Value==true) {
            nModeControllerState = 0;
            nMode = 0;
            digitalWrite(LED_MODE, 1);
        }
        break;
        
    default:
        break;
    }
    
    switch (nMode) {
    case 0:
      phMotorRunMode1();
      break;
    case 1:
      phMotorRunMode2();
      break;
    default:
      break;
    }
}


void phInit()
{
    pinMode(MOTOR1_DIR_PIN, OUTPUT);
    pinMode(MOTOR2_DIR_PIN, OUTPUT);
    pinMode(MOTOR1_STEP_PIN, OUTPUT);
    pinMode(MOTOR2_STEP_PIN, OUTPUT);
    
    pinMode(BTN1, INPUT_PULLUP);
    pinMode(LED_MODE, OUTPUT);
    
    nMotor1MV = 0;
    nMotor2MV = 0;
    stpMotor1.setMaxSpeed(MOTOR1_MAX_SPEED);
    stpMotor2.setMaxSpeed(MOTOR2_MAX_SPEED);
    stpMotor1.setAcceleration(10.0);
    stpMotor2.setAcceleration(10.0);
    stpMotor1.setSpeed(0);
    stpMotor2.setSpeed(0);
    
    digitalWrite(LED_MODE, 1);
    
    return;
}

void phGetCommand()
{
    bBTN1Value = digitalRead(BTN1);
    
    nMotor1SP = analogRead(MOTOR1_JOY_IN) - 512; // Ось Y джойстика
    nMotor2SP = analogRead(MOTOR2_JOY_IN) - 512; // Ось X джойстика
    nMode2SP = MODE2_MAX_SPEED;                  // Задание скорости для режима 2
    
    if ((nMotor1SP < -100) || (nMotor1SP > 100)) {
        nMotor1MV = map(nMotor1SP, -512, 511, -1*MOTOR1_MAX_SPEED, MOTOR1_MAX_SPEED);
    } else {
        nMotor1MV = 0;
    }
    nMotor1MV = nMotor1MV * 1;  // Поменять на -1 если требуется реверс
    
    if ((nMotor2SP < -100) || (nMotor2SP > 100)) {
        nMotor2MV = map(nMotor2SP, -512, 511, -1*MOTOR2_MAX_SPEED, MOTOR2_MAX_SPEED);        
    } else {
        nMotor2MV = 0;
    }
    nMotor2MV = nMotor2MV * 1;  // Поменять на -1 если требуется реверс
    
}

void phMotorRunMode1()
{
    stpMotor1.setSpeed(nMotor1MV);  // Задаем скорость для мотора 1
    stpMotor2.setSpeed(nMotor2MV);  // Задаем скорость для мотора 2
    
    stpMotor1.runSpeed(); // Выполняем движение с заданной скоростью
    stpMotor2.runSpeed();
}

void phMotorRunMode2()
{
    stpMotor1.setSpeed(nMode2SP);   // Задаем скорость для мотора 1  
    stpMotor1.runSpeed(); // Выполняем движение с заданной скоростью
}
С уважением, Григорий
GitHub FB ВК
Oleg1601
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Скетч для управления телескопом

Сообщение Oleg1601 »

Приветствую!
Спасибо за оперативный ответ! Большинство проблем сразу отпало :)
Остался не решенным только один момент: как менять направление движения в РЕЖИМЕ 2 - движение с заданной скоростью по одной оси МОТОРА 1
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Скетч для управления телескопом

Сообщение Mr.Kubikus »

Направление можно поменять если в строке 151 MODE2_MAX_SPEED умножить на -1.
С уважением, Григорий
GitHub FB ВК
Oleg1601
Сообщения: 47
Зарегистрирован: 26 апр 2015, 11:25

Re: Скетч для управления телескопом

Сообщение Oleg1601 »

Проверил - так и есть!
Теперь, всё СУПЕР!
ОГРОМНОЕ ВАМ СПАСИБО за неоценимую помощь в создании этого проека - сам бы я не в жизнь такого не сделал!
СПАСИБО!
Ответить