版權聲明:本文爲MULTIBEANS ORG研發跟隨文章,未經MLT ORG容許不得轉載。html
最近作項目,須要開發安卓應用,實現串口的收發,目測CH340G在安卓手機上很是麻煩,並且驅動都是Java版本的, 就沒選擇,博主在大二的時候學習過Java SE基本的語法,寫過一些小程序就放棄了Java的道路。最後選擇了藍牙無線透傳模塊,實現串口通訊。如今Qt跨平臺支持安卓,是在是使人欣喜。在網上找資料,用Qt on Android作藍牙驅動的幾乎沒有,也沒有相關例程,因此準備撰寫此文,獻給廣大嵌入式程序員們android
2018/6/27更新:程序員
增長Java版本的藍牙通訊,文章地址:https://www.cnblogs.com/sigma0/p/9234478.html小程序
1. 藍牙:HC-05,(淘寶上有賣),它的接口就是跟串口同樣的,咱們用到了TX,RX,GND,VCC四個引腳。跟下位機或者用CH340G TTL轉USB模塊接到PC機上。藍牙工做在串口模式能夠經過AT指令調節。具體參考藍牙配套的說明文檔,最主要的就是請將藍牙設定爲從機模式,不然安卓手機搜尋連接不上。
2.安卓手機:我這裏測試用了2檯安卓手機,一臺是小米4移動版,安卓版本6.0.1;一臺是MOTO MT887,安卓版本4.1.2。windows
本項目Qt版本是5.7,系統是windows 8.1 x64app
由於第一次作藍牙,就作一個很是簡單的雛形,實現藍牙狀態檢測、藍牙的開關、藍牙的掃描和藍牙配對連接,而且能像串口助手同樣完成數據收發。如圖,就是本一開始作的最簡單的軟件界面,本軟件基於QWidget控件製做,固然你能夠選擇mainwinodw,更能夠本身定義類。框架
軟件界面socket
我不用介紹每一個部位是什麼了,都會明白吧?藍牙打開後經過掃描,會將藍牙的MAC地址還有名字顯示在List中,咱們雙擊List列表中的藍牙,就會進入actived信號鏈接的槽函數,執行藍牙的配對鏈接。創建鏈接以後,就相似串口同樣能夠進行數據通訊了。另外,點擊send按鈕以後會發送一堆字符串。函數
須要用到藍牙就須要在.pro文件中引入庫,我沒有用Qt quick,用的是純C++寫的代碼,你須要在.pro文件中加入這句話:學習
QT += bluetooth
#include <QtBluetooth/qbluetoothglobal.h> #include <QtBluetooth/qbluetoothlocaldevice.h> #include <qbluetoothaddress.h> #include <qbluetoothdevicediscoveryagent.h> #include <qbluetoothlocaldevice.h> #include <qbluetoothsocket.h>
QBluetoothDeviceDiscoveryAgent *discoveryAgent; QBluetoothLocalDevice *localDevice; QBluetoothSocket *socket;
localDevice = new QBluetoothLocalDevice();
if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff ) { ui->pushButton_openBluetooth->setEnabled(true); ui->pushButton_closeDevice->setEnabled(false); }else { ui->pushButton_openBluetooth->setEnabled(false); ui->pushButton_closeDevice->setEnabled(true); }
在構造函數中
那麼,咱們如何來對藍牙進行打開和關閉呢?我在open按鈕和close按鈕的槽函數中對藍牙進行開關操做。
open按鈕的槽函數:
void Widget::on_pushButton_openBluetooth_clicked() { localDevice->powerOn(); ui->pushButton_closeDevice->setEnabled(true); ui->pushButton_openBluetooth->setEnabled(false); ui->pushButton_scan->setEnabled(true); }
void Widget::on_pushButton_closeDevice_clicked() { localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff); ui->pushButton_closeDevice->setEnabled(false); ui->pushButton_openBluetooth->setEnabled(true); ui->pushButton_scan->setEnabled(false); }
if( localDevice->hostMode() == QBluetoothLocalDevice::HostDiscoverable ) { ui->checkBox_discoverable->setChecked(true); }else { ui->checkBox_discoverable->setChecked(false); }
localDevice->setHostMode( QBluetoothLocalDevice::HostDiscoverable);
connect(discoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)) );
void Widget::addBlueToothDevicesToList( const QBluetoothDeviceInfo &info ) { QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name()); QList<QListWidgetItem *> items = ui->list->findItems(label, Qt::MatchExactly); if (items.empty()) { QListWidgetItem *item = new QListWidgetItem(label); QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(info.address()); if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired ) item->setTextColor(QColor(Qt::green)); else item->setTextColor(QColor(Qt::black)); ui->list->addItem(item); } }
static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
void Widget::itemActivated(QListWidgetItem *item) { QString text = item->text(); int index = text.indexOf(' '); if (index == -1) return; QBluetoothAddress address(text.left(index)); QString name(text.mid(index + 1)); qDebug() << "You has choice the bluetooth address is " << address; qDebug() << "The device is connneting.... "; QMessageBox::information(this,tr("Info"),tr("The device is connecting...")); socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite); }
咱們經過對字符串的處理,將獲得address信息。經過socket->connectToService(....),把地址,Uuid,和藍牙模式傳遞進去,當執行完這句話的時候,安卓手機開始和你
選擇的藍牙設備進行連接。
一樣在socket中也提供了豐富的槽函數,好比成功創建鏈接信號,成功斷開信號,這裏在槽函數中能夠作一些例子,這裏給出例子:
connect(socket, SIGNAL(connected()), this, SLOT(bluetoothConnectedEvent()) ); connect(socket, SIGNAL(disconnected()), this, SLOT(bluetoothDisconnectedEvent()) );
void Widget::bluetoothConnectedEvent() {
// 2017/10/8 更新一下,請在這裏插入關閉藍牙查找服務,不然數據會斷。
// 具體語句是什麼我忘記了,反正使用discoveryAgent的一個什麼close,或者stop的方法
qDebug() << "The android device has been connected successfully!"; QMessageBox::information(this,tr("Info"),tr("successful connection!")); } void Widget::bluetoothDisconnectedEvent() { qDebug() << "The android device has been disconnected successfully!"; QMessageBox::information(this,tr("Info"),tr("successful disconnection!")); }
最後,還有一個斷開鏈接函數。經過斷開鏈接按鈕的槽函數實現。
void Widget::on_pushButton_disconnect_clicked() { socket->disconnectFromService(); }
void Widget::on_pushButton_send_clicked() { QByteArray arrayData; QString s("Hello Windows!!!\nThis message is sended via bluetooth of android device!\n"); arrayData = s.toUtf8(); socket->write(arrayData); }
connect(socket, SIGNAL(readyRead()), this, SLOT(readBluetoothDataEvent()) );
readyRead()信號觸發,跳進readBluetoothDataEvent中。
void Widget::readBluetoothDataEvent() { QByteArray line = socket->readAll(); QString strData = line.toHex(); comStr.append(strData); qDebug() <<"rec data is: "<< comStr; qDebug() <<"The comStr length is: " << comStr.length(); if(comStr.length() >= 30) { ui->textBrowser_info->append(comStr + "\n"); comStr.clear(); } }
我這裏是這樣處理的,固然了,你有你本身的處理方法,意思就是那麼個意思。