【IoT】Arduino 实现 ESP32 BLE 与 Android 手机的数据交互

简介: ESP32 BLE 与 Android 手机的数据交互

1、效果描述:

通过简单的 Android APP 实现与 ESP32 的双向蓝牙通信。

2、实现步骤

Step 1:ESP32 硬件支持

1、支持蓝牙 4.0 以上协议的安卓手机;

2、支持 Micro USB 的 ESP32 dev board;

Step 2:配置 Arduino IDE 环境

1、下载 Arduino IDE:https://www.arduino.cc/en/Main/Software

2、安装 ESP32 支持包:https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md

根据网站步骤安装 GIT 工具,并根据提示下载 BLE 支持开发包

在 Arduino 编写实例:

/*

Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
Ported to Arduino ESP32 by Evandro Copercini

Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"

The design of creating the BLE server is:

  1. Create a BLE Server
  2. Create a BLE Service
  3. Create a BLE Characteristic on the Service
  4. Create a BLE Descriptor on the characteristic
  5. Start the service.
  6. Start advertising.

In this example rxValue is the data received (only accessible inside that function).
And txValue is the data to be sent, in this example just a byte incremented every second.
*/

include <BLEDevice.h>

include <BLEServer.h>

include <BLEUtils.h>

include <BLE2902.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
float txValue = 0;
const int readPin = 32; // Use GPIO number. See ESP32 board pinouts
const int LED = 2; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.

//std::string rxValue; // Could also make this a global var to access it in loop()

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID

define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

class MyServerCallbacks: public BLEServerCallbacks {

void onConnect(BLEServer* pServer) {
  deviceConnected = true;
};

void onDisconnect(BLEServer* pServer) {
  deviceConnected = false;
}

};

class MyCallbacks: public BLECharacteristicCallbacks {

void onWrite(BLECharacteristic *pCharacteristic) {
  std::string rxValue = pCharacteristic->getValue();

  if (rxValue.length() > 0) {
    Serial.println("*********");
    Serial.print("Received Value: ");

    for (int i = 0; i < rxValue.length(); i++) {
      Serial.print(rxValue[i]);
    }

    Serial.println();

    // Do stuff based on the command received from the app
    if (rxValue.find("A") != -1) { 
      Serial.print("Turning ON!");
      digitalWrite(LED, HIGH);
    }
    else if (rxValue.find("B") != -1) {
      Serial.print("Turning OFF!");
      digitalWrite(LED, LOW);
    }

    Serial.println();
    Serial.println("*********");
  }
}

};

void setup() {
Serial.begin(115200);

pinMode(LED, OUTPUT);

// Create the BLE Device
BLEDevice::init("ESP32 UART Test"); // Give it a name

// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());

// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);

// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(

                  CHARACTERISTIC_UUID_TX,
                  BLECharacteristic::PROPERTY_NOTIFY
                );
                  

pCharacteristic->addDescriptor(new BLE2902());

BLECharacteristic *pCharacteristic = pService->createCharacteristic(

                                     CHARACTERISTIC_UUID_RX,
                                     BLECharacteristic::PROPERTY_WRITE
                                   );

pCharacteristic->setCallbacks(new MyCallbacks());

// Start the service
pService->start();

// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}

void loop() {
if (deviceConnected) {

// Fabricate some arbitrary junk for now...
txValue = analogRead(readPin) / 3.456; // This could be an actual sensor reading!

// Let's convert the value to a char array:
char txString[8]; // make sure this is big enuffz
dtostrf(txValue, 1, 2, txString); // float_val, min_width, digits_after_decimal, char_buffer

// pCharacteristic->setValue(&txValue, 1); // To send the integer value
// pCharacteristic->setValue("Hello!"); // Sending a test message

pCharacteristic->setValue(txString);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txString);
Serial.println(" ***");

// You can add the rxValue checks down here instead
// if you set "rxValue" as a global var at the top!
// Note you will have to delete "std::string" declaration
// of "rxValue" in the callback function.

// if (rxValue.find("A") != -1) {
// Serial.println("Turning ON!");
// digitalWrite(LED, HIGH);
// }
// else if (rxValue.find("B") != -1) {
// Serial.println("Turning OFF!");
// digitalWrite(LED, LOW);
// }
}
delay(1000);
}
Step 3:下载安装 APP 测试工具

可以在资源栏下载:https://download.csdn.net/download/liwei16611/10526621

3、代码解释

3.1、库文件:

include <BLEDevice.h>

include <BLEServer.h>

include <BLEUtils.h>

include <BLE2902.h>

创建 BLE 设备:

BLEDevice::init("ESP32 UART Test"); // Give it a name
创建 BLE server:

BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
创建 BLE service:

BLEService *pService = pServer->createService(SERVICE_UUID);
添加 characteristics:

pCharacteristic = pService->createCharacteristic(

                CHARACTERISTIC_UUID_TX,
                BLECharacteristic::PROPERTY_NOTIFY
              );

pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(

                                   CHARACTERISTIC_UUID_RX,
                                   BLECharacteristic::PROPERTY_WRITE
                                 );

pCharacteristic->setCallbacks(new MyCallbacks());
启动广播:

pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
3.2、定义 service 和 characteristic UUID:TX | RX

define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID

define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

3.3、蓝牙连接回调函数

class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {

  deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
  deviceConnected = false;
}

};
3.4、数据接收回调函数

class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {

  std::string rxValue = pCharacteristic->getValue();</p><p>      if (rxValue.length() > 0) {
    Serial.println("*********");
    Serial.print("Received Value: ");</p><p>        for (int i = 0; i < rxValue.length(); i++) {
      Serial.print(rxValue[i]);
    }</p><p>        Serial.println();</p><p>        // Do stuff based on the command received from the app
    if (rxValue.find("A") != -1) { 
      Serial.print("Turning ON!");
      digitalWrite(LED, HIGH);
    }
    else if (rxValue.find("B") != -1) {
      Serial.print("Turning OFF!");
      digitalWrite(LED, LOW);
    }</p><p>        Serial.println();
    Serial.println("*********");
  }
}

};
从《天道》的角度谈谈产品规划
原创2023-02-24 21:05·产品人卫朋
今天主要借用《天道》中丁元英的商业案例来谈谈产品规划这个话题。

《天道》这部被众人追捧的影视剧来源于豆豆的成名作《遥远的救世主》。

如果没有全局做过产品或者市场的规划,而且是初次接触这部剧。

你就会惊叹于主人公的组局、布局,以及成局的能力。

从互联网拥簇的评论声中,也可见一斑。

剧中的丁元英甚至都有一种被神化的趋势。

而随着个人知识和阅历的增加,再加上每年也都要做产品规划。

也逐渐对这部剧或者这本书有了一些新的认识。

究其本质,这是一种战略性的思维,也是一种规划的能力。

更是一种市场与内部能力的匹配过程。

笔者之前也分享过这块的内容,也看到了一些质疑。

怎么能用虚拟的案例做讲解呢?

其实这么做的原因主要有两点考虑:

首先,这部剧中的商业案例的整体逻辑是自洽的,而且也符合当时的商业环境。

其次,整部剧将整个商业案例完整地呈现了出来,也包括其中很多的决策细节。

这就要比分析现实案例直观得多,也更加有指导意义。

再回到产品规划这个话题上来。

产品规划从本质上来说是一种推演能力,也就是根据第一性原则推演产品从0到1、从1到100的一个过程。

如果说一款产品是一个点的话,那产品规划便是通过构造一种系统能力以达成企业最终的商业目的。

第一性原理是埃隆·马斯克非常推崇的一种思维模型。

通常来说,企业愿景对应的便是企业的第一性原则。

围绕第一性原则可以激发资源优势、制定细分市场目标,最终实现企业目标。

下面以影视剧中丁元英操盘的格律诗音响项目为例,谈谈产品规划。

格律诗音响公司的企业愿景是实现王庙村生产力和市场的对接,最终实现农户脱贫。

这是企业的愿景,同时也是丁元英承诺要给红颜知己芮小丹创造的神话。

启动一个项目或产品,资源和人力配置是你首先要考虑的。

企业在不同的发展周期,对人的要求是有很大差异的。

丁元英在分析完这些人的本质之后,并没有把自己的全套计划完整地告诉原始这些人。

而是通过市场的变化来淘汰掉一部分人。

因为这部分人现在不淘汰掉,在以后的市场变化中,可能会给公司带来毁灭性的灾难。

下面就先梳理一下其中的关键人物:

丁元英作为格律诗音响项目的唯一操盘手,全局规划了整个项目。

他的优势是自己在欧洲的人脉和战略规划能力,以及在欧阳雪等人心中的影响力。

同时,作为发烧级音乐玩家,他对音箱的独特见解也为他们打造差异化的产品起到了关键助力作用。

差异化的意思是相比于竞争对手,你的独特优势或者护城河,没有这个前提,整个策略也就无从谈起,这为他们赢得了时间上的先机。

在音响这个市场,竞品已经很成功了,而且他们提供的价值点已经被用户接受。

如果按照他们的价值点去做产品,你就永远只能跟在他们身后。

这时候就需要找一个跟他们不一样的价值点,做差异化。

欧阳雪这个人呢,做事很踏实,很讲义气,不贪心。优势是人脉、资金和社会地位。

这个人的价值在于她对格律诗的绝对控股,这样就可以确保关键决策权的归属。

由于每个人的认知水平的限制,很多时候不同个体看到的终局是有极大差异的,这个时候你就需要考虑如何增加成事的确定性。

