TA的每日心情 | 慵懒 2024-5-31 23:20 |
---|
签到天数: 302 天 连续签到: 2 天 [LV.8]以坛为家I
|
pca9685模块是16路的舵机控制板,目前正在捣鼓多轴机械臂,显然树莓派加一般的电机控制板就是在找虐,这个16路的舵机控制板显然是绝佳的方案。
树莓派操作硬件可以通过wiringpi的库,这个库实现了一些基本的硬件操作,其中就包括pca9685模块的通讯方式——iic。
之前写过通过命令行操作的方案,那个makefile简直反人类,添加头文件什么的搞到崩溃。相比之下qt就很和谐了,控制台应用管理整个工程。不过控制台应用人机交互性还是不怎么让人满足,自从开始搞linux,就对单片机的那套不感冒了,因此开发ui界面势在必行。
(一)舵机控制原理
20ms的周期长度、0.6-2.4ms的占空比。不过对于楼主使用的sg90舵机,占空比一般在0.5ms-1.5ms之间,所以以后者为准。
(二)pca9685原理
参考:http://blog.csdn.net/nicekwell/article/details/53616277
第一第二位是模式控制;
从第七位(06)开始,每四位控制一路舵机信号。当ON匹配时,输出高电平(LEDX_ON_L==LEDX_ON_H);当OFF匹配时,输出低电平。
FE位控制占空比,计算公式:
其中还要引入校正,具体看上述帖子。
所以说,如果我们想得到上述的占空比形式,LEDX_ON_L=0,PRE_SCALE=osc_clock/4096*T - 1;
(三)qt程序
pca9685控制的源文件可以参考上面那个博客,不过由于引入的代码是c代码,而ui界面是c++的界面,所以必须经过一些转化处理,否则会报错。- /*
- 这个驱动是在树莓派的wiringPi基础上的,基于wiringPi对i2c的接口函数。
- 此驱动的使用方法是:
- 1、先用 pca9685_init(从机地址) 初始化,得到一个设备描述符(int型),这个设备描述符代表这个pca9685芯片,因为可能多个pca9685级联,通过这个设备描述符来区分它们。
- 它的
- 2、调用 pca9685_setmk
- */
- #ifndef PCA9685_WIRINGPI_H
- #define PCA9685_WIRINGPI_H
- #include <wiringPi.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- int pca9685_init(unsigned char addr); // addr是7位的i2c从机地址,返回的是linux标准的设备描述符,调用它的地方视作pca9685的设备描述符
- //因为可以多个pca9685级联,通过设备描述符区别它们
- //此驱动仅作为驱动舵机使用,周期固定死位20ms,不允许外部设置
- void pca9685_setmk(int fd, int num, int mk);
- #ifdef __cplusplus
- }
- #endif
- //设置指定通道的脉宽。fd是在pca9685_init时获得的设备描述符,num是通道号(从0开始),mk是脉宽单位是us。周期已经固定为20ms了
- #endif
复制代码 添加了extern "C"就可以在c++工程中调用c代码。
ui界面程序如下:
Dialog.h:- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include"iic_pwm.h"
- class QLineEdit;
- class QSlider;
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
-
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
-
- signals:
- public slots:
- void setLineEditValue();
- void sendValue();
- void setSliderValue();
- private:
- Ui::Dialog *ui;
- QLineEdit *lineEdit;
- QSlider *slider;
- int iic_fd;
- };
- #endif // DIALOG_H
复制代码 Dialog.c:- #include "dialog.h"
- #include "ui_dialog.h"
- #include <QtGui/QLineEdit>
- #include <QtGui/QSlider>
- #include <QtGui/QHBoxLayout>
- #include <QDebug>
- #include <QErrorMessage>
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- iic_fd=pca9685_init(0x40);
- lineEdit = new QLineEdit("600");
- //新建一个水平方向的滑动条QSlider控件
- slider = new QSlider(Qt::Horizontal);
- //设置滑动条控件的最小值
- slider->setMinimum(500);
- //设置滑动条控件的最大值
- slider->setMaximum(1500);
- //设置滑动条控件的值
- slider->setValue(600);
- //信号和槽 当滑动条的值发生改变时,即产生一个valueChanged(int)信号 设置QLineEdit控件的显示文本
- connect(slider, SIGNAL(sliderReleased()), this, SLOT(sendValue()));
- connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setLineEditValue()));
- connect(lineEdit,SIGNAL(editingFinished()),this,SLOT(setSliderValue()));
- QGridLayout *layout = new QGridLayout();
- layout->addWidget(lineEdit,0,0,1,3);
- layout->addWidget(slider,0,3,1,1);
- this->setLayout(layout);
- this->resize(500,100);
- this->setWindowTitle("QSliderDemo");
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::setLineEditValue()
- {
- int pos = slider->value();
- QString str = QString("%1").arg(pos);
- lineEdit->setText(str);
- }
- void Dialog::sendValue()
- {
- pca9685_setmk(iic_fd,0,slider->value());
- qDebug()<<"no time"<<endl;
- }
- void Dialog::setSliderValue()
- {
- bool ok;
- int dec=lineEdit->text().toInt(&ok,10);
- if(dec<500||dec>1500)
- {
- QErrorMessage *errordialog= new QErrorMessage(this);
- errordialog->setWindowTitle(tr("over value!"));
- errordialog->showMessage(tr("over value!"));
- }
- else
- slider->setValue(dec);
- pca9685_setmk(iic_fd,0,dec);
- qDebug()<<"once"<<endl;
- }
复制代码 之后我会继续发布关于qt-qt的socket控制、qt-android的socket控制源码分享。
pro文件中加上这句: |
|