御坂10032号 发表于 2024-6-28 01:45

SparkFun Pro nRF52840 Mini 蓝牙广播湿温度DHT11

<div class='showpostmsg'> 本帖最后由 御坂10032号 于 2024-6-28 03:57 编辑

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

<p>&nbsp;</p>

<p>本章节使用的湿温度传感器为DHT11。 由于使用的是Arduino的开发环境,所以关于DHT11的驱动库可以很轻松的从Arduino的IDE中找到。 我们可以在Arduino的库管理器中搜索<a data-testid="breadcrumbs-repo-link" href="https://github.com/adafruit/DHT-sensor-library/tree/master" sx="">DHT-sensor-library</a>,我已经附上了链接</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

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

<p>&nbsp;</p>

<p>&nbsp; 其中这个库,我们可以看到一共支持三种传感器,分别是 DHT 11,DHT 22 &nbsp;(AM2302), AM2321 和 DHT 21 (AM2301)</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>我们简单的在上述代码上修改一下。</p>

<pre>
<code class="language-cpp">#include &lt;DHT.h&gt;
#include &lt;Arduino.h&gt;
#include &lt;bluefruit.h&gt;


#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"));
}
</code></pre>

<p>&nbsp;</p>

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

<p>&nbsp;</p>

<pre>
<code class="language-cpp">#include &lt;DHT.h&gt;
#include &lt;bluefruit.h&gt;
#include &lt;Arduino_JSON.h&gt;

#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;
    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 = { 0 };
connection-&gt;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);
}
</code></pre>

<p>&nbsp;</p>

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

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

<p>&nbsp;</p>

<p> &nbsp;</p>

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

<p>&nbsp;</p>

<p>实验现象如下:</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

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

<p>&nbsp;</p>

<p>&nbsp;&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

秦天qintian0303 发表于 2024-6-28 08:49

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

御坂10032号 发表于 2024-6-28 12:20

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

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

lugl4313820 发表于 2024-6-28 12:36

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

御坂10032号 发表于 2024-6-28 12:37

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

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

御坂10032号 发表于 2024-6-28 12:49

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

<p>我今天晚上用我女朋友手机试一下</p>

lugl4313820 发表于 2024-6-28 13:05

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

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

御坂10032号 发表于 2024-6-28 13:35

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

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

lugl4313820 发表于 2024-6-28 13:56

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

<p>感谢感谢大佬的指点,他还支持哪些开发呀?</p>
页: [1]
查看完整版本: SparkFun Pro nRF52840 Mini 蓝牙广播湿温度DHT11