QQ登录

只需一步,快速开始

[自制DIY] 再做一个简单的电调焦

[复制链接]
tianyuan08 发表于 2020-4-2 23:53 | 显示全部楼层 |阅读模式 来自: 中国–甘肃–兰州 电信

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?加入牧夫(请注明天文爱好者,否则无法通过审核,请勿使用gmail/outlook/aol/icloud邮箱注册)

×
本帖最后由 tianyuan08 于 2020-4-2 23:57 编辑

前一阵心热,给晶华的JE100A赤道仪自制了一个电跟,[url=自制单轴电跟的基础 http://bbs.imufu.cn/forum.php?mo ... 2119&fromuid=340351 (出处: 牧夫天文论坛(中国最早的天文论坛,致力于天文和望远镜的科普交流平台))]http://bbs.imufu.cn/forum.php?mod=viewthread&tid=792119&fromuid=340351[/url],乘着热度还没减,又搞了一个电调焦出来,避免调焦的抖动,和大家分享一下,技术含量比较低,大神勿笑

主要的材料包括:(1) TITAN 42步进电机一个,保持力矩0.12NM;(2) 2GT同步轮,16、48齿,齿比1:3;(3)2GT同步带,154周长,支持中心距44.5左右;(4)铝合金孔6法兰联轴器一个;(5)铝合金 5mm-5mm 刚性联轴器一个;(6)5mm、6mm不锈钢轴各一个;(7)热弯的亚克力步进电机支架一个;

另外由于赤经已经有一个电机了,现在要控制两个电机,所以将上次步进电机驱动器TB6600换掉了,改成了CNC SHIELD V3数控板+2个A4988驱动器,又添了一个4*4的单片机矩阵键盘用来做控制器,程序还是烧到arduino里,赤经轴电机仍然通过TIMER1发送脉冲,调教座电机则通过键盘长按控制。

下面这张图就是控制逻辑了,红色大板是cnc shield v3,直接插在了arduino uno r3上面,装了两块a4988(带散热片的那个),能够独立控制两个步进电机,把矩阵键盘接在cnc shield v3上,其引脚实际是接在arduino上的。
wx_camera_1585640777128.jpg

安装48齿同步轮到调焦手轮上用了一个简单粗暴的办法,直接把法兰联轴器用AB胶粘在手轮上,再插入轴,装上同步轮就好了~~~
IMG20200402205215.jpg

为了减轻重量,用亚克力板做了一个42步进电机支架,孔位则是按照调焦座下方顶住调焦杆的4颗螺丝位置开的,亚克力板厚度5mm~
wx_camera_1585797124018.jpg

安装的时候发现两轴距离之前算错了...同步带买长了,重新计算后,给亚克力支架上用AB胶粘了两个M6螺丝,这下就刚好了,选择TITAN 42步进电机,主要是因为轻啊,而且保持力矩0.12NM也还行,再加个1:3的齿比,绝对没问题! IMG20200402205237.jpg


实际效果:通过条线设置两个a4988都是16细分,减少电机震动。在矩阵键盘上设置了7个按键,S1控制两个电机使能开关,S2是赤经电机开关,S3是调焦电机开关,S4和S5长按后,将输出1000HZ频率的脉冲,使得调焦电机可以快速旋转,S7和S8按住,则是以100HZ的频率发送脉冲,使调焦电机微速旋转。控制赤经的脉冲通过arduino的TIMER1中断给出的,而控制电调的直接用了delay和delayMicroseconds,实际是TIMER0,由于TIMER1的中断优先级高于TIMER0,所以赤经电机是不会受到电调电机的影响。测试了一下,对焦的时候全程无抖动,很爽!使用步进电机还有一个好处,可以在调焦筒伸出的时候对脉冲数计数,收回的时候,对计数值递减,当计数值为0的时候,就不再发送脉冲给电机,避免调焦筒撞到调焦座,有可能损坏电机、齿轮、皮带~~不过这部分程序还没做,有空改一改.

附上自己写的用arduino+cnc shield v3+a4988+矩阵键盘搞的控制程序,需要用到arduino的time_one和keypad附加库:

#include <Key.h>
#include <Keypad.h>
#include <TimerOne.h>

//define ena for all motors
#define ENA_PIN 8

//define motor pins
#define XDIR_PIN 5
#define YDIR_PIN 6
#define XSTEP_PIN 2
#define YSTEP_PIN 3

//define keypad rows and cols
#define ROWS 3
#define COLS 3

//define a keymap
unsigned char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'}
};

