关键词:
文章目录
目录
前言
想搞一个蓝牙app与单片机通信,控制小车的前进后退。在Git上找了好多源码,这看看那看看整得,好像都不是那么回事。以前也没整过android,整得我好费劲呀!还是老老实实选一份看看、好好的梳理梳理。
一、基本逻辑梳理
用android定义几个个按钮(前后左右),按下按钮则通过android蓝牙发出一个字符给单片机的蓝牙模块接收。蓝牙模块与单片机是串口通信。故比较接收的字符与定义的字符是否一致,一致则执行指定操作。
通过android蓝牙t调试宝测得CH06的的UUID为:00001101-0000-1000-8000-00805f9b34fb(同一类型设备通用)
MAC:98:DA:E0:01:0B:4E(每个蓝牙模块MAC唯一)
单片机部分代码:
u8 reclen=0;
if(USART2_RX_STA&0X8000) //接收到一次数据了
reclen=USART2_RX_STA&0X7FFF; //得到数据长度
USART2_RX_BUF[reclen]=0; //加入结束符
printf("USART2_RX_BUF:%s\\n",USART2_RX_BUF);
printf("reclen:%d\\n",reclen);
if(reclen==1||reclen==2) //控制DS1检测
if(strcmp((const char*)USART2_RX_BUF,"A")==0)
u2_printf("go forward!");
ZYSTM32_run(80,100);
else if(strcmp((const char*)USART2_RX_BUF,"E")==0)
u2_printf("go back!");
ZYSTM32_back(80,100);
else if(strcmp((const char*)USART2_RX_BUF,"C")==0)
u2_printf("go right!");
ZYSTM32_Right(80,100);
else if(strcmp((const char*)USART2_RX_BUF,"G")==0)
u2_printf("go left!");
ZYSTM32_Left(80,100);
else if(strcmp((const char*)USART2_RX_BUF,"X")==0)
u2_printf("Stop!");
ZYSTM32_brake(100);
else if(strcmp((const char*)USART2_RX_BUF,"Y")==0)
u2_printf("Stop!");
ZYSTM32_brake(100);
USART2_RX_STA=0;
二、android部分蓝牙扫描
2.1、权限申请
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.blueboothproject_01">
<!--请求旧设备上的遗留蓝牙权限。-->
<!--允许程序连接到已配对的蓝牙-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!--BLE feature(特征)-->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<!--允许程序连接到已配对的蓝牙-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--只有当您的应用程序与已经配对的蓝牙通信时才需要-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!--只有当应用程序寻找蓝牙设备时才需要。 必须向此权限添加属性ACCESS_FINE_LOCATION权限,取决于您的时候的结果在应用程序中检查位置使用情况-->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!---->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--允许程序访问CellID或WIFI热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--允许程序访问精确位置-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--只有当您的应用程序使设备可被蓝牙发现时才需要设备。-->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-feature android:name="android.hardware.location.gps"/>
<application
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BlueBoothProject_01"
tools:targetApi="31">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Ble_Activity" android:exported="true"/>
<service
android:name="com.example.blueboothproject_01.service.BluetoothleService"
android:enabled="true">
</service>
<activity android:name=".DebugActivity"
android:resizeableActivity="true"
/>
</application>
</manifest>
2.2、相关变量
// 通过按键扫描蓝牙
private Button BlueBooth_Scan_btn;
// 获取蓝牙适配器
private BluetoothAdapter mbluetoothAdapter;
// 低功耗蓝牙扫描回调类
private ScanCallback mScanCalBack;
// 低功耗蓝牙扫描装置
private BluetoothLeScanner mBluetoothLeScanner;
// 蓝牙信号强度
private ArrayList<Integer> rssis;
// 自定义适配器
private LeDeviceListAdapter mleDeviceListAdpater;
// 显示扫描到的蓝牙信息 Listview
private ListView lv;
// 蓝牙的扫描状态
// 扫描中
private boolean mScanming;
// 扫描标记
private boolean Scan_Flag;
// 操作类
private Handler mhandler;
// 请求使能
int REQUEST_ENABLE_BIT = 1;
// 蓝牙扫描时间
private static final long SCAN_PERIOD = 4000;
2.3、onCreate一些初始化操作
/**
* 一个activity启动调用的第一个函数就是onCreate,
* 它主要做这个activity启动时一些必要的初始化工作
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// 加载activity_main.xml
setContentView(R.layout.activity_main);
// 申请位置权限
Permissions_Init();
// 控件初始化
UI_Init();
// 蓝牙初始化
BlueTooth_Init();
// 绑定蓝牙 Build.VERSION_CODES.R sdk版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
// 回调函数
setScanCallBack();
// 开始扫描
boolean Scan_Flag = true;
// 创建一个自定义适配器类型对象
mleDeviceListAdpater = new LeDeviceListAdapter();
// 为listview指定适配器
lv.setAdapter(mleDeviceListAdpater);
// listview点击函数
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
// 获取列表中指定位置的元素
final BluetoothMessage bluetoothMessage = mleDeviceListAdpater.getDevice(position);
// 判空
if(bluetoothMessage==null)
return;
final Intent intent = new Intent(MainActivity.this, com.example.blueboothproject_01.Ble_Activity.class);
// 向意图添加扩展数据。名称必须包含包前缀,
// 例如应用程序com.android.contacts将使用“com.android.contacts. showall”这样的名称。
// 蓝牙名称
intent.putExtra(com.example.blueboothproject_01.Ble_Activity.EXTRAS_DEVICE_NAME,
bluetoothMessage.getName()!=null?bluetoothMessage.getName():bluetoothMessage.getDevice().getName());
// 蓝牙地址
intent.putExtra(com.example.blueboothproject_01.Ble_Activity.EXTRAS_DEVICE_ADDRESS,
bluetoothMessage.getDevice().getAddress());
// 信号强度
intent.putExtra(com.example.blueboothproject_01.Ble_Activity.EXTRAS_DEVICE_RSSI,
rssis.get(position).toString());
if(mScanming)
// 停止扫描
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R)
// 停止正在进行的蓝牙LE扫描
mBluetoothLeScanner.stopScan(mScanCalBack);
else
// 停止正在进行的蓝牙LE设备扫描。
mbluetoothAdapter.stopLeScan(mLeScanCallback);
mScanming= false;
try
// 启动booth_activity组
startActivity(intent);
catch (Exception e)
// 异常处理
e.printStackTrace();
);
// 蓝牙扫描 设置一个点击事件
BlueBooth_Scan_btn.setOnLongClickListener(new View.OnLongClickListener()
@Override
public boolean onLongClick(View v)
startActivity(new Intent(MainActivity.this,DebugActivity.class));
return false;
);
2.3.1、位置权限
private void Permissions_Init()
// 确定是否已授予您特定的权限。
if (ContextCompat.checkSelfPermission(this,
Manifest.permission_group.LOCATION)!= PackageManager.PERMISSION_GRANTED)
// 获取wifi连接需要定位权限,没有获取权限
ActivityCompat.requestPermissions((Activity) this, new String[]
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_WIFI_STATE,
, 1);
2.3.2、控件初始化
/**
* ********************************************************************************
* 控件初始化
* ********************************************************************************
*/
private void UI_Init()
BlueBooth_Scan_btn = this.findViewById(R.id.scan_btn);
BlueBooth_Scan_btn.setOnClickListener(this);
ListView lv = this.findViewById(R.id.lv);
mhandler = new Handler();
2.3.3、蓝牙初始化
/**
* ********************************************************************************
* 蓝牙初始化
* ********************************************************************************
*/
private void BlueTooth_Init()
// 一、手机硬件是否支持蓝牙
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
Toast.makeText(this, "Non-Supported BlueBooth-ble-devices", Toast.LENGTH_SHORT).show();
finish();
// 二、从手机获取本机蓝牙适配器
final BluetoothManager mbluetootManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
// AnBuild.VERSION.SDK_INT是一个静态变量,代表运行该应用的手机系统的SDK版本
// Build.VERSION_CODES.R 当前编译器的版本号
// startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
// 从系统服务中获取蓝牙管理器
mbluetoothAdapter = mbluetootManager.getAdapter();
else
// 获取系统默认的蓝牙适配器
mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 三、 le设备的扫描
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
mBluetoothLeScanner = mbluetoothAdapter.getBluetoothLeScanner();
// 打开蓝牙权限
if (mbluetoothAdapter == null || !mbluetoothAdapter.isEnabled())
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BIT);
/* 打开蓝牙权*/
// Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//,打开一个 Activity ,在打开的 Activity 中操作之后并获得返回结果。
// startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
/*
* 1、Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");
2、Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.
3、Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
4、Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
5、Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。*/
// 打开蓝牙
2.4、蓝牙回调函数
2.4.1、高版本蓝牙回调
/**
* ********************************************************************************
* 高版本回调函数
* ********************************************************************************
*/
private void setScanCallBack()
// 蓝牙LE扫描回调。使用这些回调来报告扫描结果。
mScanCalBack = new ScanCallback()
// 重写扫描结果 回调类型 扫描结果集
public void onScanResult(int callbackType, final ScanResult result)
// 获取蓝牙设备
final BluetoothDevice device = result.getDevice();
// 获取蓝牙设备信息
final BluetoothMessage bluetoothMessage = new BluetoothMessage(device);
// 获取蓝牙设备信息
if (null != device || null != result.getScanRecord())
try
// 蓝牙设备名字非空
if (device.getName() != null)
// 获取设备名称
byte[] name = ParseLeAdvDate.adv_report_parse(
ParseLeAdvDate.BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME,
result.getScanRecord().getBytes());
if (name != null)
bluetoothMessage.setName(new String(name, "utf-8"));
catch (UnsupportedEncodingException e)
e.printStackTrace();
// 在UI线程上运行指定的操作。如果当前线程是UI线程,那么操作将立即执行。
// 如果当前线程不是UI线程,则动作被提交到UI线程的事件队列中。
runOnUiThread(new Runnable()
@Override
public void run()
// 讲扫描到的信息输出到ListView的适配器 蓝牙信号强度
mleDeviceListAdpater.addDevice(bluetoothMessage, result.getRssi());
// 数据更新 通知附加的观察者基础数据已经被更改,任何反映数据集的视图都应该刷新自己。
mleDeviceListAdpater.notifyDataSetChanged();
);
@Override
public void onScanFailed(final int errorCode)
super.onScanFailed(errorCode);
runOnUiThread(new Runnable()
@Override
public void run()
// LENGTH_SHORT:显示短时间内的视图或文本通知。这一次可能是用户可定义的。这是默认值。
Toast.makeText(MainActivity.this,"扫描出错:"+errorCode,Toast.LENGTH_SHORT).show();
);
;
24.2、低版本蓝牙回调函数
/***************************************************************
* 低版本蓝牙回调函数
* ************************************************************/
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback()
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord)
// TODO Auto-generated method stub
runOnUiThread(new Runnable()
@Override
public void run()
// 讲扫描到设备的信息输出到listview的适配器
BluetoothMessage bluetoothMessage = new BluetoothMessage(device);
mleDeviceListAdpater.addDevice(bluetoothMessage, rssi);
mleDeviceListAdpater.notifyDataSetChanged();
);
;
2.5、点击扫描按钮执行操作
2.5.1、点击事件
/********************************************************************
* 点击事件 ble_active
********************************************************************/
@Override
public void onClick(View v)
if(!isOpenGPS(this))
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
builder.setTitle("提示")
.setMessage("请前往打开手机的位置权限!")
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, 10);
).show();
return;
if (Scan_Flag)
mleDeviceListAdpater = new LeDeviceListAdapter(); //自定义适配器
lv.setAdapter(mleDeviceListAdpater); //设置listview为自定义适配器
scanLeDevice(true); //点击按键开始扫描设备
else
scanLeDevice(false);
BlueBooth_Scan_btn.setText("扫描设备");
2.5.2、扫描事件
private void scanLeDevice(boolean enable)
//将定义的蓝牙适配器进行版本适配操作
if (mbluetoothAdapter == null)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
else
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mbluetoothAdapter = bluetoothManager.getAdapter();
//将蓝牙扫描器进行适配操作
if (mBluetoothLeScanner == null)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
mBluetoothLeScanner = mbluetoothAdapter.getBluetoothLeScanner();
if (enable)
// 10s后停止扫描
mhandler.postDelayed(new Runnable()
@Override
public void run()
mScanming = false;
Scan_Flag = true;
BlueBooth_Scan_btn.setText("扫描设备");
Log.i("SCAN", "stop.....................");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
mBluetoothLeScanner.stopScan(mScanCalBack);
else
mbluetoothAdapter.stopLeScan(mLeScanCallback);
, SCAN_PERIOD);//10s后启动停止线程
/* 开始扫描蓝牙设备,带mLeScanCallback 回调函数 */
Log.i("SCAN", "begin.....................");
mScanming = true;
Scan_Flag = false;
BlueBooth_Scan_btn.setText("停止扫描");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
mBluetoothLeScanner.startScan(mScanCalBack);
else
mbluetoothAdapter.startLeScan(mLeScanCallback);
else
Log.i("Stop", "stoping................");
mScanming = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
mBluetoothLeScanner.stopScan(mScanCalBack);
else
mbluetoothAdapter.stopLeScan(mLeScanCallback);
Scan_Flag = true;
2.5.3、GPS是否打开
private boolean isOpenGPS(final Context context)
LocationManager locationManager
= (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// GPS定位
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// 网络服务定位
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network)
return true;
return false;
三、自定义蓝牙适配器内部类
/********************************************************************
* 自定义适配器作为Listview的适配器
********************************************************************/
private class LeDeviceListAdapter extends BaseAdapter
/**ArrayList:
* 实现所有可选的列表操作,并允许所有元素,包括null。除了实现List接口之外,
*这个类还提供了一些方法来操作用于内部存储列表的数组的大小。
*(这个类大致相当于Vector,只是它是非同步的。)
* 泛型:
* 标记符号ArrayL<T> T--java类
* E - Element (在集合中使用,因为集合中存放的是元素)
* T - Type(Java 类)
* K - Key(键)
* V - Value(值)
* N - Number(数值类型)
* ? - 表示不确定的 java 类型
* */
// 低功耗设备
private ArrayList<BluetoothMessage> mLeDevice;
// 将布局XML文件实例化为相应的View对象。
// 它从不直接使用。相反,使用android.app.Activity.getLayoutInflater()或Context。getSystemService
// 来检索一个标准的LayoutInflater实例,该实例已经连接到当前上下文,并为正在运行的设备正确配置
private LayoutInflater mInflator;
public LeDeviceListAdapter()
super();
rssis = new ArrayList<Integer>();
mLeDevice = new ArrayList<BluetoothMessage>();
// 快速访问此窗口从其上下文检索的LayoutInflater实例。
//Layout: 一个用于加载布局的系统服务,就是实例化与Layout XML文件对应的View对象,不能直接使用,
// 需要通过getLayoutInflater( )方法或getSystemService( )方法来获得与当前Context绑定的 LayoutInflater实例!
mInflator = getLayoutInflater();
// 添加设备
public void addDevice(BluetoothMessage device,int rssi)
// 变量已添加的设备剔除相同地址的蓝牙
// 遍历已添加的设备 剔除相同地址的蓝牙
for(BluetoothMessage mLeDevice:mLeDevice)
if(mLeDevice.getDevice().getAddress().equals(device.getDevice().getAddress()))
return;
if(device.getName()!=null)
// 将指定的元素追加到列表的末尾。
mLeDevice.add(device);
rssis.add(rssi);
// 获取列表中元素的位置信息
public BluetoothMessage getDevice(int position)
// 返回位于列表中指定位置的元素
return mLeDevice.get(position);
// 从列表中删除所有元素。这个调用返回后,列表将为空。
public void Clear()
mLeDevice.clear();
rssis.clear();
// 返回列表中元素的个数。
@Override
public int getCount()
return mLeDevice.size();
// 返回位于列表中指定位置的元素。
@Override
public Object getItem(int i)
return mLeDevice.get(i);
@Override
public long getItemId(int i)
return i;
@Override
public View getView(int i, View view, ViewGroup parent)
view = mInflator.inflate(R.layout.listtiem,null);
// 初始化三个textview 显示蓝牙信息
// 地址
TextView deviceAddress = view.findViewById(R.id.tv_deviceAddr);
// 设备名称
TextView deviceName = view.findViewById(R.id.tv_deviceName);
// 信号强度
TextView rssi = view.findViewById(R.id.tv_rssi);
BluetoothMessage bluetoothMessage = mLeDevice.get(i);
// 返回此蓝牙设备的硬件地址。
// 例如,“00:11:22:AA: BB: CC”。
deviceAddress.setText(bluetoothMessage.getDevice().getAddress());
// 如果布尔表达式的值为 true ,则返回 表达式1 的值,否则返回 表达式2 的值
// 布尔表达式 (bluetoothMessage.getName()!=null) ? 表达式1(bluetoothMessage.getName()):表达式2(bluetoothMessage.getDevice().getName())
deviceName.setText(bluetoothMessage.getName()!=null?bluetoothMessage.getName():bluetoothMessage.getDevice().getName());
rssi.setText(""+rssis.get(i));
return view;
四、实体类
public class BluetoothMessage
// 蓝牙设备
private BluetoothDevice mDevice;
// 设备名称
private String mName;
// 蓝牙远程设备
// 表示远程蓝牙设备。BluetoothDevice允许您创建与相应设备的连接,或者查询有关设备的信息,比如名称、地址、类和绑定状态。
public BluetoothMessage(BluetoothDevice device)
this.mDevice = device;
// 设置名称
public void setName(String name)
this.mName = name;
// 获取设备
public BluetoothDevice getDevice()
return mDevice;
// 获取名称
public String getName()
return mName;
基于stm32的智能小车app自学梳理(代码片段)
文章目录目录文章目录前言一、基本逻辑梳理二、android部分蓝牙扫描2.1、权限申请2.2、相关变量2.3、onCreate一些初始化操作2.3.1、位置权限2.3.2、控件初始化2.3.3、蓝牙初始化2.4、蓝牙回调函数2.4.1、高版本蓝牙回调24.2、低版本蓝... 查看详情
关于智能小车基于stm32和传感器码盘的测速(代码片段)
光电传感器有遮挡时,输出高电平;无遮挡,输出低电平。我们接受到一次低电平时,把这个脉冲加一,轮子上有编码圈一圈可以让脉冲累加20次。我用了2个定时器和两个外部中断,定时器分别用来仿PWM输... 查看详情
基于stm32的智能小车(远程控制避障循迹)(代码片段)
学完stm32,总是想做点东西“大显身手”一下,智能小车就成了首选项目,其核心只是就是PWM输出,I/O口引脚电平判断。制作智能小车的硬件名单:制作智能小车的硬件列表: (1)STM32C8T6核心板 ... 查看详情
基于stm32c8t6的智能蓝牙小车控制设计-毕设课设资料(代码片段)
stm32最小系统(10r)型号具体为STM32F103C8T6jdy-31蓝牙模块(10r)L298N继电器模块(10r)直流步进电机版直插电解小车底座50-70r(套装包括四个直流电机四个车轮两块亚克力板车身)#include"stm32f10x_gpio... 查看详情
基于stm32f407设计的蓝牙遥控小车(代码片段)
开始语新的博客来了,博主继上个做完智能台灯项目后一直想做智能小车项目,在做老师给的项目之外抽空做了一下小车;首先强调一下,这个小车只是半成品,按照我的进度只做到50%,写这篇的博客的目... 查看详情
毕业设计:基于单片机的超声波智能跟随小车-物联网智能小车嵌入式单片机stm32跟随小车(代码片段)
文章目录1项目简介2课题背景3硬件说明3.1小车硬件设计3.2小车底座3.3无线收发器3.4超声波模块3.5直流电机和电源3.6目标携带装置3.7整体电路图4跟随系统的软件设计4.1方案一:4.2方案二:4.3方案三:5相关代码效果演示6... 查看详情
基于stm32f103的智能门锁系统(代码片段)
基于STM32F103的智能门锁系统直接说明实现了什么效果1指纹解锁(基于AS608)2RFID解锁(基于RC522)3密码解锁(基于LCD电容屏触摸控制)4蓝牙解锁(基于HC-06)5后台服务器管理开锁信息(基于ESP8266)6APP... 查看详情
毕业设计之-题目:基于stm32的wifi监控小车(代码片段)
文章目录1背景2系统设计方案2.1实现功能2.1.1硬件部分:2.1.2软件部分:2.1.3WIFI通信功能:2.2系统架构2.2.1WiFi通信2.2.2电机驱动2.2.3摄像头2.2.4舵机2.2.5PWM舵机控制2.2.6红外循迹模块3软件设计4测试效果5部分关键代码6最后1... 查看详情
基于stm32设计的避障寻迹小车(代码片段)
一、前言1.1项目背景根据美国玩具协会在一项研究中,过去几年全球玩具销售增长与GDP的世界平均水平大致相同。但全球玩具市场的内部结构已经占据了巨大的位置变化:传统玩具的市场份额正在下降,高科技电子玩... 查看详情
毕业设计-题目:基于stm32的自动泊车系统-智能小车自动停车(代码片段)
...f0c;这里是丹成学长,今天向大家介绍一个单片机项目基于STM32的自动泊车系统大家可用于课程设计或毕业设计技术解答、毕设帮助、开题指导print("Q746876041")1背景目前我们所能见到的汽车企业大多数都控制在L2级半自动... 查看详情
5♥☆基于stm32的智能手环√★☆(代码片段)
5、♥☆基于STM32的智能手环√★☆💙💙文章目录5、♥☆基于STM32的智能手环√★☆💙💙Introduction引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2系统概述2.3、设计要求2.4、系... 查看详情
5♥☆基于stm32的智能手环√★☆(代码片段)
5、♥☆基于STM32的智能手环√★☆💙💙文章目录5、♥☆基于STM32的智能手环√★☆💙💙Introduction引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2系统概述2.3、设计要求2.4、系... 查看详情
7基于stm32的智能风扇√★(代码片段)
7、💗💗基于STM32的智能风扇√★💗💗文章目录7、💗💗基于STM32的智能风扇√★💗💗Introduction引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.1.1、控制核心的... 查看详情
7基于stm32的智能风扇√★(代码片段)
7、💗💗基于STM32的智能风扇√★💗💗文章目录7、💗💗基于STM32的智能风扇√★💗💗Introduction引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.1.1、控制核心的... 查看详情
项目五:基于stm32f103的寻迹小车(代码片段)
前言:传感器工作原理:代码部分: main.c#include"motor.h"#include<stdio.h>#include"delay.h"#include"stm32f10x.h"#include"followline.h"#include"ultrasonic 查看详情
基于stm32的智能鱼缸设计(代码片段)
...省鱼友时间、劳力、增加养鱼乐趣;为此,本文基于STM32单片机设计了一款智能鱼缸。该鱼缸可以实现水温检测、水质检测、自动或手动换水、氛围灯灯光变换和自动或手动喂食等功能为一体的控制系统,可通过控制... 查看详情
基于stm32f4开发的智能台灯(代码片段)
基于STM32F4开发的智能台灯写这篇博客的目的有2个,首先是记录一下学习STM32大半年来的第一个自己动手开发的项目,整理一下开发过程和思路;其次也是希望可以和更多的同行交流开发经验,有什么问题可以多多... 查看详情
第二天:slam智能小车diy乐趣-小车控制stm32软件基础
SLAM智能小车DIY乐趣-小车控制stm32软件基础####写在前面####前面介绍了小车控制stm32硬件基础,本文就来介绍配套的小车控制stm32软件基础。关于stm32开发相关的基础知识这里就不多说了,有需要的小伙伴可以查阅相关资料进行学习... 查看详情