A A A A Автор Тема: DIY экваториальная монтировка под 15кг телескоп-рефлектор maxvisiOn 254/1270  (Прочитано 21010 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Хейтерам использования delayMicroseconds в выполнении шага мотора - скетч на управление моторов влево-вправо в двух скоростном режиме.
Кнопки в режиме - нажал-отпустил а не зажал.
#include <PinChangeInterrupt.h>
#include <TimerOne.h>

#define dirPin 2           // Пин для управления направлением
#define stepPin 3          // Пин для управления шагами
#define BtnLeft 4          // Пин, к которому подключена кнопка для включения/выключения мотора
#define BtnRight 5         // Пин, к которому подключена кнопка для смены направления
#define BtnSwitchSpeed 6   // Пин, к которому подключена кнопка для смены скорости

volatile bool motorRunning = false;     // Флаг, указывающий на состояние мотора
volatile bool motorDirection = HIGH;    // Переменная для хранения направления мотора
volatile int delayTime = 300;           // Переменная для хранения времени задержки (скорость вращения) в микросекундах

void setup() {
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(BtnLeft, INPUT_PULLUP);      // Включаем внутренний подтягивающий резистор для кнопки включения/выключения
  pinMode(BtnRight, INPUT_PULLUP);     // Включаем внутренний подтягивающий резистор для кнопки смены направления
  pinMode(BtnSwitchSpeed, INPUT_PULLUP); // Включаем внутренний подтягивающий резистор для кнопки смены скорости

  // Устанавливаем прерывания для всех кнопок
  attachPinChangeInterrupt(BtnLeft, toggleMotor, FALLING); // Прерывание на нажатие кнопки включения/выключения
  attachPinChangeInterrupt(BtnRight, changeDirection, FALLING); // Прерывание на нажатие кнопки смены направления
  attachPinChangeInterrupt(BtnSwitchSpeed, toggleSpeed, FALLING); // Прерывание на нажатие кнопки смены скорости

  // Настройка таймера 1
  Timer1.initialize(delayTime); // Устанавливаем интервал таймера в микросекундах
  Timer1.attachInterrupt(stepPulse); // Прерывание по таймеру
}

// Функция для обработки импульсов шага
void stepPulse() {
  if (motorRunning) {
    digitalWrite(stepPin, HIGH); // Подаем импульс
    // Задержка для импульса больше не нужна, так как таймер уже контролирует интервал
    digitalWrite(stepPin, LOW);  // Сбрасываем импульс
  }
}

// Прерывание для переключения состояния мотора
void toggleMotor() {
  motorRunning = !motorRunning; // Переключаем состояние мотора

  if (motorRunning) {
    digitalWrite(dirPin, motorDirection); // Устанавливаем направление один раз при запуске
    Timer1.setPeriod(delayTime); // Обновляем интервал таймера
    Timer1.start(); // Запускаем таймер
  } else {
    Timer1.stop(); // Останавливаем таймер, если мотор не работает
  }
}

// Прерывание для смены направления вращения
void changeDirection() {
  motorDirection = !motorDirection; // Переключаем направление
  digitalWrite(dirPin, motorDirection); // Меняем направление в реальном времени
}

// Прерывание для смены скорости вращения
void toggleSpeed() {
  delayTime = (delayTime == 300) ? 600 : 300; // Переключаем задержку-скорость вращения мотора
  if (motorRunning) {
    Timer1.setPeriod(delayTime); // Обновляем интервал таймера
  }
}

void loop() {
  // Вы можете оставить здесь дополнительный код или логику, если требуется
}
Утверждается, что мотор будет управляться кнопками при пустом loop()  :o

Блин, БП/АКБ и моторы не рядом не могу потестить это творчество ChatGPT  :-\

Оффлайн user340

  • ****
  • Сообщений: 379
  • Благодарностей: 45
    • Сообщения от user340
Утверждается, что мотор будет управляться кнопками при пустом loop()  :o

Блин, БП/АКБ и моторы не рядом не могу потестить это творчество ChatGPT :-\

Детально разбираться в ботве, которую ChatGPT генерит, желания, конечно, нет.
Но - в коде есть намёки на объявление прерываний, поэтому, не вижу причин, по которым он теоретически не сможет работать с пустым loop().

Всё-таки, учить работу МК лучше по даташитам, книгам и статьям, а не по сгенерённому ChatGPT коду.
« Последнее редактирование: 13 Авг 2024 [04:55:24] от user340 »

Оффлайн user340

  • ****
  • Сообщений: 379
  • Благодарностей: 45
    • Сообщения от user340
Дополню примером, написанным человеком (надо сказать, весьма низкоуровневый пример).
Код, кстати, без внешних зависимостей в виде подключаемых h-файлов.
Вот тут, например, светодиод моргает с пустым loop():

*
  Date: 23-01-21
  Code written by: Dharmik
  LED blink code using hardware timer interrupt
  This method only work for Digital pin 9
  Code is non blocking code and tested on Arduino UNO, Nano
  Code uses 634 bytes of program memory and Global variables use 9 bytes
  Find more on [url=http://www.TechTOnions.com]www.TechTOnions.com[/url]
*/

#define LED 9
void setup() {
  pinMode(LED, OUTPUT);

  TCCR1A = 0;               //Reset Timer1 control Registor A

  bitClear(TCCR1B, WGM13);  //Set CTC mode
  bitSet(TCCR1B, WGM12);

  bitSet(TCCR1B, CS12);    //Set prescaler to 1024
  bitClear(TCCR1B, CS11);
  bitSet(TCCR1B, CS10);

  //set compare value
  //max value  (16bit Timer) = 65535
  /*******************************************
    To calculate compare value
    OCR1A = (time(s) * clock Freq.)/prescaler
    OCR1A = (1*16*10^6)/1024
  ********************************************/
  //OCR1A = 3906;     //for 0.25sec
  //OCR1A = 7812;    //for 0.5sec
  OCR1A = 15625;   //for 1sec
  //OCR1A = 31250;   //for 2sec

  //  OCR1A= 62500;
  bitSet(TCCR1A, COM1A0); // Toggle pin OC1A (9)
}

void loop()
{
}
« Последнее редактирование: 13 Авг 2024 [03:37:04] от user340 »

Оффлайн user340

  • ****
  • Сообщений: 379
  • Благодарностей: 45
    • Сообщения от user340
Mistpal тут прям буквально недавно в соседней теме про прерывания было (по таймерам, в контексте управления монтировкой), вот человек их для себя открыл и осознал:
https://astronomy.ru/forum/index.php/topic,176244.msg6116039.html#msg6116039

Ну и ссылка на статью "Arduino и прерывания таймера", которую в той беседе дали:
https://habr.com/ru/articles/453276/
« Последнее редактирование: 13 Авг 2024 [03:16:27] от user340 »

Оффлайн FlexLM

  • ****
  • Сообщений: 323
  • Благодарностей: 48
    • Сообщения от FlexLM
    • AMount - cистема управления телескопом
В пустом loop() нет ничего страшного :) На самом деле после loop() ардуина в бесконечном цикле for( ; ; ) ещё проверяет последовательный порт в serialEventRun().
Основная функция main(), а там setup() и loop()...
(кликните для показа/скрытия)

Оффлайн Laplase

  • *****
  • Сообщений: 1 715
  • Благодарностей: 144
  • engineer
    • Сообщения от Laplase
    • vkontakte
Офигел от люфтов редукторов. Вы были правы на счет шестерён даже прецизионного качества. В самом начале мне нужно было проверить люфт шестерён не пальцами, т.к. момента не хватало на проворот...
да, да, я говорил. Планетарка эта та же шестеренчатая передача, и чтобы там китацы не писали, люфт на болшом рычаге будет ощутим. Причем это люфт на выходном валу, и с ним уже ничего не сделаешь.
GSO 150/750 Photo, APO DeepSky 80/480, DIY Harmonic mount, EQ6-Pro, AzGti-EQ, ASI1600MM

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
тут прям буквально недавно в соседней теме про прерывания было
спасибо

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Основная функция main(), а там setup() и loop()...
вот теперь понятнее
спасибо

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
и с ним уже ничего не сделаешь.
сейчас соосность пар подшипников 25мм валов отличная так, что вращается очень легко и даже продолжает вращаться коробки по инерции, т.е. с этим люфтом и с балансированной нагрузкой телескоп болтается легко. Похоже в этой ситуации можно лишь сделать две вещи:
1) Нарушить слегка баланс чтобы перевешивал телескоп по полярной оси а по оси склоенения зад телескопа
2) Искусственно создать сопротивление вращения валам (редуктора переварят усилия) чтобы не было свободного хода
тогда должно более менее сносно наводить даже вручную (с проворотом редуктор-шд) без этой бесячей болтанки от люфта.

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Так-то конечно следующая цель по этой монтировке - переход на червячную пару. Пока смотрю на АлиЭкспресс, задал одному магазину вопрос про люфт пары, отписались пока что "проверим" и тишина.
Мне кажется я дойду до этого вопроса как только ударюсь в токаря (осень 2024 - весна 2025).

