Skip to content

Commit

Permalink
Merge pull request #16 from matthias-bs/update-nimble-2.x
Browse files Browse the repository at this point in the history
Updated for NimBLE-Arduino 2.x
  • Loading branch information
matthias-bs authored Jan 25, 2025
2 parents eeca8ab + f0f9feb commit 2a31a0e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 82 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
board:
- esp32:esp32:esp32:DebugLevel=none
- esp32:esp32:esp32:DebugLevel=verbose
- esp32:esp32:lilygo_t3s3:Revision=Radio_LR1121
- esp32:esp32:d1_uno32

runs-on: ubuntu-latest
Expand Down Expand Up @@ -61,8 +62,8 @@ jobs:
run:
|
ps -p "$$"
arduino-cli lib install NimBLE-Arduino@1.4.2
arduino-cli lib install ATC_MiThermometer@0.4.2
arduino-cli lib install NimBLE-Arduino@2.2.0
arduino-cli lib install ATC_MiThermometer@0.5.0

- name: Install platform
if: ${{ env.run-build == 'true' }}
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ATC_MiThermometer
version=0.4.2
version=0.5.0
author=Matthias Prinke <[email protected]>
maintainer=Matthias Prinke <[email protected]>
sentence=Arduino library for BLE ATC_MiThermometer thermometer/hygrometer sensors.
Expand Down
184 changes: 105 additions & 79 deletions src/ATC_MiThermometer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@
// MIT License
//
// Copyright (c) 2022 Matthias Prinke
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -43,149 +43,175 @@
// 20240403 Added reedSwitchState, gpioTrgOutput, controlParameters,
// tempTriggerEvent &humiTriggerEvent
// 20240425 Added device name
// 20250125 Updated for NimBLE-Arduino v2.x
//
// ToDo:
// ToDo:
// -
//
///////////////////////////////////////////////////////////////////////////////////////////////////

#include <ATC_MiThermometer.h>


/*!
* \class MyAdvertisedDeviceCallbacks
*
* \class ScanCallbacks
*
* \brief Callback for advertised device found during scan
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice* advertisedDevice) {
log_d("Advertised Device: %s", advertisedDevice->toString().c_str());
/*
* Here we add the device scanned to the whitelist based on service data but any
* advertised data can be used for your preffered data.
*/
if (advertisedDevice->haveServiceData()) {
/* If this is a device with data we want to capture, add it to the whitelist */
if (advertisedDevice->getServiceData(NimBLEUUID("181A")) != "") {
log_d("Adding %s to whitelist", std::string(advertisedDevice->getAddress()).c_str());
NimBLEDevice::whiteListAdd(advertisedDevice->getAddress());
}
class ScanCallbacks : public NimBLEScanCallbacks
{
private:
void onDiscovered(const NimBLEAdvertisedDevice *advertisedDevice) override
{
log_v("Discovered Advertised Device: %s", advertisedDevice->toString().c_str());
}

void onResult(BLEAdvertisedDevice *advertisedDevice)
{
log_d("Advertised Device: %s", advertisedDevice->toString().c_str());
/*
* Here we add the device scanned to the whitelist based on service data but any
* advertised data can be used for your preffered data.
*/
if (advertisedDevice->haveServiceData())
{
/* If this is a device with data we want to capture, add it to the whitelist */
if (advertisedDevice->getServiceData(NimBLEUUID("181A")) != "")
{
log_d("Adding %s to whitelist", std::string(advertisedDevice->getAddress()).c_str());
NimBLEDevice::whiteListAdd(advertisedDevice->getAddress());
}
}
}
}
};

void onScanEnd(const NimBLEScanResults &results, int reason) override
{
log_v("Scan Ended; reason = %d", reason);
}
} scanCallbacks;

