历史上的今天
返回首页

历史上的今天

今天是:2024年12月23日(星期一)

正在发生

2019年12月23日 | 基于PIC单片机的机械臂制作教程

2019-12-23 来源:elecfans

步骤1:电路图

基于PIC单片机的机械臂制作教程

电路图非常简单;整个项目由12V适配器供电。然后使用两个7805电压调节器将此12V转换为+ 5V。一个标记为+ 5V,另一个标记为+ 5V(2)。具有两个调节器的原因是当伺服旋转时,它会吸入大量电流,从而产生电压降。这种电压降迫使PIC重新启动,因此我们无法在同一+ 5V电压轨上同时运行PIC和伺服电机。因此标有+ 5V的电源用于为PIC单片机,LCD和电位计供电,标有+ 5V(2)的独立稳压器输出用于为伺服电机供电。


提供0V至5V可变电压的电位器的五个输出引脚连接到PIC的模拟引脚An0至AN4。由于我们计划使用定时器来产生PWM,因此伺服电机可以连接到任何GPIO引脚。我为伺服电机选择了RD2到RD6的引脚,但它可以是您选择的任何GPIO。


由于程序涉及大量调试,因此16x2 LCD显示器也连接到PIC的portB。这将显示正在控制的伺服电机的占空比。除此之外,我还扩展了所有GPIO和模拟引脚的连接,以防将来需要连接任何传感器。最后,我还连接了编程器引脚H1,使用ICSP编程选项直接使用pickit3对PIC进行编程。


步骤2:在GPIO引脚上生成PWM信号以进行伺服电机控制

电路准备就绪后,我们必须弄清楚如何生成PWN PIC的GPIO引脚上的信号用于控制伺服电机。我们已经使用Timer中断方法累了类似的东西并且成功了。在这里,我们将建立在它之上。


所有业余爱好伺服电机的工作频率为50Hz。这意味着伺服电机的一个完整脉冲周期为1/50(F = 1/T),即20ms。在这20ms内,控制信号仅为0到2ms,而其余信号总是关闭。下图显示了ON时间如何仅在0到2ms之间变化,将电机从0度旋转到180度持续20ms。


考虑到这一点,我们必须在这样的情况下编写程序PIC从电位计读取0到1204的方式并将其映射到0到100,这将是伺服电机的占空比。使用此占空比,我们可以计算伺服电机的ON时间。然后我们可以定期中断初始化定时器中断,使其与Arduino中的millis()函数类似。这样,我们可以将状态GPIO引脚切换为高电平达到所需的持续时间,并在20ms(一个完整周期)后将其关闭,然后重复相同的过程。现在,我们已经了解了逻辑,让我们进入程序。


步骤3:为机器人臂编程PIC16F8771A

总是像完整的程序一样视频可以在本页末尾找到,代码也可以从这里下载所有必要的文件。在本节中,我们将讨论该程序背后的逻辑。该程序采用ADC模块,定时器模块和LCD模块来控制机械臂。如果您不了解如何使用ADC功能或定时器功能或将LCD与PIC连接,则可以回退到相应的链接以了解它们。假设读者熟悉这些概念,下面给出了解释。


定时器0端口配置

代码中最重要的部分是将Timer 0设置为过流具体延迟。计算此延迟的公式可以给出为

Delay = ((256-REG_val)*(Prescal*4))/Fosc

通过使用OPTION_REG和TMR0寄存器,我们将Timer 0设置为以预分频值32运行,REG val设置为248.我们硬件中使用的晶体频率(Fosc)为20Mhz。使用这些值,延迟可以计算为

Delay = ((256-248)*(32*4)) / (20000000)

= 0.0000512 seconds (or)

= 0.05 msec

所以现在我们已经将计时器设置为每0.05ms溢出一次。下面给出了执行相同操作的代码

/*****Port Configuration for Timer ******/

OPTION_REG = 0b00000100; // Timer0 with external freq and 32 as prescalar // Also Enables PULL UPs

TMR0=248; // Load the time value for 0.0001s; delayValue can be between 0-256 only

TMR0IE=1; //Enable timer interrupt bit in PIE1 register

GIE=1; //Enable Global Interrupt

PEIE=1; //Enable the Peripheral Interrupt

/***********______***********/

在伺服电机的总0ms到2ms控制窗口中,我们可以用0.05msec的分辨率控制它,这使得我们可以在0度之间为电机提供(2/0.05)40个不同的位置到180度。如果您的MCU可以支持它以获得更多位置和精确控制,您可以进一步降低此值。


中断服务程序(ISR)

现在我们将Timer 0设置为每0.05ms溢出一次,我们将TMR0IF中断标志设置为0.05ms。因此,在ISR函数中,我们可以重置该标志并将名为count的变量递增1。所以现在这个变量每0.05ms增加1。


