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

电子说

1.3w人已加入

描述

步骤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信号以进行伺服电机控制

PIC单片机

电路准备就绪后,我们必须弄清楚如何生成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机械臂代码的模拟

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单片机编程的更多信息,请按照上一个教程进行操作。

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

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分