查看: 25200
回复: 21
自己动手做一个写字机器人
小小宅138
13
主题
42
回复
发表于2018-11-23 13:20:02 | 显示全部楼层
1# 电梯直达

前几天没什么事,就准备自己做一个写字机器人,初期查了一些资料,但是楼主还是想了一些创新

例如“运用极坐标来制作”  PS:传统的写字机器人都是用的直角坐标

首先去超市选了一款儿童玩具,如下图

 点击查看大图


相信好多人都见过,之所以选这个的原因是,这种绘图板擦写很方便

以后调试的时候会省很多事,如果用A4纸太浪费了

然后就是选用电机了,为了控制精准,我选用的是舵机搭配步进电机

 点击查看大图

 点击查看大图

之所以选择5V的步进电机也是为了方便控制,仅仅一个ULN2003驱动芯片就可以搞定

电机舵机都选好就剩下主控芯片了,首选Arduino无疑了,这里用的是最经典的UNO

硬件电路选好以后还要考虑运动机构了,这对河南科技大学机电学院的学生来说简直小菜一碟,洛阳工学院的历史沉淀也不是吹的

皮带、丝杠、齿轮齿条三种最常用的,当然是丝杆最合适了,不过网上其他人做都是用的同步带

因为小编的材料费完全是从伙食费里面省出来的,所以说什么同步带都是有钱人玩的

去五金店五块钱买了一根1M长的丝杠完事,直径M4,另外还买了一根直径是3mm的光轴

材料都准备齐了,剩下的就该设计了


对大学生来说,最好用的设计软件当然非Solidworks莫属了

零件图,装配图,工程图,一波操作后大致雏形出来了

首先用3D打印给步进电机加个座

 点击查看大图

 点击查看大图

下面是软件绘制的模型图

 点击查看大图

中间的是用来装笔的,右边用来固定光轴

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:28:01   |  显示全部楼层
2#

上面的设计图打印出来就是这样了

 点击查看大图

步进电机和舵机的位置如下图

 点击查看大图

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:33:51   |  显示全部楼层
3#

通上电试了一下运动速度,发现舵机的速度还可以,但是步进电机就不行了

因为步进电机的速度本来就慢,再加上用的丝杠机构,速度更是慢的离谱

所以,小编又咬咬牙买了个直流减速电机,如下图

 点击查看大图

淘宝买来的,不到二十,还包邮


单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:37:09   |  显示全部楼层
4#

换了直流电机,电机的座子、联轴器都要重新设计

 

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:39:53   |  显示全部楼层
5#

座子打印完成,装配完的效果

 点击查看大图

因为单片机的电流无法驱动直流电机,所以加了一块L298N直流电机驱动

上图左下角就是了

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:42:33   |  显示全部楼层
6#

为了编程方便,构建一个极坐标系,下面开始烧脑了,苦逼的计算过程开始了

 点击查看大图

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-23 13:49:42   |  显示全部楼层
7#

算了一天,终于有点头绪,把程序搞进去看看效果

保存成GIF

 

视频压缩后上传的,有将近一分钟,可以看出来。写的有点歪,程序中设定的是一条竖直的线段

20181103_031828.zip 

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-28 09:08:39   |  显示全部楼层
9#
发表于2018-11-26 08:46:13  8# 厉害厉害。好厉害呢。
还在完善中
单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-28 09:11:24   |  显示全部楼层
10#
#include <Servo.h>
#include <Math.h>
Servo myservo;
int i = 87;//舵机中间位置 i为舵机位置指示参数
int x=30;   //笔位置(笔尖到转轴的距离)
int led = 13;//中断指示灯
int c=0;
int s=0;
int u=0;
int v=0;
volatile int state = 0;

void setup() {
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A4, OUTPUT);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
  myservo.attach(9);
  Serial.begin(9600);
}

void loop() {
  //myservo.write(87);
  //Serial.println(s);
begain();
shoudong();
//sanjiao(); 
delay(10);
//z87_78_114_91 ();
//z88_40_130_60 ();
h130_60_114_91 ();
}

