FastBond-工业机器人-树莓派CM4的Donkey car硬件设计
本项目为Donkey car的硬件设计,使用树莓派的CM4作为小车的主控单元,自行设计PCB,加入MAX17634芯片为舵机模块的供电,以及ADXL362用于读取加速度数据
标签
MPU
PCB设计
litter47
更新2021-12-13
1880

一.项目介绍

国外有一开源项目名为Donkey car,旨意为做一辆可执行某些功能的小车,本项目想法也因此而来.选用树莓派CM4作为控制芯片的原因是没有接触过树莓派且对树莓派也很感兴趣.CM4是近来刚发布不久的搭载了不同于BCM2835芯片的BCM2711芯片,性能更加强劲,但由于网上教程资源有点老同时现有开源库文件等一些资源还没有对应更新,所以使用起来问题频出,更别说对于树莓派没一点深入了解的人,导致项目从开机到实现通信等基本功能一直都问题重重.不过所幸基本功能使用旧版本的库资源没出大问题,才使本项目成功发布.

小车完整内容分为硬件(本次活动主要发布内容)和软件功能(时间原因暂未完成).已经完成的内容包括CM4底板的PCB绘制(主要工作),用于舵机的驱动电路及CM4的PWM输出功能,用于与三轴传感器通信的SPI功能,用于与可使用I2C通信来调制多路PWM输出芯片通信的I2C功能.

本项目发布用于参加fastbond活动,且贴合工业机器人的选题要求。

本项目主要内容为:

CM4底板的PCB绘制及CM4的I2C,SPI,PWM功能(主要)

  • 使用MAX17634芯片为舵机供电并成功控制舵机转动
  • 使用ADXL362芯片三轴加速度计并成功读取数据
  • 使用PCA9685芯片提供多路PWM驱动电机

 

二.软件介绍

1.树莓派CM4介绍

树莓派到如今已经发布了4代,性能自然是强了,每一代都分为A、B型(刚发布的4代暂时还没有A型),也有比较特殊的型号比如去掉大部分接口很小巧的树莓派Zero、去掉所有接口的树莓派计算型CM(Compute Module)、B型的增强型B+等。其中B型是最常用的,而A、B型区别也只在于尺寸和接口不同,SoC基本都是一致的。而目前最新发布的Compute Module则为CM4.FlmenoTiN79dtKmvf5sVUV2aA0cU

由于很难单独使用没有外引接口CM4模块进行开发,因此官方也发布了CM4IO作为CM4的扩展底板,换句话说要用CM4开发,除非自己画否则必须再买一件CM4IO,也就是多花四五十刀......所以家境贫寒的我选择自己画,这部分在后面硬件介绍.

话说回来,第四代树莓派使用的核心是BCM2711,与之前的BCM2835之类的不太相同,但基本部分大体一致,否则也轮不到我来用CM4做出什么了,水平有限,敬请指正.

FrY9mro5bGczLJc2YImZraMEPV6HFn8yYEKrUkXEJwZvNJSTKbO5BK9s

FiXbZRULphjb-PGnKm4A3A0_2KMx

好在不同树莓派的开机方法和基本设置是差不多的,因此靠着一两年前的大佬们的教学视频也是顺利开了机.有B站一位大佬的小白式讲解和齐全的工具子豪兄的树莓派,还有微雪的教程微雪课堂让我成功学会使用各种基本功能,当然还有稚晖君在知乎发表的文章<使用指南>

期间遇到的问题也很多,比如安装wiringpi库的时候识别不到CM4的gpio,一开始以为版本低了,更新之后还是不行,找了一整天资料快要放弃换成BCM2835的库的时候终于找到一篇文章也是说这件事<wiringpi的 gpio readall命令错误>,本地编译之后终于能读到gpio信息了.再之后编好一个程序之后加载wiringpi库的时候又出现了找不到库的情况,一顿超级用户普通用户的切换之后突然就好了......现在想想也还是一脸懵,不过总算能正常编译了.