//row->pin, col->pin
byte rowPins[ROWS] = {A3, 13, 12};
byte colPins[COLS] = {A2, A1, A0};

//register keymap and pins
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

//XPUL_STATE保存X电机驱动电平状态
volatile byte XPUL_STATE = LOW;

//X电机,Y电机开关
volatile byte XMOTOR_TOGGLE = LOW;
volatile byte YMOTOR_TOGGLE = LOW;

//电机使能开关
volatile byte ENA_TOGGLE = HIGH;

//Y电机状态,指示哪个键被长按
volatile unsigned char YMOTOR_STATE = 0;

void setup() {
  //set pin mod
  pinMode(ENA_PIN, OUTPUT);
  pinMode(XDIR_PIN, OUTPUT);
  pinMode(XSTEP_PIN, OUTPUT);
  pinMode(YDIR_PIN, OUTPUT);
  pinMode(YSTEP_PIN, OUTPUT);
  //set pin value
  digitalWrite(ENA_PIN, ENA_TOGGLE);
  digitalWrite(XDIR_PIN, HIGH);
  //设置timer1的频率为32HZ,则每31.25ms触发一次
  Timer1.initialize(31250);
  Timer1.attachInterrupt(timer1_ISR);
  //set keypad listener
  keypad.addEventListener(keypadEvent);
  //set hold dealy
  keypad.setHoldTime(500);
  //set serail
  Serial.begin(9600);
}

//timer1的触发频率为32HZ,也就是1秒触发32次高低电平转换,则1秒为16HZ的方波信号,600秒产生9600个周期
void timer1_ISR()
{
  if (XMOTOR_TOGGLE == HIGH)
  {
    XPUL_STATE = !XPUL_STATE;
    digitalWrite(XSTEP_PIN, XPUL_STATE);
  }
}

void loop() {
  //listern keypad
  keypad.getKey();
  //drive Y-MOTOR
  switch(YMOTOR_STATE)
  {
    //长按按键4、5,产生1000HZ的方波
    case '4':
    case '5':
      digitalWrite(YSTEP_PIN, HIGH);
      delayMicroseconds(500);
      digitalWrite(YSTEP_PIN, LOW);
      delayMicroseconds(500);
      break;
    //长按按键7、8,产生100HZ的方波
    case '7':
    case '8':
       digitalWrite(YSTEP_PIN, HIGH);
       delay(5);
       digitalWrite(YSTEP_PIN, LOW);
       delay(5);
      break;
  }
}

void keypadEvent(KeypadEvent key)
{
  switch (keypad.getState())
  {
    //有按键发生时
    case PRESSED:
      switch (key)
      {
        //按键1控制电机使能
        case '1':
          ENA_TOGGLE = !ENA_TOGGLE;
          if (ENA_TOGGLE == HIGH)
          {
            XMOTOR_TOGGLE = LOW;
            YMOTOR_TOGGLE = LOW;
          }
          digitalWrite(ENA_PIN, ENA_TOGGLE);
          break;
        //按键2控制X轴电机开关
        case '2':
          if (ENA_TOGGLE == LOW)
            XMOTOR_TOGGLE = !XMOTOR_TOGGLE;
          break;
        //按键3控制Y轴电机开关
        case '3':
          if (ENA_TOGGLE == LOW)
            YMOTOR_TOGGLE = !YMOTOR_TOGGLE;
          break;
        //按下按键4、7时,控制Y轴电机转向为HIGH
        case '4':
        case '7':
          digitalWrite(YDIR_PIN, HIGH);
          break;
        //按下5、8时,控制Y轴电机转向为LOW
        case '5':
        case '8':
          digitalWrite(YDIR_PIN, LOW);
          break;
      }
      break;
    //有按键长按时
    case HOLD:
      if (YMOTOR_TOGGLE == HIGH)
      {
        if (key == '4' || key == '5' || key == '7' || key == '8')
          YMOTOR_STATE = key;
      }
      break;
    //有按键释放时
    case RELEASED:
      if (YMOTOR_TOGGLE == HIGH)
      {
        if (key == '4' || key == '5' || key == '7' || key == '8')
        {
          YMOTOR_STATE = 0;
          digitalWrite(YSTEP_PIN, LOW);
        }
      }
      break;
  }
}







ll1234567 发表于 2020-4-3 12:37 | 显示全部楼层 来自: 中国–四川 移动/数据上网公共出口
不错,把程序复制下来了。
回复 顶~ 砸~

使用道具 举报

 楼主| tianyuan08 发表于 2020-4-4 13:36 | 显示全部楼层 来自: 中国–甘肃–兰州 电信