Оффлайн user340

  • ****
  • Сообщений: 379
  • Благодарностей: 45
    • Сообщения от user340
спасибо

Да незачто. Надеюсь, будете не против - добавлю ещё чуть образных мыслей про прерывания.

(кликните для показа/скрытия)
« Последнее редактирование: 16 Авг 2024 [16:12:54] от user340 »

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
прерывания
хорошая штука
на нём повесил три кнопки: слежение, коррекция скорости слежения -/+
#include <PinChangeInterrupt.h>

#define dirPin 2           // Пин для управления направлением
#define stepPin 3          // Пин для управления шагами
#define BtnLeft 4          // Пин, к которому подключена кнопка для вращения мотора в одну сторону
#define BtnRight 5         // Пин, к которому подключена кнопка для вращения мотора в другую сторону
#define BtnSwitchSpeed 6   // Пин, к которому подключена кнопка для смены скорости
#define BtnGuide 7         // Пин, к которому подключена кнопка для запуска слежения
#define BtnGuideSpeedMinus 8 // Пин, к которому подключена кнопка для уменьшения скорости слежения
#define BtnGuideSpeedPlus 9  // Пин, к которому подключена кнопка для увеличения скорости слежения

volatile bool motorRunning = false;
volatile bool motorDirection = HIGH;
volatile int delayTime = 300;
volatile int GuideDelayTime = 200;
volatile bool guideMode = false;