// Set up BLE scanning
void ATC_MiThermometer::begin(bool activeScan)
{
NimBLEDevice::init("");
_pBLEScan = BLEDevice::getScan(); //create new scan
_pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
_pBLEScan->setActiveScan(activeScan); //active scan uses more power, but get results faster
_pBLEScan->setInterval(100);
NimBLEDevice::init("ble-scan");
_pBLEScan = NimBLEDevice::getScan(); // create new scan
_pBLEScan->setScanCallbacks(&scanCallbacks);
_pBLEScan->setActiveScan(activeScan);
_pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL);
_pBLEScan->setWindow(99); // less or equal setInterval value
}
_pBLEScan->setInterval(100);
_pBLEScan->setWindow(99);

}

// Get sensor data by running BLE device scan
unsigned ATC_MiThermometer::getData(uint32_t duration) {
BLEScanResults foundDevices = _pBLEScan->start(duration, false /* is_continue */);

unsigned ATC_MiThermometer::getData(uint32_t scanTime)
{
// Start scanning
// Blocks until all known devices are found or scanTime is expired
BLEScanResults foundDevices = _pBLEScan->getResults(scanTime * 1000, false);

log_d("Whitelist contains:");
for (auto i=0; i<NimBLEDevice::getWhiteListCount(); ++i) {
for (auto i = 0; i < NimBLEDevice::getWhiteListCount(); ++i)
{
log_d("%s", NimBLEDevice::getWhiteListAddress(i).toString().c_str());
}

log_d("Assigning scan results...");
for (unsigned i=0; i<foundDevices.getCount(); i++) {
log_d("haveName(): %d", foundDevices.getDevice(i).haveName());
log_d("getName(): %s", foundDevices.getDevice(i).getName().c_str());

for (unsigned i = 0; i < foundDevices.getCount(); i++)
{
log_d("haveName(): %d", foundDevices.getDevice(i)->haveName());
log_d("getName(): %s", foundDevices.getDevice(i)->getName().c_str());

// Match all devices found against list of known sensors
for (unsigned n = 0; n < _known_sensors.size(); n++) {
log_d("Found: %s comparing to: %s",
foundDevices.getDevice(i).getAddress().toString().c_str(),
BLEAddress(_known_sensors[n]).toString().c_str());
if (foundDevices.getDevice(i).getAddress() == BLEAddress(_known_sensors[n])) {
for (unsigned n = 0; n < _known_sensors.size(); n++)
{
log_d("Found: %s comparing to: %s",
foundDevices.getDevice(i)->getAddress().toString().c_str(),
_known_sensors[n].c_str());
if (foundDevices.getDevice(i)->getAddress().toString() == _known_sensors[n])
{
log_d(" -> Match! Index: %d", n);
data[n].valid = true;
int len = foundDevices.getDevice(i).getServiceData().length();

int len = foundDevices.getDevice(i)->getServiceData().length();
log_d("Length of ServiceData: %d", len);

data[n].name = foundDevices.getDevice(i).getName();
if (len == 15) {

data[n].name = foundDevices.getDevice(i)->getName();
if (len == 15)
{
log_d("Custom format");
// Temperature
int temp_msb = foundDevices.getDevice(i).getServiceData().c_str()[7];
int temp_lsb = foundDevices.getDevice(i).getServiceData().c_str()[6];
int temp_msb = foundDevices.getDevice(i)->getServiceData().c_str()[7];
int temp_lsb = foundDevices.getDevice(i)->getServiceData().c_str()[6];
data[n].temperature = (temp_msb << 8) | temp_lsb;

// Humidity
int hum_msb = foundDevices.getDevice(i).getServiceData().c_str()[9];
int hum_lsb = foundDevices.getDevice(i).getServiceData().c_str()[8];
int hum_msb = foundDevices.getDevice(i)->getServiceData().c_str()[9];
int hum_lsb = foundDevices.getDevice(i)->getServiceData().c_str()[8];
data[n].humidity = (hum_msb << 8) | hum_lsb;

// Battery voltage
int volt_msb = foundDevices.getDevice(i).getServiceData().c_str()[11];
int volt_lsb = foundDevices.getDevice(i).getServiceData().c_str()[10];
int volt_msb = foundDevices.getDevice(i)->getServiceData().c_str()[11];
int volt_lsb = foundDevices.getDevice(i)->getServiceData().c_str()[10];
data[n].batt_voltage = (volt_msb << 8) | volt_lsb;

// Battery state [%]
data[n].batt_level = foundDevices.getDevice(i).getServiceData().c_str()[12];
data[n].batt_level = foundDevices.getDevice(i)->getServiceData().c_str()[12];

// Count
data[n].count = foundDevices.getDevice(i).getServiceData().c_str()[13];
//Flags
uint8_t flagsByte = foundDevices.getDevice(i).getServiceData().c_str()[14];
data[n].reedSwitchState = flagsByte & 0x01; // Extract bit 0 (Reed Switch)
data[n].gpioTrgOutput = (flagsByte >> 1) & 0x01; // Extract bit 1 (GPIO_TRG pin output)
data[n].count = foundDevices.getDevice(i)->getServiceData().c_str()[13];

// Flags
uint8_t flagsByte = foundDevices.getDevice(i)->getServiceData().c_str()[14];
data[n].reedSwitchState = flagsByte & 0x01; // Extract bit 0 (Reed Switch)
data[n].gpioTrgOutput = (flagsByte >> 1) & 0x01; // Extract bit 1 (GPIO_TRG pin output)
data[n].controlParameters = (flagsByte >> 2) & 0x01; // Extract bit 2 (Control parameters)
data[n].tempTriggerEvent = (flagsByte >> 3) & 0x01; // Extract bit 3 (Temperature trigger event)
data[n].humiTriggerEvent = (flagsByte >> 4) & 0x01; // Extract bit 4 (Humidity trigger event)

data[n].tempTriggerEvent = (flagsByte >> 3) & 0x01; // Extract bit 3 (Temperature trigger event)
data[n].humiTriggerEvent = (flagsByte >> 4) & 0x01; // Extract bit 4 (Humidity trigger event)
}
else if (len == 13) {
else if (len == 13)
{
log_d("ATC1441 format");

// Temperature
int temp_lsb = foundDevices.getDevice(i).getServiceData().c_str()[7];
int temp_msb = foundDevices.getDevice(i).getServiceData().c_str()[6];
data[n].temperature = (temp_msb << 8) | temp_lsb;
int temp_lsb = foundDevices.getDevice(i)->getServiceData().c_str()[7];
int temp_msb = foundDevices.getDevice(i)->getServiceData().c_str()[6];
data[n].temperature = (temp_msb << 8) | temp_lsb;
data[n].temperature *= 10;

// Humidity
data[n].humidity = foundDevices.getDevice(i).getServiceData().c_str()[8];
data[n].humidity = foundDevices.getDevice(i)->getServiceData().c_str()[8];
data[n].humidity *= 100;

// Battery voltage
int volt_lsb = foundDevices.getDevice(i).getServiceData().c_str()[11];
int volt_msb = foundDevices.getDevice(i).getServiceData().c_str()[10];
int volt_lsb = foundDevices.getDevice(i)->getServiceData().c_str()[11];
int volt_msb = foundDevices.getDevice(i)->getServiceData().c_str()[10];
data[n].batt_voltage = (volt_msb << 8) | volt_lsb;

// Battery state [%]
data[n].batt_level = foundDevices.getDevice(i).getServiceData().c_str()[9];
} else {
data[n].batt_level = foundDevices.getDevice(i)->getServiceData().c_str()[9];
}
else
{
log_d("Unknown ServiceData format");
}

// Received Signal Strength Indicator [dBm]
data[n].rssi = foundDevices.getDevice(i).getRSSI();
} else {
data[n].rssi = foundDevices.getDevice(i)->getRSSI();
}
else
{
log_d();
}
}
}
return foundDevices.getCount();
}


// Set all array members invalid
void ATC_MiThermometer::resetData(void)
{
for (int i=0; i < _known_sensors.size(); i++) {
for (int i = 0; i < _known_sensors.size(); i++)
{
data[i].valid = false;
}
}

0 comments on commit 2a31a0e

Please sign in to comment.