143 lines
4.3 KiB
C++
143 lines
4.3 KiB
C++
#include "NimBLEDevice.h"
|
|
#include "NimBLEServer.h"
|
|
#include "NimBLEUtils.h"
|
|
#include "NimBLE2904.h"
|
|
#include "NimBLECharacteristic.h"
|
|
#include "NimBLEAdvertising.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "esp_log.h"
|
|
#include "esp_timer.h"
|
|
#include "esp_sleep.h"
|
|
#include "driver/gpio.h"
|
|
#include "driver/rtc_io.h"
|
|
|
|
#define TAG "main"
|
|
#define TRIGGER_PIN GPIO_NUM_12
|
|
#define BLE_SERVICE_UUID "deea3136-d728-4f23-823a-104290000000"
|
|
#define BLE_CURRENTTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000001"
|
|
#define BLE_LASTTRIGGERTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000002"
|
|
|
|
extern "C"
|
|
{
|
|
void app_main();
|
|
}
|
|
|
|
NimBLEServer *bleServer;
|
|
NimBLEService *bleService;
|
|
NimBLECharacteristic *bleCurrentTimeCharacteristic;
|
|
NimBLECharacteristic *bleLastTriggerTimeCharacteristic;
|
|
|
|
QueueHandle_t triggerQueue;
|
|
uint64_t lastTriggerTime = 0;
|
|
|
|
class LocalServerCallbacks : public NimBLEServerCallbacks
|
|
{
|
|
void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override
|
|
{
|
|
// Advertising is automatically stopped after a new connection
|
|
// -> restart to make up to nine concurrent connections possible
|
|
if (pServer->getConnectedCount() < 9)
|
|
{
|
|
NimBLEDevice::startAdvertising();
|
|
}
|
|
ESP_LOGI(TAG, "Device connected!");
|
|
};
|
|
|
|
void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override
|
|
{
|
|
// This is only required for the case that advertising was
|
|
// not restarted due to nine connected devices
|
|
NimBLEDevice::startAdvertising();
|
|
ESP_LOGI(TAG, "Device disconnected!");
|
|
}
|
|
};
|
|
|
|
class LocalCharacteristicCallbacks : public NimBLECharacteristicCallbacks
|
|
{
|
|
void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override
|
|
{
|
|
bleCurrentTimeCharacteristic->setValue(esp_timer_get_time() / 1000);
|
|
// ESP_LOGI(TAG, "Characteristic read!");
|
|
}
|
|
};
|
|
|
|
void handleTrigger(void *)
|
|
{
|
|
uint64_t currentTime = esp_timer_get_time() / 1000;
|
|
|
|
if (currentTime - lastTriggerTime < 1000)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lastTriggerTime = currentTime;
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
xQueueSendFromISR(triggerQueue, ¤tTime, &xHigherPriorityTaskWoken);
|
|
if (xHigherPriorityTaskWoken)
|
|
{
|
|
portYIELD_FROM_ISR();
|
|
}
|
|
}
|
|
|
|
void app_main()
|
|
{
|
|
rtc_gpio_pullup_en(TRIGGER_PIN);
|
|
esp_sleep_enable_ext0_wakeup(TRIGGER_PIN, 0);
|
|
|
|
ESP_LOGI("main", "Starting BLE work!");
|
|
|
|
NimBLEDevice::init("Speed buzzer");
|
|
|
|
bleServer = NimBLEDevice::createServer();
|
|
bleServer->setCallbacks(new LocalServerCallbacks());
|
|
|
|
bleService = bleServer->createService(BLE_SERVICE_UUID);
|
|
|
|
bleCurrentTimeCharacteristic = bleService->createCharacteristic(
|
|
BLE_CURRENTTIME_CHARACTERISTIC_UUID,
|
|
NIMBLE_PROPERTY::READ);
|
|
bleCurrentTimeCharacteristic->addDescriptor(new NimBLE2904());
|
|
bleCurrentTimeCharacteristic->setCallbacks(new LocalCharacteristicCallbacks());
|
|
|
|
bleLastTriggerTimeCharacteristic = bleService->createCharacteristic(
|
|
BLE_LASTTRIGGERTIME_CHARACTERISTIC_UUID,
|
|
NIMBLE_PROPERTY::READ |
|
|
NIMBLE_PROPERTY::NOTIFY);
|
|
bleLastTriggerTimeCharacteristic->addDescriptor(new NimBLE2904());
|
|
|
|
bleService->start();
|
|
|
|
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
|
pAdvertising->addServiceUUID(BLE_SERVICE_UUID);
|
|
pAdvertising->setScanResponse(true);
|
|
pAdvertising->setMinPreferred(0x00);
|
|
NimBLEDevice::startAdvertising();
|
|
|
|
ESP_LOGI("main", "Advertising started!");
|
|
|
|
triggerQueue = xQueueCreate(10, sizeof(uint64_t));
|
|
|
|
gpio_install_isr_service(0);
|
|
gpio_set_pull_mode(TRIGGER_PIN, GPIO_PULLUP_ONLY);
|
|
gpio_set_direction(TRIGGER_PIN, GPIO_MODE_INPUT);
|
|
gpio_set_intr_type(TRIGGER_PIN, GPIO_INTR_NEGEDGE);
|
|
gpio_isr_handler_add(TRIGGER_PIN, handleTrigger, NULL);
|
|
|
|
for (;;)
|
|
{
|
|
uint64_t currentTime;
|
|
if (xQueueReceive(triggerQueue, ¤tTime, 5 * 60 * 1000 / portTICK_PERIOD_MS) == pdTRUE)
|
|
{
|
|
bleLastTriggerTimeCharacteristic->setValue(currentTime);
|
|
bleLastTriggerTimeCharacteristic->notify();
|
|
}
|
|
else if (bleServer->getConnectedCount() == 0)
|
|
{
|
|
esp_deep_sleep_start();
|
|
}
|
|
}
|
|
}
|