社区导航

 

搜索
查看: 487|回复: 1

[经验分享] ST MEMS创意大赛第4贴 -- 机械臂控制

[复制链接]

521

TA的帖子

1

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2020-5-10 21:25 | 显示全部楼层 |阅读模式
本帖最后由 传媒学子 于 2020-5-10 21:30 编辑

由于项目最后要驱动机械臂实现手势或者语音跟踪,机械臂驱动的话最好是用驱动板来进行驱动,因此上网上买了一个驱动模块,PCA9685, 可驱动16路PWM。

由于MEMS的MCU没有预留的GPIO口,因此,这里采用STM32F429作为驱动I2C PWM驱动器的主控MCU。

STM32F429主要实现以下功能:

1.采用串口接收PC机中的命令,这些命令根据ST MEMS 获取的传感器数值,结合LSM6DSOX机器学习内核,最终送出的数据。

2.解析串口中的数据,驱动I2C PWM驱动器,控制机械臂实现跟踪功能。

 

这里,首先分享2. 这里采用硬件I2C驱动pac9685, 采用HAL库进行操作,具体程序工程见附件。驱动PCA9685的库是从github上找的,移植到STM32F4上的,大家有兴趣的可以参考。

 

这里PCA9685有个坑,给大家指出:网上买的这个模块,见下图:

这个PAC9685输出端配置如下:

3.jpg 这个芯片原本是用于驱动LED的,被机器人爱好者用于驱动电机了,当然也是可以的;但是网上有一些卖这个模块的,不知道是从哪里搞来的。原理图也没有,资料也是网上的。

我重新看了手册,发现输出是需要添加上拉电阻的,而我买的模块却没有,浪费了我1天的时间,如果不加上拉电阻,波形幅度非常小,大概几十mv. 如果我手里没有那个逻辑分析仪,说实话,估计我就用STM23F429生成多路PWM了;最后看了手册将驱动板后边的输出部分加了一个上拉电阻拉至5V,其实拉到3.3V就行。然后,就可以驱动我的机械臂了。

 

1.jpg

 

 

主程序如下:

2.jpg

 

程序就不多贴了,硬件I2C,PCA9685driver驱动,STM32F4 MCU: 用STM32CubeMX 生成HAL库。

printf(" %d ",pca9685_init(&handle));
//pca9685_write_u8(&handle, 1, 0x10);
// Set PWM frequency.
// The frequency must be between 24Hz and 1526Hz.
printf("%d+1 ",pca9685_set_pwm_frequency(&handle, 50.0f));
// Set the channel on and off times.
// The channel must be >= 0 and < 16.
// The on and off times must be >= 0 and < 4096.
// In this example, the duty cycle is (off time - on time) / 4096 = (2048 - 0) / 4096 = 50%
    printf("%d+2 ",pca9685_set_channel_pwm_times(&handle, 0, 0, 4096*0.5/20));
    printf("%d+2 ",pca9685_set_channel_pwm_times(&handle, 1, 0, 4096*1/20));
	printf("%d+2 ",pca9685_set_channel_pwm_times(&handle, 2, 0, 4096*1.5/20));
	printf("%d+2 ",pca9685_set_channel_pwm_times(&handle, 3, 0, 4096*2.0/20));
// If you do not want to set the times by hand you can directly set the duty cycle. The last parameter
// lets you use a logarithmic scale for LED dimming applications.
	//printf("%d+3 ",pca9685_set_channel_duty_cycle(&handle, 1, 0.5f, false));
  /* USER CODE END 2 */
    uint8_t prescaler = (uint8_t)roundf(25000000.0f/ (4096 * 50)) - 1;
	printf("    %d   ",prescaler);
#include "main.h"

#include <stdbool.h>

#ifndef PCA9685_I2C_TIMEOUT
#define PCA9685_I2C_TIMEOUT 0x1000
#endif

#define PCA9865_I2C_DEFAULT_DEVICE_ADDRESS 0x80