本次项目使用的gpio库名为wiringpi,很方便使用的一个库,只不过作者上次更新还是在上次......这个库有很方便的I2C,SPI,PWM等的函数可以直接调用,如何使用自行官网查询.

2.PCA9685介绍

PCA9685是16路12位PWM信号发生器,可用于控制舵机、led、电机等设备,采用I2C通信。主机只需要I2C接口即可实现16路舵机控制。PCA9685的I2C地址默认0x40,如果需要改变地址,则需要将板上A0-A5焊通即可对应的bit置1,此时地址为:0x40+A5:A0。这也意味着主机可以通过I2C地址控制64个PCA9685模块,从而实现最大16*64路舵机控制。<数据手册链接>
FsexxPVh2Cz2swoBy1JPlBFNvx4A

芯片引脚很好理解,a0-a5六个地址控制口,16个led输出口,i2c的两根线和使能,时钟引脚.FgyGniofwE5HD0GIVIBUGrJO-B6G

 

主要配置mode1寄存器的状态和参数:

Ftc_jPpZ4beTVLFjAa5H4UOdUbmo

 

首先初始化wiringpi的i2c功能以及PCA的初始设置,程序中,先确定wiringpi的初始化成功,再设置起始状态:

bool PCA9685Init() 
{
	//初始化
	PCA9685_fd = wiringPiI2CSetup(PCA9685_ADDRESS);
	if (PCA9685_fd <= 0) 
		return false;
	PCA9685_initSuccess = true;
	ResetPca9685();
	return true;
}

void ResetPca9685() 
{
	if (true == PCA9685_initSuccess) 
	{
		//sleep mode, Low power mode. Oscillator off
		WriteByte(PCA9685_fd, PCA9685_MODE1, 0x00);
		WriteByte(PCA9685_fd, PCA9685_MODE2, 0x04);
		usleep(1000);
		//Delay Time is 0, means it always turn into high at the begin
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_L + PCA9685_LED_SHIFT * 0, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_H + PCA9685_LED_SHIFT * 0, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_L + PCA9685_LED_SHIFT * 1, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_H + PCA9685_LED_SHIFT * 1, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_L + PCA9685_LED_SHIFT * 2, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_H + PCA9685_LED_SHIFT * 2, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_L + PCA9685_LED_SHIFT * 3, 0);
		WriteByte(PCA9685_fd, PCA9685_LED0_ON_H + PCA9685_LED_SHIFT * 3, 0);
		usleep(1000);
	}
	else 
	{
		printf("pca9685 doesn't init\n");
	}
}

 

之后设置PCA的频率,须先用公式算出装配值:

 //设置频率
	unsigned char preScale = (PCA9685_CLOCK_FREQ / 4096 / freq) - 1;

之后先写mode1进入睡眠,写入频率后再设置mode1工作

unsigned char oldMode = 0;
	//printf("set PWM frequency to %d HZ\n",freq);
	//read old mode
	oldMode = ReadByte(PCA9685_fd, PCA9685_MODE1);
	//setup sleep mode, Low power mode. Oscillator off (bit4: 1-sleep, 0-normal)
	WriteByte(PCA9685_fd, PCA9685_MODE1, (oldMode & 0x7F) | 0x10);
	//set freq
	WriteByte(PCA9685_fd, PCA9685_PRE_SCALE, preScale);
	//setup normal mode (bit4: 1-sleep, 0-normal)
	WriteByte(PCA9685_fd, PCA9685_MODE1, oldMode);
	usleep(1000); // >500us
	//setup restart (bit7: 1- enable, 0-disable)
	WriteByte(PCA9685_fd, PCA9685_MODE1, oldMode | 0x80);
	usleep(1000); // >500us

之后设置需要用到的通道的PWM起止时间也就是占空比:

void PCA9685SetPwm(unsigned char channel, unsigned short on, unsigned short value)
{
	//设置各个通道的PWM
	if (!PCA9685_initSuccess) 
	{
		printf("Set Pwm failure!\n");
		return;
	}

	WriteByte(PCA9685_fd, PCA9685_LED0_ON_L + PCA9685_LED_SHIFT * channel, on & 0xFF);
	WriteByte(PCA9685_fd, PCA9685_LED0_ON_H + PCA9685_LED_SHIFT * channel, on >> 8);
	WriteByte(PCA9685_fd, PCA9685_LED0_OFF_L + PCA9685_LED_SHIFT * channel, value & 0xFF);
	WriteByte(PCA9685_fd, PCA9685_LED0_OFF_H + PCA9685_LED_SHIFT * channel, value >> 8);
}

PCA大致程序介绍如上,成功驱动现象如下,图中打印出的设置成功信息及输出的PWM占空比值

FgpQaz1UbNa4QPiBsWDmuftxjzpb

下面是用示波器看的波形(毛刺由接地不良产生)FiGP4KcoXS4QLGkp_1kZ7yvZFwxG

3.ADXL362介绍 

Analog Devices 的 ADXL362 是一款超低功耗、3 轴 MEMS 加速计,在 100 Hz 输出数据速率时的功耗低于 2 μA,在运动触发唤醒模式下的功耗为 270 nA。 与采用电源占空比方案实现低功耗的加速计不同,ADXL362 不会因为欠采样而混叠输入信号,且在所有数据速率下都能对传感器的整个带宽进行采样。

ADXL362 提供 12 位输出分辨率;在只需较低分辨率的应用中,提供 8 位格式化数据以实现更高效的单字节传输。 测量范围包括 ±2 g、±4 g 及 ±8 g,且 ±2 g 范围内的分辨率为 1 mg/LSB。 对于要求噪声电平低于 ADXL362 正常值 550 μg/√Hz 的应用,可以选择两种低噪声模式之一(典型值低至 175 μg/√Hz),且增加的电源电流最小。<数据手册>

ADXL362支持spi通信,且官方也有spi的驱动文件,所以这里介绍362的spi通信程序。程序主函数很简单,初始化wiringpi库的spi,初始化362,之后就可以通过读取寄存器数值来取得加速度计的三组数据。

