赞
踩
目录
本文主要介绍使用Arduino UNO作为主板,用于控制电机和接收蓝牙模块数据。蓝牙模块用于从手机App上接收控制信号,使用L298N作为驱动板设计一台智能小车,可通过手机上的App来控制小车的运行状态。
项目代码 git 地址:Arduino_project: 基于Arduino板卡的开源项目 (gitee.com)
本系统硬件结构是以Arduino为主控板,蓝牙模块上RX和TX与Arduino上的TX和RX相连。L298N作为电源管理模块和驱动模块,分别为控制板、蓝牙模块提供电源。电池模块提供整个系统的工作电压,采用可充电的锂电池,单个电池电压为: 3.7V, 电池盒中总共装载4节锂电池。硬件列表如下。
名称 | 功能介绍 | 注释 |
Arduino UNO | 控制板 | 处理蓝牙数据和控制电机 |
L298N | 驱动模块 | 驱动四个电机:正转、反转、停止 |
HC-05 蓝牙模块 | 接收/发送控信号 | 传送App发送的信号 |
3.7V 锂电池 | 系统供电 | 4节锂电池构成供电盒 |
HC-08蓝牙串口通信模块是新一代的基于Bluetooth Specification V4.0 BLE 蓝牙协议的数传模块。无线工作频段为 2.4GHz ISM,调制方式是 GFSK。模块最大发射功率为4dBm,接收灵敏度-93dBm,空旷环境下和 手机可以实现 80 米超远距离通信。
其和MCU之间通过串口通信,软件设计也简单便捷,且不需要考虑蓝牙协议栈问题,非常适合做速成产品。
蓝牙模块与MCU之间连接图:
引脚功能定义如下:
控制板引脚 | 功能 | 介绍 |
AI-0 | 连接控制板: IN-1 | 左侧电机控制信号引脚 |
AI-1 | 连接控制板: IN-2 | 左侧电机控制信号引脚 |
AI-2 | 连接控制板: IN-3 | 右侧电机控制信号引脚 |
AI-3 | 连接控制板: IN-4 | 右侧电机控制信号引脚 |
RX/TX | 连接HC-08蓝牙模块 TX/RX |
系统采用集成底盘结构,四个电机固定在最底层底板上,L298N放在最底层的顶层板上,顶层板用于支撑控制板和电池模块。其具体框架结构如下:
固件主要使用电机控制和蓝牙模块数据的发送和接收。其具体代码如下,工程采用Arduino IDE开发:
系统代码:
- // ATMEL ATMEGA8 & 168 / ARDUINO
- //
- // +-\/-+
- // PC6 1| |28 PC5 (AI 5)
- // (D 0) PD0 2| |27 PC4 (AI 4)
- // (D 1) PD1 3| |26 PC3 (AI 3)
- // (D 2) PD2 4| |25 PC2 (AI 2)
- // PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
- // (D 4) PD4 6| |23 PC0 (AI 0)
- // VCC 7| |22 GND
- // GND 8| |21 AREF
- // PB6 9| |20 AVCC
- // PB7 10| |19 PB5 (D 13)
- // PWM+ (D 5) PD5 11| |18 PB4 (D 12)
- // PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
- // (D 7) PD7 13| |16 PB2 (D 10) PWM
- // (D 8) PB0 14| |15 PB1 (D 9) PWM
- // +----+
-
- #include <Arduino.h>
-
- //电机控制接口
- #define PIN_A0 (14)
- #define PIN_A1 (15)
- #define PIN_A2 (16)
- #define PIN_A3 (17)
-
- static const uint8_t MA0 = PIN_A0;
- static const uint8_t MA1 = PIN_A1;
- static const uint8_t MA2 = PIN_A2;
- static const uint8_t MA3 = PIN_A3;
-
- // BLUE TOOTH
- char command;
-
- void setup()
- {
- // put your setup code here, to run once:
- Serial.begin(9600);
-
- pinMode(MA0, OUTPUT);
- pinMode(MA1, OUTPUT);
- pinMode(MA2, OUTPUT);
- pinMode(MA3, OUTPUT);
- }
-
- void loop()
- {
- while(Serial.available())
- {
- command =Serial.read();
- switch(command )
- {
- case 0x18: //前进
- digitalWrite(MA0, LOW);
- digitalWrite(MA1, HIGH);
- digitalWrite(MA2, LOW);
- digitalWrite(MA3, HIGH);
-
- break;
-
- case 0x52: //后退
- digitalWrite(MA0, HIGH);
- digitalWrite(MA1, LOW);
- digitalWrite(MA2, HIGH);
- digitalWrite(MA3, LOW);
-
-
- break;
-
- case 0x08: // 左转
- digitalWrite(MA0, HIGH);
- digitalWrite(MA1, LOW);
- digitalWrite(MA2, LOW);
- digitalWrite(MA3, HIGH);
- break;
-
- case 0x5a: //右转
- digitalWrite(MA0, LOW);
- digitalWrite(MA1, HIGH);
- digitalWrite(MA2, HIGH);
- digitalWrite(MA3, LOW);
-
- break;
- case 0x45:
- default:
- digitalWrite(MA0, LOW);
- digitalWrite(MA1, LOW);
- digitalWrite(MA2, LOW);
- digitalWrite(MA3, LOW);
- break;
- }
- }
- }
使用微信小程序开发App,其特点是集成在微信App内,不用单独安装,搜索到该App既可以使用。该程序主要实现4个按钮,实现小车前进、后退、左转、右转功能。
App UI:
开发工具:
核心代码如下:
- const utils = require('utils.js')
- const ble = require('bluetooth.js')
- Page({
- /**
- * 页面的初始数据
- */
- data: {
- pageload: false,
- connected: false,
- send_hex: false,
- send_string: true,
- send_string_val: 'Hex',
- recv_string: true,
- recv_string_val: 'Hex',
- recv_value: '',
- send_number: 0,
- recv_number: 0,
- recv_hex: true,
- try_cnt:0,
- deviceArray: []
- },
-
-
- /**
- * 生命周期函数--监听页面加载
- */
- onLoad: function (options) {
- var that = this;
-
- console.log(options);
- this.setData({
- pageload:true,
- connected: false,
- deviceId: options.id,
- try_cnt:0,
- deviceName: options.name
- });
-
- console.log("detail: onLoad");
- wx.stopBluetoothDevicesDiscovery({
- success: function (res) {
- console.log('停止搜索设备', res)
- }
- })
-
- that.closeBLEConnection(that.data.deviceId);
- that.createBLEConnection(that.data.deviceId, that.data.deviceName);
- },
-
- onHide () {
- var that = this;
- // Do something when hide.
- // 断开连接
- console.log("detail: onHide");
- },
-
- onShow:function()
- {
- // var that = this;
- // connect bluetooth
- // that.closeBLEConnection(that.data.deviceId);
- // that.createBLEConnection(that.data.deviceId, that.data.deviceName);
- },
-
- onUnload() {
- var that = this;
-
- this.setData({
- pageload:true,
- connected: false,
- try_cnt:0,
- });
-
- console.log("page: onUnload ");
- that.offBLEMonitor();
- that.closeBLEConnection(that.data.deviceId);
- that.closeBluetoothAdapter();
-
- wx.showToast({
- title: '断开蓝牙',
- icon: 'success',
- duration: 2000
- })
- },
-
-
- DisConnectTap:function()
- {
- var that = this;
-
- that.setData({
- pageload:true,
- connected: false,
- try_cnt:0,
- });
-
- ble.openBluetoothAdapter(that.data.deviceId, that.data.deviceName);
- that.createBLEConnection(that.data.deviceId, that.data.deviceName);
- },
-
-
-
- RecvCleanTap: function () {
- this.setData({
- recv_value: '',
- recv_number: 0
- });
- },
-
- /**
- * 创建连接
- * @param {*} deviceId
- * @param {*} name
- */
- createBLEConnection(deviceId, name)
- {
- wx.createBLEConnection({
- deviceId,
- success: (res) => {
- console.log('createBLEConnection - success: ', res)
- this.getBLEDeviceServices(deviceId)
- },
- fail: (res) => {
- console.error('createBLEConnection - fail: ', res)
- if(res.errCode == 10006 ){
- this.createBLEConnection(deviceId, name)
- }
- else{
- ble.openBluetoothAdapter(deviceId, name)
- this.createBLEConnection(deviceId, name)
- }
-
- this.setData({
- connected: false,
- })
- }
- })
- },
-
- getBLEDeviceServices(deviceId)
- {
- var that = this;
- wx.getBLEDeviceServices({
- deviceId,
- success: (res) =>
- {
- console.log('getBLEDeviceServices - success: ', res)
- for (let i = 0; i < res.services.length; i++)
- {
- var ergodic_UUID =res.services[i].uuid; //取出服务里面的UUID
- var UUID_slice = ergodic_UUID.slice(4, 8); //截取4到8位
-
- console.log('getBLEDeviceServices, service ID = ', res.services[i].uuid);
- if ( res.services[i].isPrimary && (UUID_slice == "FFE0") )
- {
- that.setData({
- serviceId: res.services[i].uuid,
- });
- break;
- }
- }
-
- wx.getConnectedBluetoothDevices({
- services: res.services,
- success: (res) =>
- {
- console.log("getConnectedBluetoothDevices - success: " + res)
- },
- fail: (res) => {
- console.error('getConnectedBluetoothDevices - fail: ', res)
- ble.openBluetoothAdapter(deviceId, that.data.deviceName)
- }
- })
-
- that.getBLEDeviceCharacteristics(deviceId, that.data.serviceId);
- },
- fail: (res) => {
- console.error('getBLEDeviceServices - fail: ', res)
- // try it again
- ble.openBluetoothAdapter(deviceId, that.data.deviceName)
- that.monitor_connected();
- }
- });
- },
-
- getBLEDeviceCharacteristics(deviceId, serviceId)
- {
- var that = this;
- let falg = false;
-
- wx.getBLEDeviceCharacteristics({
- deviceId,
- serviceId,
- success: (res) =>
- {
- that.setData({
- connected: true,
- })
- console.log('getBLEDeviceCharacteristics success', res.characteristics)
- for (let i = 0; i < res.characteristics.length; i++)
- {
- let item = res.characteristics[i]
-
- console.log('getBLEDeviceCharacteristics, Characteristics ID = ', item.uuid)
- // 该特征值:可读
- if (item.properties.read)
- {
- wx.readBLECharacteristicValue({
- deviceId,
- serviceId,
- characteristicId: item.uuid,
- })
- }
-
- // 该特征值:可写
- if (item.properties.write)
- {
- this.setData({
- canWrite: true
- })
- this._deviceId = deviceId
- this._serviceId = serviceId
- this._characteristicId = item.uuid
- this.writeValue()
- }
-
- if (item.properties.notify || item.properties.indicate)
- {
- that.setData({
- characteristicId: item.uuid
- });
- falg = true;
- break;
- }
- }
-
-
- if( falg )
- {
- console.debug('getBLEDeviceCharacteristics - deviceId : ', deviceId)
- console.debug('getBLEDeviceCharacteristics - serviceId : ', serviceId)
- console.debug('getBLEDeviceCharacteristics - characteristicId: ', that.data.characteristicId)
-
- // read device character value
- that.readBLECharacteristicValue(deviceId, serviceId, that.data.characteristicId)
- that.notifyBLECharacteristicValueChange(deviceId, serviceId, that.data.characteristicId)
- }
- },
- fail: (res) => {
- console.error('getBLEDeviceCharacteristics -- fail: ', res)
- this.setData({
- connected: false,
- })
-
- if (res.errCode === 10006)
- {
- that.offBLEMonitor();
- that.createBLEConnection(deviceId, that.data.deviceName);
- }
- }
- })
-
- },
-
- readBLECharacteristicValue(deviceId,serviceId, characteristicId )
- {
- wx.readBLECharacteristicValue({
- // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
- deviceId,
- // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
- serviceId,
- // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
- characteristicId,
- success (res) {
- console.log('readBLECharacteristicValue:', res.errCode)
- }
- })
- },
-
- notifyBLECharacteristicValueChange(deviceId,serviceId, characteristicId )
- {
- var that = this;
-
- wx.notifyBLECharacteristicValueChange({
- state: true, // enable notify
- deviceId,
- serviceId,
- characteristicId,
-
- success: (res) => {
- console.info('notifyBLECharacteristicValueChange success: ', res.errMsg)
-
- // read data here
- // 操作之前先监听,保证第一时间获取数据
- wx.onBLECharacteristicValueChange(function(res)
- {
- that.data.connected = true;
- console.info('onBLECharacteristicValueChange', res);
- console.info(`characteristic ${res.characteristicId} has changed, now is ${res.value}`);
-
- var result = res.value;
- var hex = utils.buf2hex(result);
- var _hex_ss = utils.hex2string(hex);
-
- console.info("hex: " + hex);
- console.info("string: " + _hex_ss);
-
- var recv_number_1 = that.data.recv_number + _hex_ss.length / 2;
- var recv_number = Math.round(recv_number_1);
-
- that.setData({
- recv_number: recv_number,
- recv_value: that.data.recv_value + _hex_ss,
- });
-
- let _ss = that.data.recv_value
- if( _ss.includes("TM(C):") && _ss.includes("HM:") && _ss.includes("\n"))
- {
- let buff = _ss.split(' ')
- console.log( _ss )
- console.log(buff)
- that.data.recv_value = "";
- that.data.recv_number = 0;
-
- that.setData({
- temphtValue: buff[2],
- humidityValue: buff[4],
- });
-
- }
- that.monitor_connected();
- })
- },
-
- fail: (res) => {
- console.error('notifyBLECharacteristicValueChange fail: ', res)
- that.monitor_connected();
- }
- })
- },
-
- monitor_connected_action()
- {
- var that = this;
-
-
- let deviceId = that.data.deviceId;
-
- wx.onBLEConnectionStateChange(function(res) {
- // 该方法回调中可以用于处理连接意外断开等异常情况
- console.log( "onBLEConnectionStateChange ----- " + `device ${res.deviceId} state has changed, connected: ${res.connected}`)
- if( res.deviceId == deviceId && res.connected == false )
- {
- wx.closeBLEConnection({
- deviceId,
- success: (res) => {
- console.debug('detail: closeBLEConnection success', res);
- that.offBLEMonitor();
- that.createBLEConnection(deviceId, that.data.deviceName);
- },
- fail: (res) => {
- console.error('detail: closeBLEConnection fail', res);
- if (res.errCode === 10006) {
- that.offBLEMonitor();
- that.createBLEConnection(deviceId, that.data.deviceName);
- }
- }
- })
-
- that.setData({
- try_cnt: that.data.try_cnt + 1,
- })
- }
- else{
- that.data.try_cnt = 0;
- }
- })
- },
-
- monitor_connected()
- {
- var that = this;
-
- setTimeout(that.monitor_connected_action, 200);
- },
-
- writeValue( val )
- {
- // 向蓝牙设备发送一个0x00的16进制数据
- let buffer = new ArrayBuffer(1);
- let dataView = new DataView(buffer);
-
- dataView.setUint8(0, val);
-
- console.debug('getBLEDeviceCharacteristics - deviceId : ', this._deviceId)
- console.debug('getBLEDeviceCharacteristics - serviceId : ', this._serviceId)
- console.debug('getBLEDeviceCharacteristics - characteristicId: ', this._characteristicId)
-
- wx.writeBLECharacteristicValue({
- deviceId: this._deviceId,
- serviceId: this._serviceId,
- characteristicId: this._characteristicId,
- value: buffer,
- success: (res) => {
- console.debug('writeBLECharacteristicValue success', res);
- },
- fail: (res) => {
- console.error(' writeBLECharacteristicValue fail', res);
- this.setData({
- connected: false,
- })
- }
- })
- },
-
- closeBluetoothAdapter()
- {
- wx.closeBluetoothAdapter({
- success (res) {
- console.log(res)
- }
- })
-
- this.setData({
- connected: false,
- }),
- this._discoveryStarted = false
- },
-
- closeBLEConnection( deviceId )
- {
- wx.closeBLEConnection({
- deviceId,
- success: (res) => {
- console.debug('detail: closeBLEConnection success', res);
- },
- fail: (res) => {
- console.error('detail: closeBLEConnection fail', res);
- }
- })
-
- this.setData({
- connected: false,
- canWrite: false,
- })
- },
-
- run_up:function()
- {
- var that = this;
-
- var val = 0x18 ;
- that.writeValue( val );
- },
-
- run_down:function()
- {
- var that = this;
-
- var val = 0x52;
- that.writeValue( val );
- },
-
- run_left:function()
- {
- var that = this;
-
- var val = 0x08;
- that.writeValue( val );
-
- },
-
- run_right:function()
- {
- var that = this;
-
- var val = 0x5a;
- that.writeValue( val );
- },
-
- whiteLightValueSliderChange:function(e)
- {
- var that = this;
- // 向蓝牙设备发送一个0x00的16进制数据
- var val = Math.random() * 255 | 0;
- that.writeValue( val );
- },
-
- offBLEMonitor(){
- this.setData({
- connected: false,
- }),
- wx.offBLEPeripheralConnectionStateChanged();
- wx.offBLEConnectionStateChange();
- wx.offBLECharacteristicValueChange();
- wx.offBLEMTUChange();
- }
- })
1)使用Arduino UNO硬件平台制作智能小车-CSDN博客
2)汇承HC-08蓝牙串口模块使用规格书(含指令集).pdf
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。