搜索
bottom↓
回复: 50
打印 上一主题 下一主题

用stc15w4k32移植arduino小贱钟Plotclock

  [复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2018-2-20 11:53:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 XTXB 于 2018-2-20 19:02 编辑

大伙见过类似的东东吧?最早是老外用arduino做的开源项目,用的是avr芯片,春节闲来无事,移植到STC,供大家一乐。
本人业余电子爱好者,多年前从AVR入坑,得到坛友们的无私奉献,收获许多快乐,多谢了!到现在还是菜鸟一个,代码都是东拼西凑的,多多包涵。
在此特别感谢: 傻孩子,马潮,鸿哥,有名称的**,heicad,还有众多网友,当然更要感谢阿莫,感谢amoBBS!
arduino代码:https://github.com/9a/plotclock/blob/master/plotclock.ino
网友作品视频地址:http://v.youku.com/v_show/id_XODIxNTk4MzA4.html
左图是STC完工成品,数码管显示时,分,星期,写字时数码管熄灭,右图是网友arduino作品。

STC芯片下载线只需四根,串口无需晶振,又不用复位电路,单面板DIY排版超级简洁方便,这也是我不用AVR芯片DIY的主要原因了。

三个舵机的电源端合在一起,电容躺着不占地方,数码管是单排的,把管脚弯了90°,装在TOP层,哦!数码管装倒了。

题外话,硅胶线(用30#细线)做下载线就是爽:软,耐高温,胶皮多次焊接不熔,拆普通杜邦线的插头焊上,爽得不要不要的。

用SolidWorks画的外壳,部分设计参照网友的外壳,在此感谢了。个人经验,PAL材料壳体厚度1.5mm比较好,强度够用,打印也迅速。

笔座XY坐标与舵机角度转换的数学模型,当初我看arduino程序时只敢照抄,后来画图仔细研究了一下,其实就是初中几何及三角函数而已。

C语言程序实现:------从xy坐标到舵机角度转换函数,有了以上的推导,C实现起来好像也不是那么复杂了。
  1. ***********************************************************/
  2. float return_angle(float a, float b, float c)         //备用函数,已知ABC三边求AC夹角
  3. {
  4.         // cosine rule for angle between c and a
  5.         return acos((a * a + c * c - b * b) / (2 * a * c));
  6. }
  7. //固定尺寸OL=L1,OT=L2,TH=L3  ∠TMO=120°,∠HTO=46.7°(实际测量角度)
  8. void set_XY(double Tx, double Ty) 从xy坐标到舵机角度转换函数,
  9. {
  10.         float dx;float dy;float c;float a1;float a2;float Hx;float Hy;
  11.         delay_ms(1);//写字速度调节
  12.         // calculate triangle between pen, servoLeft and arm joint
  13.         // cartesian dx/dy
  14.         //左舵机臂长度L1,OT=L2
  15.         dx = Tx - O1X;
  16.         dy = Ty - O1Y;
  17.         // polar lemgth (c) and angle (a1)
  18.         c = sqrt(dx * dx + dy * dy); // 笔(Tx,Ty)到左舵机中心点L的距离TL
  19.         a1 = atan2(dy, dx); //a1=(Tx,Ty)到左舵机中心点与X轴夹角a1=∠TLC,
  20.         a2 = return_angle(L1, L2, c);//a2=LO与LT的夹角∠TLO
  21.         write_Ms(1,floor(((a2 + a1 - M_PI) * SERVOFAKTORLEFT) + SERVOLEFTNULL));//驱动左舵机
  22.         //左舵机角度∠OLC=∠TLO+∠TLC=a1+a2
  23.         //舵机总角度180°(弧度3.14)对应总脉宽2000us,
  24.         //角度与脉宽转换比例SERVOFAKTORLEFT=总脉宽2000us/总角度180°=2000/3.14=637
  25.         //舵机臂安装起始角度=SERVOLEFTNULL
  26.         a2 = return_angle(L2, L1, c);//a2=L2与C的夹角∠OTL
  27.         //三叉支点H的坐标=(Hx,Hy)
  28.         //L3与Y轴的夹角=a1-a2+46.7°
  29.         //46.7°=0.815(OT与HT夹角,机械结构决定的)
  30.         //∠MTH=∠0TG+∠OTH+180°=(∠LTH-∠LTO)+∠OTH+180°
  31.         Hx = Tx + L3 * cos((a1 - a2 + 0.815) + M_PI);
  32.         Hy = Ty + L3 * sin((a1 - a2 + 0.815) + M_PI);
  33.         // calculate triangle between pen joint, servoRight and arm joint
  34.         dx = Hx - O2X;
  35.         dy = Hy - O2Y;
  36.         c = sqrt(dx * dx + dy * dy);//C=HR
  37.         a1 = atan2(dy, dx);//a1=∠HRC,
  38.         a2 = return_angle(L1, 45, c);//a1=∠HRP,HP=45
  39.         write_Ms(2,floor(((a1 - a2) * SERVOFAKTORRIGHT) + SERVORIGHTNULL));//驱动右舵机
  40.         //右舵机角度∠PRC=∠MRC-∠MRP=a1-a2
  41. }
  42. //
复制代码

C语言程序实现:------舵机角度与高电平脉宽的转换
舵机脉冲周期20ms  0°-180°对应高电平0.5ms-2.5ms  相差2000us,角度与脉宽转换比例 SERVOFAKTORLEFT=总脉宽/总角度=2000/3.14=637。
左舵机的驱动函数可以写成write_Ms(1,floor(((a1 + a2 - M_PI) * SERVOFAKTORLEFT) + SERVOLEFTNULL)); (floor是取整函数)
1为左舵机编号,由于舵机安装起始角度无法绝对准确,所以先减M_PI=180°,后加180°=SERVOLEFTNULL=2000作为可调补偿量,当初为这个一减一加困惑了很久。
这是arduino写的驱动函数:servo2.writeMicroseconds(floor(((a1 + a2 - M_PI) * SERVOFAKTORLEFT) + SERVOLEFTNULL));
右舵机初始跟左舵机垂直,可调补偿量SERVORIGHTNULL=1000,就是直接加90°。
由于设定字体的中心纵坐标为0,设定01Y=02Y=-25 笔尖位于蓝色中心线最左到最右,旋转角度为90°,舵机摇臂初始安装时与极限位置(橙色虚线)的夹角45°时最佳。

C语言程序实现:------3个舵机驱动脉冲的产生
整体思路:参照开源程序,占用一个16位定时器,连续输出3个舵机所需的高电平,加上剩下的低电平时间凑够舵机驱动周期20ms。
  1. ***********************************************************/

  2. void write_Ms(unsigned char Channel,unsigned int value)//舵机驱动函数,channel=通道,value=高电平脉宽(550-2500)us
  3. {
  4.                 TR0 = 1;//启动定时器0
  5.                 PWM_Value[Channel]=(value*2);//时钟24MHz 定时器12分频 计数2次1us
  6.                 if(PWM_Value[Channel]>5000)PWM_Value[Channel]=5000;//脉冲宽度不大于2.5ms
  7.                 if(PWM_Value[Channel]<1200)PWM_Value[Channel]=1200;//脉冲宽度不小于0.6ms
  8. }
  9. void Timer0_Init(void)                        //servo定时器初始化@24MHz
  10. {
  11.                 AUXR &= 0x7F;                //定时器时钟12T模式24MHz
  12.                 TMOD &= 0xF0;                //设置定时器模式
  13.                 TL0=(65536-5000)%256;//虽然后面都要重装,但初始化时还是不要太大为好
  14.                 TH0=(65536-5000)/256;
  15.                 TR0 = 1;//启动定时器0
  16.                 //ET0 = 1;//仅在写字时打开定时器0中断,数码管扫描及读时钟时要关闭中断
  17. }
  18. void timer0(void) interrupt 1 //连续输出3路高电平脉冲,剩下的时间为低电平补足20ms
  19. {
  20.                 TR0 = 0;//关闭定时器0
  21.                 switch(order)
  22.                         {
  23.                                 case 1:   
  24.                                                 PWM_OUT0=1; //开第0路高电平,
  25.                                                 TL0=(-PWM_Value[0])%256;  //(-PWM_Value[0])=(65536-PWM_Value[0]) 定时时间会更精准
  26.                                                 TH0=(-PWM_Value[0])/256;    //赋值第0路舵机高电平时间
  27.                                                 break;
  28.                                 case 2:
  29.                                                 PWM_OUT0=0;//关第0路高电平,开第1路高电平,
  30.                                                 PWM_OUT1=1;
  31.                                                 TL0=(-PWM_Value[1])%256;
  32.                                                 TH0=(-PWM_Value[1])/256;   //赋值第1路舵机高电平时间
  33.                                                 break;
  34.                                 case 3:  
  35.                                                 PWM_OUT1=0; //关第1路高电平,开第2路高电平
  36.                                                 PWM_OUT2=1;
  37.                                                 TL0=(-PWM_Value[2])%256;
  38.                                                 TH0=(-PWM_Value[2])/256; //赋值第2路舵机高电平时间
  39.                                                 break;
  40.                                 case 4:   
  41.                                                 PWM_OUT2=0; //3路舵机低电平时间=20ms-3路高电平时间
  42.                                                 TL0=(25536+PWM_Value[0]+PWM_Value[1]+PWM_Value[2])%256;
  43.                                                 TH0=(25536+PWM_Value[0]+PWM_Value[1]+PWM_Value[2])/256;   
  44.                                                 order=0;
  45.                                                 break;
  46.                         }
  47.                                                 TR0 = 1;//启动定时器0
  48.                                                 order++;
  49. }
复制代码


C语言程序实现:------直线运动插补(插入许多点逼近直线),实现从A(lastX,lastY)走直线到B(pX,pY),
  1. /************************************************/
  2. void drawTo(float pX, float pY) {
  3.   float dx; float dy; float c;
  4.   int i;
  5.          // dx dy of new point
  6.         dx = pX - lastX;//以上次点为坐标原点
  7.         dy = pY - lastY;
  8.         //path lenght in mm, times 4 equals 4 steps per mm
  9.         c = floor(4 * sqrt(dx * dx + dy * dy));
  10.         //计算两点之间直线距离并取整  CxC=AxA+BxB  
  11.         if (c < 1) c = 1;
  12.         for (i = 0; i <= c; i++) {
  13.                 // 每次走i/c ,逐点走完距离C
  14.                 set_XY(lastX + (i * dx / c), lastY + (i * dy / c));
  15.         }
  16.         lastX = pX;//存储此次位置坐标
  17.         lastY = pY;
  18. }
  19. //
复制代码

C语言程序实现:------圆弧运动插补(插入许多点逼近圆弧),弧的圆心(bx,by),半径radius,起始角度start,结束角度ende
  1. /************************************************/
  2. void bogenGZS(float bx, float by, float radius, int start, int ende, float sqee)
  3. {//圆弧圆心(bx,by),圆弧半径radius,起始角度start,结束角度ende,X轴向比例sqee
  4.   float inkr = 0.05;//圆弧插补,逆时针每次+0.05°顺时针是-0.05°
  5.   float count = 0;
  6.   do {
  7.         drawTo(sqee * radius * cos(start + count) + bx,radius * sin(start + count) + by);
  8.         //三角函数  X=斜边*cosα, Y=斜边*sinα,        
  9.         count += inkr;//下一点旋转角度inkr
  10.   }
  11.   while ((start + count) <= ende);//到达角度ende,结束
  12. }
  13. //
复制代码

C语言程序实现:------有了以上函数,如何写数字?
  1. /************************************************/
  2. case 5:   //在中心坐标(bx,by)处写数字5
  3.     drawTo(bx + 2 * scale, by + 5 * scale);//走到起始位置
  4.     lift(0);//落笔
  5.     bogenGZS(bx + 5 * scale, by + 6 * scale, 6 * scale, -2.5, 2, 1);//从5的最下端逆时针画圆弧
  6.     drawTo(bx + 5 * scale, by + 20 * scale);//画5的脖子
  7.     drawTo(bx + 12 * scale, by + 20 * scale);//画5的顶上一横
  8.     lift(1);//抬笔
  9.     break;
复制代码

C语言程序实现:------main流程
  1. ******************************************/
  2. void main(void)
  3. {
  4.                 unsigned char Last_ucTemp4=0;//分钟个位记录
  5.                 delay_ms(5);
  6.                 Init_devices();//初始化
  7.                 //ds3231_write_time();//时钟初始数据写入
  8.                 uiVoiceCnt=40;//开机短响                        
  9.                 delay1s();                        
  10.         while (1)         
  11.         {
  12.                 key_service_1_win_4_flash();//按键服务的应用程序
  13.                 display_service_1_win_6_flash(); //显示的窗口菜单服务程序
  14.                 delay1s();
  15.                 if(ucTemp4!=Last_ucTemp4){//如果分有变化,开始写字程序,每分钟写一次
  16.                         P1|=0x3F;////0B xx11 1111;熄灭数码管
  17.                         Last_ucTemp4=ucTemp4;//保存当前分钟值
  18.                         IE2 &=~(1<<2);//关定时器2中断
  19.                         ET0 = 1;//开定时器0中断
  20.                      /*lift(0); //落笔   没用白板笔
  21.                         drawTo(rubberx, rubbery); //停留在笔擦位置,小心撞笔,损坏舵机
  22.                         delay1s();
  23.                         lift(2); //抬笔 */               
  24.                      /*lift(1); //落笔
  25.                         drawTo(0, 25);  //装配测试,笔从写字板左边走到右边
  26.                         delay1s();               
  27.                         drawTo(60, 25);        
  28.                         delay1s(); */                    
  29.                         Test_DrawTime();//写时间函数
  30.                         IE2 |=(1<<2);//开定时器2中断,准备按键扫描,数码管显示,
  31.                         ET0 = 0;//关定时器0中断,防止干扰         
  32.                 }
  33.         }
  34. }
  35. //
复制代码

C语言程序实现:------编译结果,code=13800 ,好家伙,有十几K!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

2
发表于 2018-2-20 11:58:14 | 只看该作者
厉害,我这一假期就是睡觉了

出0入0汤圆

3
发表于 2018-2-20 12:41:36 | 只看该作者
点赞,初中学了SIN,COS基本没用过

出0入0汤圆

4
发表于 2018-2-20 12:43:33 | 只看该作者
这个必须支持。

出0入0汤圆

5
发表于 2018-2-20 15:55:51 | 只看该作者
牛!!!
真心佩服!

出0入0汤圆

6
发表于 2018-2-20 16:30:16 | 只看该作者
这个好玩。牛!

出0入0汤圆

7
发表于 2018-2-20 16:39:30 | 只看该作者
支持!挺好玩的。

出0入0汤圆

8
发表于 2018-2-20 16:50:49 来自手机 | 只看该作者
厉害!支持楼主

出0入0汤圆

9
发表于 2018-2-20 18:45:22 | 只看该作者
挺好玩的。但是这钟也太能造了

出0入0汤圆

10
发表于 2018-2-21 10:33:15 | 只看该作者
点赞,初中学了SIN,COS基本没用

出0入0汤圆

11
 楼主| 发表于 2018-2-21 12:08:45 | 只看该作者
本帖最后由 XTXB 于 2018-2-22 07:55 编辑

新年好!多谢各位的点赞!春节还逛坛子的对电子都是真爱,要不咱们移植个更有意思的。https://github.com/grbl/grbl
工程量可能有点大,好在人家已经铺好了路,咱们只是探索一下,应该只是时间问题,有感兴趣的筒子吗?
我大致看了下雕刻机,写字机,3D打印机的开源程序,基本原理都是读取G码数据,然后控制XYZ。代码也都差不多。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

12
发表于 2018-2-21 12:56:50 | 只看该作者
大大的赞一个

出0入0汤圆

13
发表于 2018-2-21 16:06:44 | 只看该作者
厉害,大好的假期时间被我浪费了

出0入0汤圆

14
发表于 2018-2-21 22:35:09 | 只看该作者
不错,很有意思

出0入0汤圆

15
发表于 2018-2-22 07:54:39 来自手机 | 只看该作者
666,前排围观

出0入0汤圆

16
发表于 2018-2-22 08:51:59 | 只看该作者
不错,楼主加油

出0入76汤圆

17
发表于 2018-2-22 20:00:59 | 只看该作者
不错,赞一个, 楼主DIY能力超强哇

出0入17汤圆

18
发表于 2018-2-22 23:24:12 | 只看该作者
太牛了,必须顶一下!

出0入0汤圆

19
发表于 2018-2-22 23:27:59 来自手机 | 只看该作者
移植grbl不如Marlin啊 Marlin应用范围广一点

出0入0汤圆

20
发表于 2018-2-23 00:23:12 | 只看该作者
厉害了,这个假期就是吃喝睡玩抓螃蟹

出0入0汤圆

21
发表于 2018-2-23 08:24:44 | 只看该作者
不错,感谢楼主分享。我的3D打印机吃灰好久了,改天也仿一个

出0入0汤圆

22
发表于 2018-2-23 14:45:11 | 只看该作者
XTXB 发表于 2018-2-21 12:08
新年好!多谢各位的点赞!春节还逛坛子的对电子都是真爱,要不咱们移植个更有意思的。https://github.com/g ...

这个已经有某位大神移植到了stm32 上面了, 我比较感兴趣的是 marlin  这个 只有很久以前 的一个 不完整的移植版

出0入0汤圆

23
 楼主| 发表于 2018-2-24 09:00:52 | 只看该作者
本帖最后由 XTXB 于 2018-2-24 10:11 编辑
panjun10 发表于 2018-2-23 14:45
这个已经有某位大神移植到了stm32 上面了, 我比较感兴趣的是 marlin  这个 只有很久以前 的一个 不完整的 ...


marlin的步进电机驱动的确很牛,打印时加减速的声音听着就舒服,值得学习,正好有台3D打印机,机械方面都是现成的,板子也是现成的,把arduino移植到c,哈哈,更省事了

出0入0汤圆

24
发表于 2018-2-24 09:59:07 | 只看该作者
用笔还是太消耗了。可以改成沙盘写字

https://www.elektor.com/arduino-controlled-sand-clock

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

25
 楼主| 发表于 2018-2-24 10:02:06 | 只看该作者
本帖最后由 XTXB 于 2018-2-24 10:49 编辑

用沙盘,这都想得到,人才啊,赞!舵机精度很重要,4块5的舵机连个直线都画不直。

出0入0汤圆

26
发表于 2018-2-28 11:54:52 | 只看该作者
就喜欢这种高射炮打蚊子的做法,超贱超牛! 哈哈

出0入0汤圆

27
发表于 2018-3-20 13:27:57 | 只看该作者
厉害,这个给小孩子做一个相对不错。

出0入0汤圆

28
发表于 2018-3-20 18:23:45 | 只看该作者
创意不错

出0入0汤圆

29
发表于 2018-3-21 21:23:22 | 只看该作者
有意思,羡慕你们没事搞点这种创意玩的人,现在我已经变懒了。。。。

出0入0汤圆

30
发表于 2018-5-20 09:03:47 | 只看该作者
收藏,收藏,做个小玩具挺好的

出0入0汤圆

31
发表于 2018-5-20 20:40:33 | 只看该作者
支持一下

出0入16汤圆

32
发表于 2018-5-21 12:23:03 | 只看该作者
楼主牛B得一塌糊涂,必须赞!

出0入0汤圆

33
发表于 2018-5-21 12:35:17 | 只看该作者
支持一下,谢谢分享

出0入0汤圆

34
发表于 2018-5-23 17:20:18 | 只看该作者
牛逼,这个很不错

出0入0汤圆

35
发表于 2018-6-12 13:52:05 | 只看该作者
mark,备用

出0入0汤圆

36
发表于 2018-6-12 14:12:48 | 只看该作者
厉害了,留个印备用。

出0入8汤圆

37
发表于 2018-6-13 20:16:36 | 只看该作者
好玩,改天做个玩玩

出0入0汤圆

38
发表于 2018-6-14 12:02:32 来自手机 | 只看该作者
想问下这个机械结构哪买的?看着挺好玩的呀

出0入0汤圆

39
 楼主| 发表于 2018-6-17 15:45:05 | 只看该作者
闲鱼翻身 发表于 2018-6-14 12:02
想问下这个机械结构哪买的?看着挺好玩的呀

我有台3d打印机

出0入0汤圆

40
发表于 2018-6-17 22:21:18 | 只看该作者
不错
厉害了

出0入0汤圆

41
发表于 2018-6-19 10:07:00 | 只看该作者
XTXB 发表于 2018-6-17 15:45
我有台3d打印机

好吧,只能默默口水下

出0入0汤圆

42
发表于 2018-6-23 07:51:53 | 只看该作者
大神,非常不错!

出0入0汤圆

43
发表于 2018-6-26 09:28:00 | 只看该作者
三角函数......我会....那是不可能的了

出20入30汤圆

44
发表于 2018-6-26 10:02:01 | 只看该作者
伟大数学家高斯说过,数学是科学之王。实际上高深技术最终拼的是数学。

出0入0汤圆

45
 楼主| 发表于 2018-6-27 09:51:01 | 只看该作者
本帖最后由 XTXB 于 2018-6-27 09:55 编辑
HXDZ-AAA 发表于 2018-6-26 10:02
伟大数学家高斯说过,数学是科学之王。实际上高深技术最终拼的是数学。


1999年,在任正非的支持下,华为公司在俄罗斯建立了专门的算法研究所,招聘了数十名全球顶级的数学家,创造性地用非线性数学多维空间逆函数解决了GSM多载波干扰问题。算法研究所突破了移动网络的几个特殊瓶颈,使华为成为全球第一家实现GSM多载波合并的公司,通过软件打通2G、3G和4G网络,使2G、3G、4G产品可以在同一平台上运行,不再需要一个波段一根天线,节省成本,还节省空间,这可能是华为在移动基站领域得以崛起的最重大的突破。

出0入0汤圆

46
发表于 2019-1-31 03:03:51 | 只看该作者
机械臂 也是这个算法

出0入0汤圆

47
发表于 2019-1-31 09:15:08 来自手机 | 只看该作者
厉害了,亲

出0入0汤圆

48
发表于 2019-2-6 09:27:34 | 只看该作者
不错,很有意思!备用

出0入0汤圆

49
发表于 2019-3-6 14:48:31 | 只看该作者
学习了,感谢楼主分享!~

出16170入6148汤圆

50
发表于 2023-10-25 17:14:55 来自手机 | 只看该作者
帖子移动通知:
原分论坛:8051/STC32【已下线】
目标分论坛:51单片机
移动时间:0小时之后
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-21 01:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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