int main()
{
   int16_t ACC_362[3]={0};

   float ACC_362_F[3]={0};
	  wiringPiSPISetup (0, 5000000) ;
    ADXL362_Init();

    while(1)
   {
      ADXL362RegisterRead6(ACC_362);
     ACC_362_F[0] = ACC_362[0]*8.0f/4096;
     ACC_362_F[1] = ACC_362[1]*8.0f/4096;
     ACC_362_F[2] = ACC_362[2]*8.0f/4096;  
     

     
      printf("acc:%f,%f,%f\n",ACC_362_F[0],ACC_362_F[1],ACC_362_F[2]);
   }

362初始化中,先读取器件ID等信息,再写入特定数值配置

int ADXL362_Init(void)
{                       
   if(ADXL362RegisterRead2(XL362_DEVID_AD)==0XAD) //读取器件ID
   {  
      if(ADXL362RegisterRead2(XL362_DEVID_MST)==0x1D) //读取器件ID
      {  
		 
       ADXL362RegisterWrite(XL362_FILTER_CTL,0x53); //1001 0011
       ADXL362RegisterWrite(XL362_POWER_CTL,0x02);
	
       return 0;  
      }
	   
    }           
		return 1;                                     
} 

树莓派上的数据显示:

Fn6cquIThBb0N4OFGtPd9s7wgolR

三.硬件介绍

1.Kicad软件及树莓派官方CM4IO工程介绍

KiCad是一种免费、开源的EDA设计工具,它能够创建电路原理图并进行PCB布局布线,它具有一个集成化的开发环境,且下载之后自带各种库,包括元器件的原理图和封装库,3D库也在其之中,只需要自行导入一下就可以直接使用,整个库大小好几个G(具体忘了多大),基本包含了常用的器件,像本项目的CM4底座之类的直接可以导入,如果没有也可以在树莓派官网找到相关资料,巧的是官网也是用的Kicad设计并且整个工程也是开源的<官方开源项目链接>,更加降低了自行设计小号底板的难度.

FtShqy7gTduf1M504KY3Lgdrs0z3

各个画图软件大致操作也是差不多的,AD会用的话Kicad的基本功能使用起来也完全没有任何难度,只需要花一点时间适应适应快捷键以及UI界面功能的位置等等.这里附上<镜像下载地址>.

Kicad还有各种各样的插件,比如bom文件的导出什么的,之后的介绍会有本项目工程文件bom导出的示例.这些插件极大的增加了使用的方便性,各种意义上.<Kicad的详细介绍>

打开官方CM4IO的开源工程后的原理图及PCB如下图所示FuVDQhkzIqnED50sgvAUBIsfqTUGFoA552RCo1ofgKCr-JvbUBMIvuX0

原理图只截取了主框图,详细原理图请自行下载工程查看,PCB经典双面板,布线啥的值得我学习好久了,看起来很令人舒服,自己呕心沥血画出来的却跟个破铜烂铁一样,打完板之后还忐忑不安不知道能不能用......不过官方板子成本一百五左右卖了35刀,虽然不高但是能省还是省点,顺便也能锻炼锻炼自身画板技术,毕竟之前也没画过差分线,等长线什么的,太讲究了,哪怕板子白给几次能学到东西也是血赚.

      

2.原理图部分介绍

自行设计的CM4底板减少了一些暂时用不上的接口比如HDMI.camera,display,去掉了包括以太网,PCLe等用不上的接口,并在原基础上加了一个MAX17634芯片给舵机供电和额外分别引出一个i2C,UART,SPI,PWM的排针接口为了外接传感器等可能需要用到通信的东西.

FvH7xiXZBBClhFAhZ9h7PpP3U6x8

特别介绍一下本次活动所需的,除了ADXL362以外的另一个芯片,用于供电的MAX17634<datasheet>.FhQJkrUYHe2xk_8FB0EcltuMEaX9

MAX17634x为高效、高压、同步降压型DC-DC转换器,集成MOSFET,工作在4.5V至36V输入电压范围。器件可提供高达4.25A电流。MAX17634有三种版本:MAX17634A、MAX17634B和MAX17634C。MAX17634A和MAX17634B分别为3.3V和5V固定输出电压器件;MAX17634C为可调节输出电压(0.9V至90% VIN)器件。内部补偿覆盖整个输出电压范围,无需外部元件。

MAX17634x采用峰值电流模式控制架构。器件可在强制脉宽调制(PWM)、脉冲频率调制(PFM)或非连续传导模式(DCM)三种开关状态下工作,支持在满载和轻载条件下实现高效率。MAX17634x具有极低最小导通时间,允许高开关频率和较小方案尺寸。

本项目中该芯片原理图如下:

Ftpu6DK6xBeBogd-Gz6tz4aYsV1y

原理图其他部分不予赘述,皆为常见电路,详情请见文件.

3.PCB部分介绍

正如前文所说,第一次画这么一言难尽的图,好不好用暂且不提,看起来就很稀碎......大佬轻喷,日后再加改进.

Fp7NixoV0nSjfZIOf4gzJz0LWzLG

总体是个10x10以内的板子,由于是第一版所以中间还有很多空间可以压缩,甚至于说没有焊接技术限制的话将某些元器件放在背面布线可以极大压缩板子大小.不过CM4的底座实在是细得超出我的焊接水平,不敢轻易浪费材料......好在身边有位焊接巨匠反手就给整好了,在这里十分感谢(90度鞠躬).

四.感言与后续

本项目无论从软件还是硬件方面都让我获得了不少知识,最重要的是稍微提高了硬件设计的水平和树莓派的学习.一直没有机会好好与树莓派进行深入交流,这次也算是通过fastbond活动好好了解了树莓派这个平台,哪怕现在只是简简单单的运用一些gpio功能也让我很喜欢树莓派,也依然觉得树莓派乐趣无穷.另外本次项目也让我扩充了芯片知识,让我更熟悉了ADI和Maxim的芯片.

      

附件下载
donkey_car.kicad_sch
底板原理图
MAX17634.SchDoc
MAX17634模块原理图
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号