void z87_78_114_91 ()
{
for(;s<1;s++)
{
  for(int t=90;t<=114;t++)
  {
    int a=80.00/cos(PI*(t-90)*1.20/180.00)+0.5;
    yundong(t-2,a);
    Serial.print(t);Serial.print("  ");Serial.println(a);
    delay(200);
    }
  }
}
void z88_40_130_60 ()
{
for(;s<1;s++)
{
  for(int t=90;t<=130;t++)
  {
    int a=40.00/cos(PI*(t-90)*1.20/180.00)+0.5;
    yundong(t-2,a);
    Serial.print(t);Serial.print("  ");Serial.println(a);
    delay(200);
    }
  }
}
void h130_60_114_91 ()
{
for(;u<1;u++)
{
  for(int t=130;t>=114;t--)
  {
    int a=40.00/sin(PI*(t-90)*1.00/180.00);
    yundong(t,a);
    Serial.print(t);Serial.print("  ");Serial.println(a);
    delay(200);
    }
  }
}


///////////////////////////////////////////////////////////////////////子程序///////////////////////////////////////////////
void begain()//回零点
{
  for(;c<=1;c++)
  {
    myservo.write(i);
    delay(100);
    fanzhuan(120);
    zhengzhuan(3);
    x=30;  
    }  
  }

int yundong(int a,int l)//////////////////////////运动/////////////
{
  if(l>x)
  {
    zhengzhuan(l-x);
    }
    else fanzhuan(x-l);
myservo.write(a);
delay(100);
i=a;//更新位置
x=l;
}
  
void shoudong()
{
  myservo.write(i);
  if (digitalRead(3) == LOW) {i++;delay(10);Serial.print(i);Serial.print(" ");Serial.print(x);Serial.println("  k1");}
  if (digitalRead(4) == LOW) {i--;delay(10);Serial.print(i);Serial.print(" ");Serial.print(x);Serial.println("  k2");}
  if (digitalRead(5) == LOW) {i = 87;delay(150);Serial.print(i);Serial.print(" ");Serial.print(x);Serial.println("  k3");}
  if (digitalRead(6) == LOW) {yundong(87,78);Serial.println("4");}
  if(state==0)
  {
      if (digitalRead(7) == LOW)
      {
          if(x>30)
            {
              fanzhuan(1);x--;Serial.print("   ");Serial.print(x);Serial.println("  k5");
              }
      }
      if (digitalRead(8) == LOW)
       {
          zhengzhuan(1);x++;Serial.print("   ");Serial.print(x);Serial.println("  k6");
        }
  delay(10);
  }  
}


int zhengzhuan(int m)
{
  for (; m >= 1; m--)//m是移动的距离,单位毫米
  {
    analogWrite(A1, 255);//1
    analogWrite(A2, 0);
    delay(210);
    analogWrite(A1, 0);
    delay(10);
  }
}

int fanzhuan(int m)
{
  for (; m >= 1; m--)
  {
    if(x<30)break;
    analogWrite(A1, 0);
    analogWrite(A2, 255);
    delay(210);
    analogWrite(A2, 0);
    delay(10);   
  }
}

void blink()//中断函数
{
  state = !state;
  digitalWrite(led, state);
  x=29;
  
}
单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-28 09:27:07   |  显示全部楼层
11#

为了安全起见程序中加入了一个限位,防止电机超程堵转

 点击查看大图

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-28 09:43:05   |  显示全部楼层
12#

笔上面的皮筋是为了笔尖和画板始终接触

为了防止出现意外,在电机架上面加了一个限位开关,程序写在中断里面

只要笔架碰到限位,自动回零点(画板的中心)

 点击查看大图

单片机小白
小小宅138
13
主题
42
回复
发表于2018-11-30 08:51:43   |  显示全部楼层
14#
发表于2018-11-28 19:27:37  13# 不能抬笔,只能一笔画?
后期会加舵机来抬笔,或者当初的想法是直接用电磁铁,因为笔尖本来就是一块磁铁,换成电磁铁就可以通过单片机控制了
单片机小白
小小宅138
13
主题
42
回复
发表于2018-12-06 14:19:37   |  显示全部楼层
15#

目前走直线是没有问题了,简单写了一个画二极管的程序

 

 

单片机小白
小小宅138
13
主题
42
回复
发表于2018-12-14 10:24:48   |  显示全部楼层
16#

这个是Arduino的驱动插件

drivers.zip 

因论坛最大上传文件大小为50M,我的IDE传不上来,所以需要的留个邮箱,我给发过去

单片机小白
小小宅138
13
主题
42
回复
发表于2018-12-14 10:30:32   |  显示全部楼层
17#

极坐标单位表.PDF 

这是我自己画的一个极坐标单位表,用来方便编程的

单片机小白
小小宅138
13
主题
42
回复
发表于2019-12-02 23:23:00   |  显示全部楼层
20#
发表于2019-10-28 16:20:54  19# 楼主,请问这个有开源的算法么
算法是自己写的,不够完善,也谈不上开源了
单片机小白

主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部