unsigned long lastPressTimeMinus = 0;   // Время последнего нажатия BtnGuideSpeedMinus
unsigned long lastPressTimePlus = 0;    // Время последнего нажатия BtnGuideSpeedPlus
unsigned long lastSwitchSpeedTime = 0;  // Время последнего нажатия BtnSwitchSpeed
unsigned long lastGuideModeTime = 0;    // Время последнего нажатия BtnGuide
const unsigned long debounceDelay = 200; // Дебаунс задержка в миллисекундах

void setup() {
  Serial.begin(9600); // Инициализация последовательного порта для логирования

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(BtnLeft, INPUT_PULLUP);
  pinMode(BtnRight, INPUT_PULLUP);
  pinMode(BtnSwitchSpeed, INPUT_PULLUP);
  pinMode(BtnGuide, INPUT_PULLUP);
  pinMode(BtnGuideSpeedMinus, INPUT_PULLUP);
  pinMode(BtnGuideSpeedPlus, INPUT_PULLUP);

  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(BtnGuide), toggleGuideMode, CHANGE);
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(BtnGuideSpeedMinus), checkGuideSpeedMinus, CHANGE);
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(BtnGuideSpeedPlus), checkGuideSpeedPlus, CHANGE);
}

void stepMotor(int delayTime) {
  digitalWrite(stepPin, HIGH);     
  delayMicroseconds(delayTime);     
  digitalWrite(stepPin, LOW);       
  delayMicroseconds(delayTime);     
}

void toggleSpeed() {
  unsigned long currentTime = millis();
  if ((currentTime - lastSwitchSpeedTime) >= debounceDelay) {
    lastSwitchSpeedTime = currentTime;
    delayTime = (delayTime == 300) ? 600 : 300;
    Serial.print("Speed switched to: ");
    Serial.println(delayTime); // Логирование нового значения delayTime
  }
}

void toggleGuideMode() {
  unsigned long currentTime = millis();
  if ((currentTime - lastGuideModeTime) >= debounceDelay) {
    lastGuideModeTime = currentTime;
    guideMode = !guideMode;  // Переключаем режим слежения
    motorRunning = guideMode; // Включаем/выключаем мотор в зависимости от guideMode
    Serial.print("GuideMode set to: ");
    Serial.println(guideMode); // Логирование нового состояния guideMode
  }
}

void checkGuideSpeedMinus() {
  if (digitalRead(BtnGuideSpeedMinus) == LOW) {
    unsigned long currentTime = millis();
    if (currentTime - lastPressTimeMinus >= debounceDelay) {
      lastPressTimeMinus = currentTime;
      decreaseGuideSpeed();
    }
  }
}

void checkGuideSpeedPlus() {
  if (digitalRead(BtnGuideSpeedPlus) == LOW) {
    unsigned long currentTime = millis();
    if (currentTime - lastPressTimePlus >= debounceDelay) {
      lastPressTimePlus = currentTime;
      increaseGuideSpeed();
    }
  }
}