/**
 * Structure defining a handle describing a PCA9685 device.
 */
typedef struct {

	/**
	 * The handle to the I2C bus for the device.
	 */
	I2C_HandleTypeDef *i2c_handle;

	/**
	 * The I2C device address.
	 * @see{PCA9865_I2C_DEFAULT_DEVICE_ADDRESS}
	 */
	uint16_t device_address;

	/**
	 * Set to true to drive inverted.
	 */
	bool inverted;

} pca9685_handle_t;

/**
 * Initialises a PCA9685 device by resetting registers to known values, setting a PWM frequency of 1000Hz, turning
 * all channels off and waking it up.
 * @param handle Handle to a PCA9685 device.
 * @return True on success, false otherwise.
 */
bool pca9685_init(pca9685_handle_t *handle);

/**
 * Tests if a PCA9685 is sleeping.
 * @param handle Handle to a PCA9685 device.
 * @param sleeping Set to the sleeping state of the device.
 * @return True on success, false otherwise.
 */
bool pca9685_is_sleeping(pca9685_handle_t *handle, bool *sleeping);

/**
 * Puts a PCA9685 device into sleep mode.
 * @param handle Handle to a PCA9685 device.
 * @return True on success, false otherwise.
 */
bool pca9685_sleep(pca9685_handle_t *handle);

/**
 * Wakes a PCA9685 device up from sleep mode.
 * @param handle Handle to a PCA9685 device.
 * @return True on success, false otherwise.
 */
bool pca9685_wakeup(pca9685_handle_t *handle);

/**
 * Sets the PWM frequency of a PCA9685 device for all channels.
 * Asserts that the given frequency is between 24 and 1526 Hertz.
 * @param handle Handle to a PCA9685 device.
 * @param frequency PWM frequency to set in Hertz.
 * @return True on success, false otherwise.
 */
bool pca9685_set_pwm_frequency(pca9685_handle_t *handle, float frequency);

/**
 * Sets the PWM on and off times for a channel of a PCA9685 device.
 * Asserts that the given channel is between 0 and 15.
 * Asserts that the on and off times are between 0 and 4096.
 * @param handle Handle to a PCA9685 device.
 * @param channel Channel to set the times for.
 * @param on_time PWM on time of the channel.
 * @param off_time PWM off time of the channel.
 * @return True on success, false otherwise.
 */
bool pca9685_set_channel_pwm_times(pca9685_handle_t *handle, unsigned channel, unsigned on_time, unsigned off_time);

/**
 * Helper function to set the PWM duty cycle for a channel of a PCA9685 device. The duty cycle is either directly
 * converted to a 12-bit value used for the PWM timings, if logarithmic is set to false, or an 8-bit value which is then
 * transformed to a 12-bit value using a look up table for the PWM timings.
 * Asserts that the duty cycle is between 0 and 1.
 * @param handle Handle to a PCA9685 device.
 * @param channel Channel to set the duty cycle of.
 * @param duty_cycle Duty cycle to set.
 * @param logarithmic Set to true to apply logarithmic function.
 * @return True on success, false otherwise.
 */
bool pca9685_set_channel_duty_cycle(pca9685_handle_t *handle, unsigned channel, float duty_cycle, bool logarithmic);
bool pca9685_read_u8(pca9685_handle_t *handle, uint8_t address, uint8_t *dest);
bool pca9685_write_u8(pca9685_handle_t *handle, uint8_t address, uint8_t value);
	

具体代码,参考附件。

pca9685.h

3.28 KB, 下载次数: 0

pca9685.c

8.05 KB, 下载次数: 0



回复

使用道具 举报

1万

TA的帖子

133

TA的资源

管理员

Rank: 13Rank: 13Rank: 13Rank: 13

发表于 2020-5-11 11:39 | 显示全部楼层

赞!这个看上去不错呀

玩板看这里:

http://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/7 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

词云| Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-7-14 05:25 , Processed in 0.103801 second(s), 22 queries , Gzip On, MemCache On.

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