查看: 3886|回复: 1

【BPI-M2 Berry试用】通过安卓手机app远程控制舵机转动

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-10 08:31
  • 签到天数: 300 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2017-10-23 21:49:46 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 ky123 于 2017-10-24 10:11 编辑

    (一)关于舵机控制与qt调用
    对于qt如何调用wiringpi和控制舵机的基本操作可以看我上一篇帖子,这里不再赘述
    1. https://www.cirmall.com/bbs/forum.php?mod=viewthread&tid=97546&page=1&extra=#pid442108
    复制代码
    )字符转化
    安卓和qt通讯一个核心问题就是tcp socket的字符转化问题。
    安卓一般使用writeUTF函数发送utf-8格式的数据,接收到它的qt必须转化为qt专用的QString类型才方便操作:
    1. QString utf8str = utf8codec->toUnicode(alldata.mid(2));
    复制代码
    utf8codec有个成员函数toUnicode解决了这一问题。

    校核位
    至于如何预防一些错误以及识别不同舵机目标,我采用了第二位作为区分校核:
    1. //如果符合条件,改变数值
    2.         if (utf8str.mid(1, 1) == "-")
    3.         {
    4.                 //将第一个字段转化为int
    5.                 QString stur = QString("%1-%2").arg(utf8str.mid(0, 1)).arg(utf8str.section("-", 1));
    6.                 lable_order[utf8str.mid(0, 1).toInt()]->setText(stur);
    7.                 qDebug() << "the order is:" << utf8str.section("-", 0);
    8.                 //qDebug()<<"0:"<<utf8str.mid(0,1);
    9.                 //qDebug()<<"1:"<<utf8str.section("-",1);

    10.                 //同步到硬件
    11.         pca9685_setmk(iic_fd,utf8str.mid(0, 1).toInt(),utf8str.section("-", 1).toInt());
    12.         }
    复制代码
    核心代码
    qt核心工程代码:
    1. #include "dialog.h"
    2. #include "ui_dialog.h"
    3. #include "dialog.h"
    4. #include "ui_dialog.h"
    5. #include <QDebug>
    6. #include <QTextCodec>
    7. #include <QString>
    8. #include <QtGui>

    9. Dialog::Dialog(QWidget *parent) :
    10. QDialog(parent),
    11. ui(new Ui::Dialog)
    12. {
    13.         ui->setupUi(this);
    14.     //1
    15.     iic_fd=pca9685_init(0x40);

    16.     //2、ui界面
    17.         order = 3;
    18.         lable_statu = new QLabel("statu:waitting");
    19.         lable_value = new QLabel("value:null");
    20.         button_box = new QDialogButtonBox;
    21.         ok_button = button_box->addButton(tr("ok"), QDialogButtonBox::ActionRole);
    22.         cancal_button = button_box->addButton(tr("cancel"), QDialogButtonBox::ActionRole);
    23.         for (int i = 0; i<order; i++)
    24.                 lable_order.push_back(new QLabel(QString("%1-").
    25.                 arg(QString::number(lable_order.size() + 1))
    26.                 ));


    27.     connect((QObject *)ok_button, SIGNAL(clicked()), this, SLOT(disConnect()));
    28.     connect((QObject *)ok_button, SIGNAL(clicked()), this, SLOT(close()));

    29.         sv_layout = new QVBoxLayout;
    30.         sv_layout->addWidget(lable_statu);
    31.         sv_layout->addWidget(lable_value);
    32.         for (int i = 0; i<order; i++)
    33.                 sv_layout->addWidget(lable_order[i]);
    34.         sv_layout->addWidget(button_box);
    35.         setLayout(sv_layout);
    36.         setWindowTitle(tr("服务器"));

    37.     //3、tcp
    38.         m_tcpServer = new QTcpServer(this);
    39.         if (!m_tcpServer->listen(QHostAddress::Any, 6000))
    40.         {
    41.                 close();
    42.                 return;
    43.         }
    44.         connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnect())); //新连接信号触发,调用newConnect()槽函数,这个跟信号函数一样,可以随便取。

    45. }

    46. Dialog::~Dialog()
    47. {
    48.         delete ui;
    49. }

    50. void Dialog::newConnect()
    51. {
    52.         m_tcpSocket = m_tcpServer->nextPendingConnection(); //得到每个连进来的socket
    53.         lable_statu->setText(QString("statu:success-ip:%1").arg(m_tcpSocket->peerAddress().toString()));
    54.         connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(recmsg()));
    55. }

    56. void Dialog::recmsg()
    57. {
    58.         qint64 len = m_tcpSocket->bytesAvailable();
    59.         //qDebug()<<"socket data len:"<< len;
    60.         QByteArray alldata = m_tcpSocket->read(len);

    61.         //开始转换编码
    62.         QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
    63.         QString utf8str = utf8codec->toUnicode(alldata.mid(2));
    64.         //qDebug()<<"hex:["<<alldata.toHex().toUpper()<<"]";
    65.         //qDebug()<<"utf-8 ["<< (utf8str) << "]";

    66.         //显示到控件上
    67.         lable_value->setText(utf8str);

    68.         //如果符合条件,改变数值
    69.         if (utf8str.mid(1, 1) == "-")
    70.         {
    71.                 //将第一个字段转化为int
    72.                 QString stur = QString("%1-%2").arg(utf8str.mid(0, 1)).arg(utf8str.section("-", 1));
    73.                 lable_order[utf8str.mid(0, 1).toInt()]->setText(stur);
    74.                 qDebug() << "the order is:" << utf8str.section("-", 0);
    75.                 //qDebug()<<"0:"<<utf8str.mid(0,1);
    76.                 //qDebug()<<"1:"<<utf8str.section("-",1);

    77.                 //同步到硬件
    78.         pca9685_setmk(iic_fd,utf8str.mid(0, 1).toInt(),utf8str.section("-", 1).toInt());
    79.         }
    80. }

    81. void Dialog::disConnect()
    82. {
    83.         //    if(m_tcpSocket->isValid())
    84.         //        m_tcpSocket->disconnected();
    85.         close();
    86. }

    复制代码
    android核心工程代码:
    1. //重载的滑块监听器
    2.     class BarListener implements SeekBar.OnSeekBarChangeListener {
    3.             @Override
    4.             //1、每一次改变时调用:同步pwm_value和对应SeekBar的progress值
    5.             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    6.                 switch (seekBar.getId()) {
    7.                     case R.id.bar_for_lr:
    8.                         text_for_lr.setText("lr当前进度值:" + progress + "  / 100 ");
    9.                         pwm_value[0] = progress;
    10.                         break;
    11.                     case R.id.bar_for_fb:
    12.                         text_for_fb.setText("fb当前进度值:" + progress + "  / 100 ");
    13.                         pwm_value[1] = progress;
    14.                         break;
    15.                     case R.id.bar_for_ud:
    16.                         text_for_ud.setText("ud当前进度值:" + progress + "  / 100 ");
    17.                         pwm_value[2] = progress;
    18.                         break;
    19.                 }
    20.             }
    21.             //2、每次点下时调用:
    22.             @Override
    23.             public void onStartTrackingTouch(SeekBar seekBar) {

    24.             }
    25.             //3、每次松开时调用
    26.             @Override
    27.             public void onStopTrackingTouch(SeekBar seekBar) {
    28.                 if (seekBar.getProgress() < 500)
    29.                     seekBar.setProgress(500);
    30.                 if (seekBar.getProgress() > 1500)
    31.                     seekBar.setProgress(1500);

    32.                 int seekbar_order = 0;
    33.                 switch (seekBar.getId()){
    34.                     case R.id.bar_for_lr:
    35.                         seekbar_order=0;
    36.                         break;
    37.                     case R.id.bar_for_fb:
    38.                         seekbar_order = 1;
    39.                         break;
    40.                     case R.id.bar_for_ud:
    41.                         seekbar_order=2;
    42.                         break;
    43.                     default:
    44.                         break;
    45.                 }

    46.                 if(socket.isConnected()){
    47.                     final int finalSeekbar_order = seekbar_order;
    48.                     new Thread() {
    49.                         @Override
    50.                         public void run() {
    51.                             //启动子线程创建socket并发送字符
    52.                             String command=String.valueOf(finalSeekbar_order)+"-"+String.valueOf(pwm_value[finalSeekbar_order]);
    53.                             try {
    54.                                 out.writeUTF(command);
    55.                             } catch (IOException e) {
    56.                                 e.printStackTrace();
    57.                             }
    58.                         }
    59.                     }.start();
    60.                 }
    61.             }
    62.         }
    复制代码
    )编译
    必须要在.pro文件中加上两行:
    1. QT  +=  network

    2. LIBS    +=  -lwiringPi -lcrypt
    复制代码
    硬件连接
    N$}PVD}}]2_9MSRH)Q8[R.jpg
    这里使用SDA1、SCL1,对应系统第二条iic总线。

    IMG_20171021_174711.jpg
    IMG_20171021_174732.jpg


    (六)视频演示与工程分享




    pca_socket.rar

    31.66 KB, 阅读权限: 10, 下载次数: 1

    回复

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2017-12-19 15:07:41 | 显示全部楼层
    贴的可真长
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-10 01:52 , Processed in 0.141141 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.