bluetooth-buzzer/firmware/src/main.cpp
Dorian Zedler 48fe73611d
All checks were successful
/ build (push) Successful in 3m40s
Fix: properly wait for audio
2024-01-20 11:16:01 +01:00

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, &currentTime, &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, &currentTime, 5 * 60 * 1000 / portTICK_PERIOD_MS) == pdTRUE)
{
bleLastTriggerTimeCharacteristic->setValue(currentTime);
bleLastTriggerTimeCharacteristic->notify();
}
else if (bleServer->getConnectedCount() == 0)
{
esp_deep_sleep_start();
}
}
}