void decreaseGuideSpeed() {
  if (GuideDelayTime > 50) { // Устанавливаем минимальное значение задержки
    GuideDelayTime--;  // Уменьшаем скорость слежения
    Serial.print("GuideDelayTime decreased to: ");
    Serial.println(GuideDelayTime); // Логирование нового значения GuideDelayTime
  } else {
    Serial.println("GuideDelayTime сannot be decreased further: ");
    Serial.println(GuideDelayTime);
  }
}

void increaseGuideSpeed() {
  GuideDelayTime++;  // Увеличиваем скорость слежения
  Serial.print("GuideDelayTime increased to: ");
  Serial.println(GuideDelayTime); // Логирование нового значения GuideDelayTime
}

void loop() {
  if (digitalRead(BtnSwitchSpeed) == LOW) {
    toggleSpeed();
  }

  // Управление вращением мотора при зажатии кнопок BtnLeft или BtnRight
  if (digitalRead(BtnLeft) == LOW) {
    motorDirection = HIGH;
    digitalWrite(dirPin, motorDirection);
    while (digitalRead(BtnLeft) == LOW) {  // Мотор вращается, пока удерживается BtnLeft
      stepMotor(delayTime);
    }
  } else if (digitalRead(BtnRight) == LOW) {
    motorDirection = LOW;
    digitalWrite(dirPin, motorDirection);
    while (digitalRead(BtnRight) == LOW) {  // Мотор вращается, пока удерживается BtnRight
      stepMotor(delayTime);
    }
  }

  // Вращение в режиме слежения, если активирован guideMode и не нажаты другие кнопки
  if (guideMode && digitalRead(BtnLeft) == HIGH && digitalRead(BtnRight) == HIGH) {
    digitalWrite(dirPin, motorDirection);
    stepMotor(GuideDelayTime);
  }
}


без   if (GuideDelayTime > 50) { // Устанавливаем минимальное значение задержки
моя любознательность убила Ардуинку когда кнопкой дошёл до единицы микросекунды, чип мгновенно нагрелся и вышел из строя  :-\

Оффлайн user340

  • ****
  • Сообщений: 379
  • Благодарностей: 45
    • Сообщения от user340
хорошая штука
на нём повесил три кнопки: слежение, коррекция скорости слежения -/+

Хороший прогресс!
Тогда уже и коментарии по прерываниям будут излишни - вы с ними вполне быстро разобрались! 👍

А то что ардуинка померла - бывает, тоже периодически палю.
Зато не скучно, приходит понимание, а за ним и прогресс.

Удачи вам в экспериментах! Ваш проект интересный!

Оффлайн Sergey70

  • ***
  • Сообщений: 227
  • Благодарностей: 301
  • Мне нравится этот форум!
    • Сообщения от Sergey70
Похоже в этой ситуации можно лишь сделать две вещи:
1) Нарушить слегка баланс чтобы перевешивал телескоп по полярной оси а по оси склоенения зад телескопа
2) Искусственно создать сопротивление вращения валам (редуктора переварят усилия) чтобы не было свободного хода
              А ведь вас предупреждали... Ваши последние идеи тоже тупиковые, с электроникой похоже у вас все хороше, а вот понимания как работает точная механика нет,разбираем по пунктам: 1) сместили баланс. что из этого выйдет?, включили мотор, мотор выбрал свободный ход на редукторе, а конец трубы все еще находится в состоянии покоя и тут он получает пинка от привода, преодолев момент страгивания труба пойдет , допустим в верх, люфт то редуктора никуда не делся, поэтому труба продолжит двигаться уже по инерции до тех пор пока не лязгнут зубы редуктора, закончился свободный ход, конец трубы резко тормозит и возникает противоход и за счет того же люфта трубу откинет назад и так из раза в раз. По скольку наводится вы хотите в ручную то процедура превратится в пытку, Короче станет только хуже.
           2) торможение в принципе ничем не поможет, по сути получаем тоже самое что в п.1 только в профиль.
           ВЫход видится в другом, программно регулировать скорость разгона привода, вот вам и карты в руки, у меня на монтировке готовое решение по электронике, и разгон установлен 10 секунд, труба к стати тоже 12" и на таких массах и рычагах при слабой механике это реально лучше чем ничего.
           И оставте розовые мечты о червячной паре да еще и с Али, такое впечатление что вы совсем себе слабо представляете разницу между общепромышленными узлами и агрегатами и ими же только изготовленными из требований оптики, вот вы камерку классную прикупили, астрономическую, а какой у нее размер пикселя? 1.5-3  микрона? вот с такой точностью должна и двигаться ваша монтировка, и с такой точностью должна быть изготовлена червячная пара.
          Или выход номер два  -это переход к гармоническим редукторам, Олег Чекалин как раз начал новую тему.