更新了一下程序,加了一个计数器变量,arduino上电的时候,变量初始化为0,当调焦筒伸出时每个脉冲计数器+1,当计数值到达30000的时候,按键也不再发送脉冲让调焦筒伸出。收回的时候计数值每个脉冲递减1,当脉冲计数大于1000时,以2000HZ的速度收回,当计数小于1000时,开始以100HZ收回,计数值到达0时,按键不也不再发送脉冲。这样就可以保护机械部分,避免调焦筒伸出、收回的时候到达限位时继续让电机运转造成机械部件的损伤。由于使用了步进电机控制,所以完全可以用程序来保护,不用加什么限位开关之类的了。另外,30000的上限是按照我的电机调速以及调焦筒最大伸出算的,方法很简单,在调焦筒上画一条线,控制电机让调焦筒伸出到达线停止,此时查看一下用了多少个脉冲即可~

更新程序如下:
#include <Key.h>
#include <Keypad.h>
#include <TimerOne.h>

//define ena for all motors
#define ENA_PIN 8

//define motor pins
#define XDIR_PIN 5
#define YDIR_PIN 6
#define XSTEP_PIN 2
#define YSTEP_PIN 3

//define keypad rows and cols
#define ROWS 3
#define COLS 3

//define a keymap
unsigned char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'}
};

//row->pin, col->pin
byte rowPins[ROWS] = {A3, 13, 12};
byte colPins[COLS] = {A2, A1, A0};

//register keymap and pins
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

//XPUL_STATE保存X电机驱动电平状态
volatile byte XPUL_STATE = LOW;

//X电机,Y电机开关
volatile byte XMOTOR_TOGGLE = LOW;
volatile byte YMOTOR_TOGGLE = LOW;

//电机使能开关
volatile byte ENA_TOGGLE = HIGH;

//Y电机状态,指示哪个键被长按
volatile unsigned char YMOTOR_STATE = 0;

//Y电机的累计脉冲数, 不受电机使能、Y电机开关置0,上电后初始化为0
volatile unsigned int YSTEP_CNT = 0;


void setup() {
  //set pin mod
  pinMode(ENA_PIN, OUTPUT);
  pinMode(XDIR_PIN, OUTPUT);
  pinMode(XSTEP_PIN, OUTPUT);
  pinMode(YDIR_PIN, OUTPUT);
  pinMode(YSTEP_PIN, OUTPUT);
  //set pin value
  digitalWrite(ENA_PIN, ENA_TOGGLE);
  digitalWrite(XDIR_PIN, HIGH);
  //设置timer1的频率为32HZ,则每31.25ms触发一次
  Timer1.initialize(31250);
  Timer1.attachInterrupt(timer1_ISR);
  //set keypad listener
  keypad.addEventListener(keypadEvent);
  //set hold dealy
  keypad.setHoldTime(500);
  //set serail
  Serial.begin(9600);
}

//timer1的触发频率为32HZ,也就是1秒触发32次高低电平转换,则1秒为16HZ的方波信号,600秒产生9600个周期
void timer1_ISR()
{
  if (XMOTOR_TOGGLE == HIGH)
  {
    XPUL_STATE = !XPUL_STATE;
    digitalWrite(XSTEP_PIN, XPUL_STATE);
  }
}

void loop() {
  //listern keypad
  keypad.getKey();
  //drive Y-MOTOR
  switch (YMOTOR_STATE)
  {
    //长按按键4、5,产生2000HZ的方波
    case '4':
      if(YSTEP_CNT>0)
      {
        if(YSTEP_CNT>1000)
        {
          digitalWrite(YSTEP_PIN, HIGH);
          delayMicroseconds(250);
          digitalWrite(YSTEP_PIN, LOW);
          delayMicroseconds(250);
        }
        else
        {
          digitalWrite(YSTEP_PIN, HIGH);
          delay(5);
          digitalWrite(YSTEP_PIN, LOW);
          delay(5);
        }
        YSTEP_CNT--;
      }
      break;
    case '5':
      if(YSTEP_CNT<30000)
      {
        digitalWrite(YSTEP_PIN, HIGH);
        delayMicroseconds(250);
        digitalWrite(YSTEP_PIN, LOW);
        delayMicroseconds(250);
        YSTEP_CNT++;
      }
      break;
    //长按按键7、8,产生100HZ的方波
    case '7':
      if(YSTEP_CNT>0)
      {
        digitalWrite(YSTEP_PIN, HIGH);
        delay(5);
        digitalWrite(YSTEP_PIN, LOW);
        delay(5);
        YSTEP_CNT--;
      }
      break;
    case '8':
      if(YSTEP_CNT<30000)
      {
        digitalWrite(YSTEP_PIN, HIGH);
        delay(5);
        digitalWrite(YSTEP_PIN, LOW);
        delay(5);
        YSTEP_CNT++;
      }
      break;
  }
}