void interrupt timer_isr() {

if(TMR0IF==1) // Timer flag has been triggered due to timer overflow -》 set to overflow for every 0.05ms {

TMR0 = 248; //Load the timer Value

TMR0IF=0; // Clear timer interrupt flag

count++; //Count increments by 1 for every 0.05ms }

计算占空比和导通时间

接下来,我们必须计算所有五个伺服电机的占空比和导通时间。我们有五个伺服电机,每个伺服电机用于控制臂的各个部分。因此,我们必须读取所有五个的ADC值,并计算每个的占空比和导通时间。


ADC值将在0到1024的范围内,只需将0.0976(100/1024 = 0.0976)乘以获得的值即可转换为0%至100%占空比。然后必须将此0到100%的占空比转换为ON时间。我们知道,在100%占空比时,ON时间必须为2ms(180度),因此乘以0.02(2/100 = 0.02)将0到100占空比转换为0到2ms。但是我们的定时器变量计数设置为每0.05ms增加一次。这意味着每1ms计数值将为20(1/0.05 = 20)。所以我们必须将20乘以0.02来计算我们程序的准确时间,这将给出0.4(0.02 * 20 = 0.4)的值。相同的代码如下所示,你可以看到它使用for循环重复5次。结果值存储在T_ON数组中。


for (int pot_num=0; pot_num《=3; pot_num++)

{ int Pev_val = T_ON[pot_num];

POT_val = (ADC_Read(pot_num)); //Read the value of POT using ADC

Duty_cycle = (POT_val * 0.0976); //Map 0 to 1024 to 0 to 100

T_ON[pot_num] = Duty_cycle* 0.4;//20*0.02


选择要旋转的电机

我们无法控制所有五个电机,因为它会使ISR代码大幅减速整个微控制器。所以我们一次只能旋转一个伺服电机。要选择旋转哪个伺服,微控制器会监控所有五个伺服电机的开启时间,并将其与之前的准时进行比较。如果ON时间发生变化,我们可以得出结论,必须移动特定的伺服。相同的代码如下所示。


if (T_ON[pot_num] != Pev_val) {

Lcd_Clear();

servo = pot_num;

Lcd_Set_Cursor(2,11); Lcd_Print_String(“S:”);

Lcd_Print_Char(servo+‘0’);

if (pot_num==0)

{Lcd_Set_Cursor(1,1);

Lcd_Print_String(“A:”);}

else if (pot_num==1)

{Lcd_Set_Cursor(1,6);

Lcd_Print_String(“B:”);}

else if (pot_num==2)

{Lcd_Set_Cursor(1,11);

Lcd_Print_String(“C:”);}

else if (pot_num==3)

{Lcd_Set_Cursor(2,1);

Lcd_Print_String(“D:”);}

else if (pot_num==4)

{Lcd_Set_Cursor(2,6);

Lcd_Print_String(“E:”);}

char d2 = (Duty_cycle) %10;

char d1 = (Duty_cycle/10) %10;

Lcd_Print_Char(d1+‘0’);Lcd_Print_Char(d2+‘0’);

我们还在LCD屏幕上打印伺服占空比,以便用户了解其当前位置。基于接通时间的变化,可变伺服系统用0到4的数字更新,每个数字代表各个电动机。


控制ISR内部的伺服电机

在ISR内部,变量计数每0.05ms增加一次,这意味着每1ms变量将增加20。使用它我们必须控制引脚以产生PWM信号。如果count的值小于导通时间,则使用下面的行

打开该电机的GPIOPORTD = PORTD | servo_code[servo];

此处,数组servo_code []具有所有五个伺服电机的引脚细节,并根据变量伺服中的值,将使用该特定伺服电机的代码。然后逻辑OR(|)与现有的PORTD位,这样我们就不会干扰其他电机的值,只更新这个特定的电机。类似地,关闭引脚

PORTD = PORTD & ~(servo_code[servo]);

我们使用逻辑反转(〜)运算符反转了位值,然后在PORTD上执行AND(&)操作以仅关闭所需的引脚,同时将其他引脚保持在先前的状态。完整的代码段如下所示。


void interrupt timer_isr() {

if(TMR0IF==1) // Timer flag has been triggered due to timer overflow -》 set to overflow for every 0.05ms {

TMR0 = 248; //Load the timer Value

TMR0IF=0; // Clear timer interrupt flag

count++; //Count increments by 1 for every 0.05ms -》 count will be 20 for every 1ms (0.05/1 = 20)) }

int servo_code[] = {0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100 };

if (count 》= 20*20)

count=0;

if (count 《= (T_ON[servo]) )

PORTD = PORTD | servo_code[servo];

else

PORTD = PORTD & ~(servo_code[servo]); }

我们知道在GPIO引脚再次打开之前,总周期必须持续20ms。因此,我们通过将count的值与400(上面讨论的计算相同)进行比较来检查计数是否超过20ms,如果是,我们必须再次将计数初始化为零。


步骤4:PIC机械臂代码的模拟

在将代码送到真实硬件之前,最好先模拟代码。所以我使用Proteus来模拟我的代码并验证它是否正常工作。用于仿真的电路如下所示。我们使用示波器检查是否按要求生成PWM信号。此外,我们可以验证LCD和伺服电机是否按预期旋转。


正如您所见,LCD根据第3电机的电位值显示电机D的占空比为07。类似的,如果移动另一个电位器,则该电位器的占空比及其电机编号将显示在LCD上。示波器上显示的PWM信号

使用示波器上的光标选项测量的总循环周期为22.2ms,非常接近所需的20ms。最后,我们确信代码有效,因此要继续使用电路,我们可以将其焊接在穿孔板上或使用PCB。它不会在面包板上轻松工作,因为POT总是会因连接不良而产生一些问题。


步骤5:使用EasyEDA进行PCB设计

设计此PIC机器人手臂,我们选择了名为EasyEDA的在线EDA工具。我已经使用它很长一段时间了,因为它占地面积大,易于使用,所以非常方便。在设计PCB之后,我们可以通过其低成本PCB制造服务订购PCB样品。他们还提供组件采购服务,他们拥有大量电子元件,用户可以订购他们所需的组件以及PCB订单。


在线计算和订购样品

完成此设计后PIC Robot PCB,您可以通过JLCPCB.com订购PCB。要从JLCPCB订购PCB,您需要Gerber File。要下载PCB的Gerber文件,只需单击EasyEDA编辑器页面上的Generate Fabrication File按钮,然后从那里下载Gerber文件,或者您可以单击JLCPCB上的Order,如下图所示。这会将您重定向到JLCPCB.com,在那里您可以选择要订购的PCB数量,所需的铜层数,PCB厚度,铜重量,甚至PCB颜色,如下图所示:


选择所有选项后,单击“保存到购物车”,然后您将进入可以上传我们从EasyEDA下载的Gerber文件的页面。上传您的Gerber文件,然后单击“保存到购物车”。最后安全地点击Checkout以完成您的订单,然后您将在几天后获得PCB。他们以非常低的速率制造PCB,价格为2美元。他们的建造时间也非常少,这是48小时DHL交付3-5天,基本上你会在订购后一周内获得你的PCB。


订购PCB后,您可以查看PCB的生产进度以及日期和时间。您可以通过进入“帐户”页面并点击“生产进度”进行检查。


订购PCB后几天,我将PCB样品装在漂亮的包装中。


在获得这些碎片之后,我已经在PCB上焊接了所有必需的元件。我也直接焊接POT而不是使用连接线,因为我最初使用的母线到母线可能会因为接触松动而产生奇怪的模拟输出电压。组装完所有组件后,我的PCB看起来像这样。


你可能已经注意到这块板上只有一个7805。那是因为最初我认为我可以通过调节器为PIC和伺服电机供电,后来我意识到我需要两个。所以我使用外部电路通过你在这里看到的绿线为伺服电机供电。


然而,你不必担心它,因为;我现在已对PCB进行了更改。您可以使用修改过的PCB并焊接板上的稳压器。


PIC机器人手臂的工作

经过所有的疲劳工作后,我们需要付出代价。焊接电路板上的所有组件并将程序上载到PIC控制器。完整代码如下,或者可以从这里下载。电路板上提供的编程连接器可以帮助您直接使用Pickit 3上传程序,而不会有太多麻烦。程序上传后,您应该看到LCD显示当前正在控制的伺服。要了解有关PIC单片机编程的更多信息,请按照上一个教程进行操作。


从那里你可以简单地转动电位器并检查伺服电机如何响应每个电位器。一旦您了解了格式,您就可以控制机器人手臂执行您需要执行的任何操作并获得乐趣。

推荐阅读

史海拾趣

Fukushima Futaba Electric Co Ltd公司的发展小趣事

进入21世纪后,中国市场的快速发展吸引了Futaba Electric的注意。为了更好地服务于中国市场,公司于2002年在北京成立了双叶电子科技开发(北京)有限公司。这家子公司专营Futaba Electric的全线产品,包括VFD真空荧光显示管、RC无线遥控设备等。通过深耕中国市场,Futaba Electric不仅扩大了产品销量,还进一步提升了品牌知名度和影响力。

DB Unlimited公司的发展小趣事

随着公司业务的不断发展壮大,DB Unlimited开始将目光投向全球市场。公司积极开拓海外市场,通过参加国际展会、与海外客户建立合作关系等方式,成功将产品推向了全球各地。同时,公司还根据不同国家和地区的市场需求和文化差异,对产品进行本地化改造和优化,进一步提高了产品的市场适应性和竞争力。

Aeroflex Metelics / Hi-Rel Components公司的发展小趣事

DB Unlimited始终将客户放在心中最重要的位置。公司坚持以客户为中心的服务理念,为客户提供全方位、高品质的服务。无论是售前咨询、售后服务还是技术支持等方面,DB Unlimited都始终秉持着专业、高效、热情的态度,赢得了客户的广泛赞誉和信赖。这种客户至上的服务理念也成为了公司不断发展壮大的重要保障之一。

请注意,以上故事框架仅供参考,实际的故事需要根据DB Unlimited公司的真实发展历程和具体事实进行编写。

乔光电子(FTR)公司的发展小趣事

在音频市场日益竞争激烈的环境下,DB Unlimited意识到定制化服务的重要性。因此,公司开始提供定制设计服务,以满足客户对特定音频需求的个性化要求。通过与客户的紧密合作和深入沟通,DB Unlimited成功为客户解决了许多复杂的声学设计问题,赢得了客户的信任和赞誉。

ACI [Applied Concepts, Inc.]公司的发展小趣事

在环保意识日益增强的今天,ACI公司积极响应国家号召,将绿色环保理念融入产品设计和生产过程中。公司采用环保材料和生产工艺,推出了一系列绿色电子产品。这些产品不仅具有优异的性能,而且符合环保标准,得到了消费者的广泛认可。通过倡导绿色环保理念,ACI成功引领了行业潮流,树立了良好的企业形象。

DURATOOL公司的发展小趣事

DURATOOL公司自成立以来,一直致力于电子工具的技术创新。在20世纪90年代,公司研发出了一款具有革命性的数字万用表,该产品在精确度、稳定性和操作便捷性方面均大幅超越当时的市场主流产品。这一创新不仅为DURATOOL公司赢得了大量忠实用户,也为其在电子测量工具市场树立了技术领先的形象。随后,DURATOOL公司不断加大研发投入,推出了一系列具有竞争力的新产品,逐步巩固了其在电子工具行业的领先地位。

问答坊 | AI 解惑

proutes 和keil c 调联工具

此工具 可以将proutes 和keil c 连接在一起 实现实时仿真 当你的proutes 是7.0以上版本是 不用将原来的proutes。dll 替换…

查看全部问答>

大家帮帮我,我在找工作啊,我仿真不出来啦!!!附原理图的。

我是想分别利用串口通信和IC总线向8个LED灯进行控制,为什么串口的时候,有些数据发送的时候可以,有些就不行,还有我用IC总线的时候没有什么反应,我的程序应该没有什么问题的,串口用的虚拟的com口,调试助手,应该怎么做呢???file:///C:/DOCU ...…

查看全部问答>

想做嵌入式linux方面的毕业设计,大家给个建议,谢谢

我现在有个ARM9的开发板(mini2440),带触摸屏和摄像头,想用它来做个毕业设计。但是不知道到底做什么比较好,导师说选题要有实用性,有意义。我自己想搞QT方面或者驱动方面的,但具体的内容我还想不好,请大家给个建议,非常感谢!任何建议都可以 ...…

查看全部问答>

征集嵌入式系统论文材料

由于学校硬件资源不足,今年学习嵌入式没有理想的实验环境 学习效果不佳 老师要求是让我们自己下一篇嵌入式系统的论文来充实一下嵌入式的知识 现在征集嵌入式系统的论文资源 最好提供较基础的,篇幅不长 容易读懂,自己也希望通过这次写论文来 ...…

查看全部问答>

WinCE5.0与WinCE6.0的主要区别在那里?

我想了解下WinCE5.0和WinCE6.0的主要区别,那位能告诉我吗?…

查看全部问答>

09年全国大学生电子设计大赛优秀作品选集

本帖最后由 paulhyde 于 2014-9-15 09:35 编辑 09年全国大学生电子设计大赛优秀作品选集  …

查看全部问答>

3700系列系统开关同类产品(二)

安捷伦L4400系列模块   简介: • 1U、单槽开关卡,带集成控制器 • LXI-C,包括GPIB选项 • 内置触发功能 • 使用安捷伦34980插卡 • Web浏览器接口 • 继电器计数器 市场信息: 便携式LXI开关 ...…

查看全部问答>

IPM为什么会出现故障信号

在进行电机控制时用电阻串联测电流波形时,一接示波器探头,IPM为什么会出现故障信号?哎,谁知道告诉我好吗?拜托了…

查看全部问答>

德州仪器 (TI) 最新推出的多内核编程指南

英文的, 邮件里的,不敢独享,特来分享。 …

查看全部问答>