Телескоп DOB12", 1\5, окуляры Meade Series 5000 UWA  14, 8.8 мм и Celestron Luminos 7 мм, 23мм  все окуляры 82гр. + ЛБ2х 2"ЕД,

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
На прошедших выходных дёрнул на озеро Сонкуль сюда
Но с погодой не свезло, только на второй день в полночь ветер утихомирился но облака закрывали небо. Только к 9 утра облака кончились по закону подлости  :D
В итоге свет увидела только монтировка, телескоп даже не вытаскивал из коробки.
Грунтовую дорогу зеркала перенесли без последствий, чего не скажешь о генераторе и трамблёре авто  ;D
« Последнее редактирование: 23 Авг 2024 [11:00:13] от Mistpal »

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Сегодня выдвигаюсь в другую область на озеро Иссык-Куль
Точка наблюдения #1
Точка наблюдения #2

Оффлайн Fatalik

  • Модератор
  • *****
  • Сообщений: 10 087
  • Благодарностей: 2108
  • Алексей
    • Instagram: fatalerror83
    • DeepSkyHosting: id8
  • Награды Неоднократный победитель конкурса астрофото
    • Сообщения от Fatalik
зачем нам координаты точек наблюдений )) лучше про монти )
как прошло .. какие выводы... если погоды небыло и не прошло ничего ... то и подождать ))

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Вернулся с вылазки. Удалось испытать только в Субботу. Насмотрелись на Луну и Сатурн, позже на Юпитер. Телескоп юстировать и юстировать, только лазерным настроил главное зеркало а позже в темноте посмотрел через чешир и офигел) Оставил в другой ясный день для этого.
Мастхев закрепить зелёный лазер для наведения на объект - очень удобно наводить чем через искатель.


Касательно монтировки:
1) Люфты осей никуда не делись, но с тормозом люфта оси склонения при управлении мотором куда-то пропал. Как такое возможно? Буквально жму влево - начинается движение сразу. Нажимаю вправо - начинается движение сразу! На полярной оси ожидаемо есть задержка перед движением в противоположную сторону.
2) Качки из-за выборки люфта, инерции нет или был не заметен глазу. Видимо из-за того что зарезал скорости наведения раза в два т.к. слишком быстро менялась картинка
3) Колонну коробки полярной оси надо еще разжать, задолбался собирать и разбирать.
4) Через полтора часа активной работы пульт/мозги начали глючить, включался мотор полярной оси по кнопке наведения. Перезапуск не помогает. Осмотрел ещё раз внутренности - ни росы, ни насекомых. Непонятно что заставляет Ардуино детектировать падение напряжение на D5 выводе. Если отключить питание на 15-20минут, то после включения штатно работает управление, но буквально через пару минут опять начинает глючить Ардуино полярной оси... Очень очень захотелось на тот момент поменять шаговики на обычные коллекторные моторы с регулятором напряжения для простых визуальных наблюдений...
5) Монтировка одна, но процесс сборки и разборки это поход к машине за:
а) ногами
б) колонной
в) коробки полярной и оси склонения
г) поиск крепежа
Надо бы сделать чехол с карманами под мелочевку - крепеж, малый инструмент и т.д.
Кроме него сам телескоп, чемодан с аксессуарами и др. не вошедшие в него...
Короче надо еще продумать и этот вариант, на 1688.com видел дипломаты целые с продуманными пазами под разное.

Астрокамера наконец заработала, точнее показала картинку. Оказывается он был посажен глубоко, даже максимальный вылет фокусёра не было достаточно. Когда надоело смотреть на смазанный образ Луны вытащил камеру до середины и сразу проявилась картинка!
https://youtu.be/w-YcVj18TWo
« Последнее редактирование: 26 Авг 2024 [12:08:07] от Mistpal »

Оффлайн Jozef

  • **
  • Сообщений: 68
  • Благодарностей: 9
  • Мне нравится этот форум!
    • Сообщения от Jozef
Луна что-то сильно болтается...

Оффлайн MistpalАвтор темы

  • ****
  • Сообщений: 389
  • Благодарностей: 4
  • Мне нравится этот форум!
    • Сообщения от Mistpal
Луна что-то сильно болтается...
ручное наведение, люфты, инерция  :-\