484|8

65

帖子

0

TA的资源

一粒金砂(中级)

SparkFun Pro nRF52840 Mini 蓝牙广播湿温度DHT11 [复制链接]

本帖最后由 御坂10032号 于 2024-6-28 03:57 编辑

前几篇测评文章详细说明了如何使用蓝牙功能以及结合App来接收到来自开发板发送的蓝牙数据(单Hex)本节我们将结合一个湿温度传感器来将湿温度数据发送给上位机。

 

本章节使用的湿温度传感器为DHT11。 由于使用的是Arduino的开发环境,所以关于DHT11的驱动库可以很轻松的从Arduino的IDE中找到。 我们可以在Arduino的库管理器中搜索DHT-sensor-library,我已经附上了链接

 

image.png  

 

一点很友好的就是github的这个库还提供了非常详细的Demo example

 

image.png   其中这个库,我们可以看到一共支持三种传感器,分别是 DHT 11,DHT 22  (AM2302), AM2321 和 DHT 21 (AM2301)

 

image.png  

我们简单的在上述代码上修改一下。

#include <DHT.h>
#include <Arduino.h>
#include <bluefruit.h>


#define DHTPIN 2      // DHT11 数据引脚连接到 Arduino 的数字引脚 2
#define DHTTYPE DHT11 // 定义传感器类型为 DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test!");

  dht.begin();
}

void loop() {
  // 延迟两秒钟
  delay(1000);

  // 获取温度和湿度数据
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // 检查是否读取失败并打印相应信息
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // 打印温度和湿度数据
  Serial.print(F("Humidity: "));
  Serial.print(humidity);
  Serial.print(F("%  Temperature: "));
  Serial.print(temperature);
  Serial.println(F("°C"));
}

 

这样的话,将IO2 连接到DHT11 上便可以读取到DHT11的数据了。 那么我们结合上一节蓝牙广播的代码在上述代码上再修改一次,使其将湿温度的数据通过蓝牙数据发送出去。

 

#include <DHT.h>
#include <bluefruit.h>
#include <Arduino_JSON.h>

#define DHTPIN 2       // DHT11 数据引脚连接到 Arduino 的数字引脚 2
#define DHTTYPE DHT11  // 定义传感器类型为 DHT11

DHT dht(DHTPIN, DHTTYPE);

// BLE Service
BLEDfu bledfu;    // OTA DFU service
BLEDis bledis;    // device information
BLEUart bleuart;  // uart over ble
BLEBas blebas;    // battery

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

#if CFG_DEBUG
  // Blocking wait for connection when debug mode is enabled via IDE
  while (!Serial) yield();
#endif

  Serial.println("Bluefruit52 BLEUART Example");
  Serial.println("---------------------------\n");

  // Setup the BLE LED to be enabled on CONNECT
  // Note: This is actually the default behavior, but provided
  // here in case you want to control this LED manually via PIN 19
  Bluefruit.autoConnLed(true);

  // Config the peripheral connection with maximum bandwidth
  // more SRAM required by SoftDevice
  // Note: All config***() function must be called before begin()
  Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);

  Bluefruit.begin();
  Bluefruit.setTxPower(4);  // Check bluefruit.h for supported values
  //Bluefruit.setName(getMcuUniqueID()); // useful testing with multiple central connections
  Bluefruit.Periph.setConnectCallback(connect_callback);
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  // To be consistent OTA DFU should be added first if it exists
  bledfu.begin();

  // Configure and Start Device Information Service
  bledis.setManufacturer("Adafruit Industries");
  bledis.setModel("Bluefruit Feather52");
  bledis.begin();

  // Configure and Start BLE Uart Service
  bleuart.begin();

  // Start BLE Battery Service
  blebas.begin();
  blebas.write(100);

  // Set up and start advertising
  startAdv();

  dht.begin();
}

void startAdv(void) {
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();

  // Include bleuart 128-bit uuid
  Bluefruit.Advertising.addService(bleuart);

  // Secondary Scan Response packet (optional)
  // Since there is no room for 'Name' in Advertising packet
  Bluefruit.ScanResponse.addName();

 
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);  // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);    // number of seconds in fast mode
  Bluefruit.Advertising.start(0);              // 0 = Don't stop advertising after n seconds
}

void loop() {


    delay(500);
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();

    if (isnan(humidity) || isnan(temperature)) {
      Serial.println(F("Failed to read from DHT sensor!"));
      return;
    }

    // 只保留整数部分
    int humidityInt = (int)humidity;
    int temperatureInt = (int)temperature;

    // 创建JSON对象
    JSONVar jsonObj;
    jsonObj["temperature"] = temperatureInt;
    jsonObj["humidity"] = humidityInt;

    // 将JSON对象转换为字符串
    String jsonString = JSON.stringify(jsonObj);

    // 将JSON字符串转换为字节数组
    uint8_t buf[64];
    int len = jsonString.length();
    jsonString.getBytes(buf, len + 1);

    // 通过BLE UART发送字节数组
    bleuart.write(buf, len);
    // 打印到串口监视器
    Serial.println(jsonString);

}

// callback invoked when central connects
void connect_callback(uint16_t conn_handle) {
  // Get the reference to current connection
  BLEConnection* connection = Bluefruit.Connection(conn_handle);

  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));

  Serial.print("Connected to ");
  Serial.println(central_name);
}