void keypadEvent(KeypadEvent key)
{
  switch (keypad.getState())
  {
    //有按键发生时
    case PRESSED:
      switch (key)
      {
        //按键1控制电机使能
        case '1':
          ENA_TOGGLE = !ENA_TOGGLE;
          if (ENA_TOGGLE == HIGH)
          {
            XMOTOR_TOGGLE = LOW;
            YMOTOR_TOGGLE = LOW;
          }
          digitalWrite(ENA_PIN, ENA_TOGGLE);
          break;
        //按键2控制X轴电机开关
        case '2':
          if (ENA_TOGGLE == LOW)
            XMOTOR_TOGGLE = !XMOTOR_TOGGLE;
          break;
        //按键3控制Y轴电机开关
        case '3':
          if (ENA_TOGGLE == LOW)
            YMOTOR_TOGGLE = !YMOTOR_TOGGLE;
          break;
        //按下按键4、7时,控制Y轴电机转向为HIGH
        case '4':
        case '7':
          digitalWrite(YDIR_PIN, HIGH);
          break;
        //按下5、8时,控制Y轴电机转向为LOW
        case '5':
        case '8':
          digitalWrite(YDIR_PIN, LOW);
          break;
      }
      break;
    //有按键长按时
    case HOLD:
      if (YMOTOR_TOGGLE == HIGH)
      {
        if (key == '4' || key == '5' || key == '7' || key == '8')
          YMOTOR_STATE = key;
      }
      break;
    //有按键释放时
    case RELEASED:
      if (YMOTOR_TOGGLE == HIGH)
      {
        if (key == '4' || key == '5' || key == '7' || key == '8')
        {
          YMOTOR_STATE = 0;
          digitalWrite(YSTEP_PIN, LOW);
        }
      }
      break;
  }
}
回复 顶~ 砸~

使用道具 举报

九大行星 发表于 2020-4-5 11:23 | 显示全部楼层 来自: 中国–湖北–武汉 电信
很羡慕会编程的人!
回复 顶~ 砸~

使用道具 举报

紫气东来 发表于 2020-4-22 20:06 | 显示全部楼层 来自: 中国–广东–深圳 联通
厉害厉害
回复 顶~ 砸~

使用道具 举报

hldcloudyou 发表于 2020-4-22 23:24 来自手机 | 显示全部楼层 来自: 中国–辽宁–丹东 联通
能编程的都是高手
回复 顶~ 砸~

使用道具 举报

KKKVVV 发表于 2020-4-23 09:06 | 显示全部楼层 来自: 中国–广东–深圳 电信
能编程的都是高手
回复 顶~ 砸~

使用道具 举报

vvv64 发表于 2020-4-25 14:18 | 显示全部楼层 来自: 中国–广西–南宁 移动
很羡慕会编程的人!
回复 顶~ 砸~

使用道具 举报

信达小黑黑 发表于 2020-4-25 18:21 | 显示全部楼层 来自: 中国–江苏–常州 电信
大神级别的人物啊!顶一下!新手膜拜中。
回复 顶~ 砸~

使用道具 举报

folker 发表于 2020-6-25 23:43 | 显示全部楼层 来自: 中国–湖北–武汉 电信
断电以后保存不了电机位置的。每次还是要回个参考点。这玩意还是要用多圈绝对值编码器才行吧。
回复 顶~ 砸~

使用道具 举报

弹琴的人 发表于 2020-7-10 10:29 | 显示全部楼层 来自: 中国–北京–北京 联通
膜拜 大神。
回复 顶~ 砸~

使用道具 举报

bell.chang 发表于 2020-7-10 11:04 | 显示全部楼层 来自: 中国–上海–上海–长宁区 联通
曾几何时,我也是单片机编程爱好者,现在,。。。, 一言难尽....
回复 顶~ 砸~

使用道具 举报

本版积分规则

APP下載|手机版|爱牧夫天文淘宝店|牧夫天文网 ( 公安备案号21021102000967 )|网站地图|辽ICP备19018387号

GMT+8, 2024-11-22 16:37 , Processed in 0.082930 second(s), 17 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表