如果开公司的话,股权的分配问题是你优先要考虑的。

不赚钱的时候,大家还都能力出一孔。一旦公司有起色,每个人就开始有自己的诉求,不确定性也就随之而来。

肖亚文见过世面,知道公司怎么运行,知道商务谈判和商务合作的事情,是很精明的职场人物。

而冯世杰和叶晓明想成就一番事业,但没有机会,能够脚踏实地的做事情,但眼光欠缺。刘冰是小人物,唯利是图,关键时刻不能顶上,迟早会被淘汰。

叶晓明,冯世杰,刘冰这三个人的优势就是懂音乐,会组装,可以作为高级技术工。

同时,这三人和王庙村农民有一定的关系,可以作为连接的纽带,核心竞争力是技术和人脉。

乐圣公司的掌舵人是林雨峰(竞争对手),但太过刚硬,只知道进攻,不懂防守,考虑问题存在漏洞。

这就有点类似竞争分析了,通过分析竞争对手的漏洞,找到破局点,制定商业竞争策略。

接下来就需要统一思想了:

想要以小博大,达成乐圣跟王庙村合作的目的,就必须把优势发挥到最大效果。

这才有几次股东开会,召集农民兄弟一起开会等,就是为了统一思想。

市场的生存竞争非常残酷,胜负往往就在毫厘之间,微弱的优势都可能成为关键一环,你比他多一口气,你就是赢家。

最后,丁元英就把这些人的优势资源整合起来,按照需要组建公司,精心规划。

详细案例分析可以参阅笔者之前的文章。

卫朋

人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。

卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。

文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。

相关文章
|
4月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
3412 2
|
2天前
|
Java Linux Android开发
移动应用开发与操作系统的交互:深入理解Android和iOS
在数字时代,移动应用成为我们日常生活的一部分。本文将深入探讨移动应用开发的核心概念、移动操作系统的工作原理以及它们如何相互作用。我们将通过实际代码示例,展示如何在Android和iOS平台上创建一个简单的“Hello World”应用,并解释其背后的技术原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和知识。
|
2月前
|
物联网 数据管理 Apache
拥抱IoT浪潮,Apache IoTDB如何成为你的智能数据守护者?解锁物联网新纪元的数据管理秘籍!
【8月更文挑战第22天】随着物联网技术的发展,数据量激增对数据库提出新挑战。Apache IoTDB凭借其面向时间序列数据的设计,在IoT领域脱颖而出。相较于传统数据库,IoTDB采用树形数据模型高效管理实时数据,具备轻量级结构与高并发能力,并集成Hadoop/Spark支持复杂分析。在智能城市等场景下,IoTDB能处理如交通流量等数据,为决策提供支持。IoTDB还提供InfluxDB协议适配器简化迁移过程,并支持细致的权限管理确保数据安全。综上所述,IoTDB在IoT数据管理中展现出巨大潜力与竞争力。
67 1
|
2月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
2天前
|
Ubuntu Linux Android开发
termux+anlinux+Rvnc viewer来使安卓手机(平板)变成linux服务器
本文介绍了如何在Android设备上安装Termux和AnLinux,并通过这些工具运行Ubuntu系统和桌面环境。
18 2
termux+anlinux+Rvnc viewer来使安卓手机(平板)变成linux服务器
|
2月前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
58 1
|
2月前
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
41 6
|
2月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
2月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
2月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。

热门文章

最新文章

  • 1
    若依修改02,若以提供了多种版本,RuoYi-Cloud和SpringBoot+Vue都是PC端的,如果想要适配手机端,用Uniapp+vue,导入Mysql和启动Redis
    104
  • 2
    无法拒绝!GPT-4o 完美适配az手机,畅享丝滑体验
    33
  • 3
    无法拒绝!GPT-4o 完美接入 苹果手机,Siri 更有趣
    195
  • 4
    移动端的打开方式,打开F12之后,就可以看到手机样式设计,移动端的初始化使用normalize.css代码库录到,box-sizing: border-box; 定宽度为多少就是多少,代码库,移动端
    48
  • 5
    vue 项目/备案网页/ip网页打包成 apk 安装到平板/手机(含vue项目跨域代理打包成apk后无法访问接口的解决方案)
    83
  • 6
    软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
    38
  • 7
    软件开发常见流程之兼容性和手机屏页面设计,PC端和移动端常见浏览器,国内的UC都是根据Webkit修改过来的内核,开发重点关注尺寸,常见移动端尺寸汇总,移动端,理想视口根据你设别的样式进行修改
    35
  • 8
    【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
    329
  • 9
    基于SpringBoot+Vue华强北商城二手手机管理系统(源码+部署说明+演示视频+源码介绍+lw)(4)
    44
  • 10
    基于SpringBoot+Vue华强北商城二手手机管理系统(源码+部署说明+演示视频+源码介绍+lw)(3)
    58