/**
 * Callback invoked when a connection is dropped
 * @param conn_handle connection where this event happens
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
  (void)conn_handle;
  (void)reason;

  Serial.println();
  Serial.print("Disconnected, reason = 0x");
  Serial.println(reason, HEX);
}

 

可以看到,在上述代码的主循环中,获取到湿温度数据之后,把转换成INT类型之后使用Arduino_JSON 把它转换成JSON格式。然后通过蓝牙发送到上位机

如果你本地没有安装Arduino_JSON的话,需要先在库管理器中安装Arduino_JSON

 

image.png  

之后我们便可以将代码烧录到开发板中,并且使用上一章节我提及的蓝牙工具进行数据接收。

 

实验现象如下:

 

b2880742cf30b23e336315fff798099.jpg  

 

本来我想在这一章节用安卓Studio写一个上位机软件,接收蓝牙数据,然后显示折线图。但是不知道为什么我这个安卓手机没办法连接到这个开发板的蓝牙。 IOS的开发我不会。所以只能使用App store 里的软件来展示效果。 之后再有打算的话。应该是构建一个安卓程序,接收蓝牙数据,然后解析为ASCII格式。再解析JSON然后根据JSON 的 data object  绘制折线图。 这边还有一种做法就是把数据使用MQTT上传到Home assistant。 手机端使用Home assistant 来实时查看这个信息。但是总是感觉多此一举。 改天试试我女朋友的手机,然后可以用的话我build 个 APP 然后在这个帖子上附加上GITHUB仓库的地址。

 

  

此帖出自RF/无线论坛

最新回复

感谢感谢大佬的指点,他还支持哪些开发呀?   详情 回复 发表于 2024-6-28 13:56

回复
举报

5224

帖子

5

TA的资源

版主

安卓Studio写一个上位机软件这工作量快赶上这次测评了,无线传输测试就是这样,没法弄好看的测试界面,只能看数据

此帖出自RF/无线论坛

点评

还好的其实,如果只是解析JSON,不考虑数据存储. 图表功能的选择, 很快就能搞定的。  详情 回复 发表于 2024-6-28 12:20
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引


回复

65

帖子

0

TA的资源

一粒金砂(中级)

秦天qintian0303 发表于 2024-6-28 08:49 安卓Studio写一个上位机软件这工作量快赶上这次测评了,无线传输测试就是这样,没法弄好看的测试界面,只能 ...

还好的其实,如果只是解析JSON,不考虑数据存储. 图表功能的选择, 很快就能搞定的。

此帖出自RF/无线论坛

点评

我今天晚上用我女朋友手机试一下  详情 回复 发表于 2024-6-28 12:49

回复

6646

帖子

9

TA的资源

版主

挺好的,我看楼主是用arduino进行开发的,教程丰富吗?

此帖出自RF/无线论坛

点评

Arduino的教程非常丰富而且方便. 像比如复杂的蓝牙协议等它已经提供了封装的库. 仅仅使用几行代码就可以开启广播和发送数据  详情 回复 发表于 2024-6-28 12:37

回复

65

帖子

0

TA的资源

一粒金砂(中级)

lugl4313820 发表于 2024-6-28 12:36 挺好的,我看楼主是用arduino进行开发的,教程丰富吗?

Arduino的教程非常丰富而且方便. 像比如复杂的蓝牙协议等它已经提供了封装的库. 仅仅使用几行代码就可以开启广播和发送数据

此帖出自RF/无线论坛

点评

那简单太方便了,原来看得捷大赛,不敢申请NRF的,怕学不会。  详情 回复 发表于 2024-6-28 13:05

回复

65

帖子

0

TA的资源

一粒金砂(中级)

御坂10032号 发表于 2024-6-28 12:20 还好的其实,如果只是解析JSON,不考虑数据存储. 图表功能的选择, 很快就能搞定的。

我今天晚上用我女朋友手机试一下

此帖出自RF/无线论坛

回复

6646

帖子

9

TA的资源

版主

御坂10032号 发表于 2024-6-28 12:37 Arduino的教程非常丰富而且方便. 像比如复杂的蓝牙协议等它已经提供了封装的库. 仅仅使用几行代码就可以 ...

那简单太方便了,原来看得捷大赛,不敢申请NRF的,怕学不会。

此帖出自RF/无线论坛

点评

我也是看这个支持Arduino的才申请这个的,不然原生开发估计还真的搞不定  详情 回复 发表于 2024-6-28 13:35

回复

65

帖子

0

TA的资源

一粒金砂(中级)

lugl4313820 发表于 2024-6-28 13:05 那简单太方便了,原来看得捷大赛,不敢申请NRF的,怕学不会。

我也是看这个支持Arduino的才申请这个的,不然原生开发估计还真的搞不定

此帖出自RF/无线论坛

点评

感谢感谢大佬的指点,他还支持哪些开发呀?  详情 回复 发表于 2024-6-28 13:56

回复

6646

帖子

9

TA的资源

版主

御坂10032号 发表于 2024-6-28 13:35 我也是看这个支持Arduino的才申请这个的,不然原生开发估计还真的搞不定

感谢感谢大佬的指点,他还支持哪些开发呀?

此帖出自RF/无线论坛

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

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表