Feat: some optimization and fixes
This commit is contained in:
parent
e16904fae9
commit
853a58dab4
5 changed files with 76 additions and 41 deletions
|
@ -13,7 +13,7 @@
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
#define TAG "main"
|
#define TAG "main"
|
||||||
#define TRIGGER_PIN GPIO_NUM_23
|
#define TRIGGER_PIN GPIO_NUM_12
|
||||||
#define BLE_SERVICE_UUID "deea3136-d728-4f23-823a-104290000000"
|
#define BLE_SERVICE_UUID "deea3136-d728-4f23-823a-104290000000"
|
||||||
#define BLE_CURRENTTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000001"
|
#define BLE_CURRENTTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000001"
|
||||||
#define BLE_LASTTRIGGERTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000002"
|
#define BLE_LASTTRIGGERTIME_CHARACTERISTIC_UUID "deea3136-d728-4f23-823a-104290000002"
|
||||||
|
@ -55,11 +55,10 @@ class LocalServerCallbacks : public NimBLEServerCallbacks
|
||||||
|
|
||||||
class LocalCharacteristicCallbacks : public NimBLECharacteristicCallbacks
|
class LocalCharacteristicCallbacks : public NimBLECharacteristicCallbacks
|
||||||
{
|
{
|
||||||
void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override
|
void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override
|
||||||
{
|
{
|
||||||
bleCurrentTimeCharacteristic->setValue(esp_timer_get_time() / 1000);
|
bleCurrentTimeCharacteristic->setValue(esp_timer_get_time() / 1000);
|
||||||
bleCurrentTimeCharacteristic->notify();
|
// ESP_LOGI(TAG, "Characteristic read!");
|
||||||
// ESP_LOGI(TAG, "Characteristic written!");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,9 +93,7 @@ void app_main()
|
||||||
|
|
||||||
bleCurrentTimeCharacteristic = bleService->createCharacteristic(
|
bleCurrentTimeCharacteristic = bleService->createCharacteristic(
|
||||||
BLE_CURRENTTIME_CHARACTERISTIC_UUID,
|
BLE_CURRENTTIME_CHARACTERISTIC_UUID,
|
||||||
NIMBLE_PROPERTY::READ |
|
NIMBLE_PROPERTY::READ);
|
||||||
NIMBLE_PROPERTY::WRITE |
|
|
||||||
NIMBLE_PROPERTY::NOTIFY);
|
|
||||||
bleCurrentTimeCharacteristic->addDescriptor(new NimBLE2904());
|
bleCurrentTimeCharacteristic->addDescriptor(new NimBLE2904());
|
||||||
bleCurrentTimeCharacteristic->setCallbacks(new LocalCharacteristicCallbacks());
|
bleCurrentTimeCharacteristic->setCallbacks(new LocalCharacteristicCallbacks());
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,6 @@ async function startBluetooth() {
|
||||||
bluetoothService = await server.getPrimaryService(BLUETOOTH_BUZZER_SERVICE_UUID);
|
bluetoothService = await server.getPrimaryService(BLUETOOTH_BUZZER_SERVICE_UUID);
|
||||||
|
|
||||||
bluetoothCharacteristics.currentTime = await bluetoothService.getCharacteristic(BLUETOOTH_BUZZER_SERVICE_BASE_UUID + '000' + (1));
|
bluetoothCharacteristics.currentTime = await bluetoothService.getCharacteristic(BLUETOOTH_BUZZER_SERVICE_BASE_UUID + '000' + (1));
|
||||||
await bluetoothCharacteristics.currentTime.startNotifications();
|
|
||||||
bluetoothCharacteristics.currentTime.addEventListener('characteristicvaluechanged', handleNotifications);
|
|
||||||
|
|
||||||
bluetoothCharacteristics.lastTriggerTime = await bluetoothService.getCharacteristic(BLUETOOTH_BUZZER_SERVICE_BASE_UUID + '000' + (2));
|
bluetoothCharacteristics.lastTriggerTime = await bluetoothService.getCharacteristic(BLUETOOTH_BUZZER_SERVICE_BASE_UUID + '000' + (2));
|
||||||
await bluetoothCharacteristics.lastTriggerTime.startNotifications();
|
await bluetoothCharacteristics.lastTriggerTime.startNotifications();
|
||||||
|
@ -95,9 +93,7 @@ function handleNotifications(this: BluetoothRemoteGATTCharacteristic, event: Eve
|
||||||
|
|
||||||
const characteristic = event.target as BluetoothRemoteGATTCharacteristic;
|
const characteristic = event.target as BluetoothRemoteGATTCharacteristic;
|
||||||
|
|
||||||
if (characteristic.uuid == bluetoothCharacteristics.currentTime?.uuid)
|
if (characteristic.uuid == bluetoothCharacteristics.lastTriggerTime?.uuid)
|
||||||
handleNewCurrentTime(new DataView(characteristic.value!.buffer, 0).getBigUint64(0, true));
|
|
||||||
else if (characteristic.uuid == bluetoothCharacteristics.lastTriggerTime?.uuid)
|
|
||||||
handleNewLastTriggerTime(new DataView(characteristic.value!.buffer, 0).getBigUint64(0, true));
|
handleNewLastTriggerTime(new DataView(characteristic.value!.buffer, 0).getBigUint64(0, true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,13 +105,9 @@ async function doOneTimeSync() {
|
||||||
|
|
||||||
let sentAt = performance.now();
|
let sentAt = performance.now();
|
||||||
|
|
||||||
const remoteTime = new Promise<bigint>((resolve) => {
|
const remoteTime = await bluetoothCharacteristics.currentTime.readValue();
|
||||||
timeSyncResponse = resolve;
|
|
||||||
});
|
|
||||||
|
|
||||||
await bluetoothCharacteristics.currentTime.writeValueWithResponse(new ArrayBuffer(0));
|
let time = remoteTime.getBigUint64(0, true);
|
||||||
|
|
||||||
let time = await remoteTime;
|
|
||||||
let receivedAt = performance.now();
|
let receivedAt = performance.now();
|
||||||
|
|
||||||
ntp.handleTimeSync(BigInt(Math.floor(sentAt)), BigInt(Math.floor(receivedAt)), time);
|
ntp.handleTimeSync(BigInt(Math.floor(sentAt)), BigInt(Math.floor(receivedAt)), time);
|
||||||
|
@ -126,14 +118,6 @@ async function doOneTimeSync() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNewCurrentTime(time: bigint) {
|
|
||||||
if (timeSyncResponse === undefined)
|
|
||||||
return;
|
|
||||||
|
|
||||||
timeSyncResponse(time);
|
|
||||||
timeSyncResponse = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleNewLastTriggerTime(time: bigint) {
|
function handleNewLastTriggerTime(time: bigint) {
|
||||||
if (ntp === undefined) return;
|
if (ntp === undefined) return;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,30 @@
|
||||||
import Timer from './Timer.svelte';
|
import Timer from './Timer.svelte';
|
||||||
|
|
||||||
const uap = new UAParser();
|
const uap = new UAParser();
|
||||||
|
let timer: Timer;
|
||||||
|
|
||||||
|
let state: 'idle' | 'wait' | 'ready' | 'running' = 'idle';
|
||||||
|
|
||||||
|
const delay = (time: number) => {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, time));
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = async () => {
|
||||||
|
state = 'wait';
|
||||||
|
await delay(3000);
|
||||||
|
state = 'ready';
|
||||||
|
await new Audio('/sound/ok-ready-go.mp3').play();
|
||||||
|
await delay(2600);
|
||||||
|
timer.start();
|
||||||
|
state = 'running';
|
||||||
|
};
|
||||||
|
|
||||||
|
const PLACEHOLDERS = {
|
||||||
|
idle: 'Press start!',
|
||||||
|
wait: 'At your marks!',
|
||||||
|
ready: 'Ready!',
|
||||||
|
running: ''
|
||||||
|
};
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
checkAvailability();
|
checkAvailability();
|
||||||
|
@ -39,7 +63,27 @@
|
||||||
{/if}.
|
{/if}.
|
||||||
</span>
|
</span>
|
||||||
{:else if $bluetoothState == 'CONNECTED'}
|
{:else if $bluetoothState == 'CONNECTED'}
|
||||||
<Timer />
|
<Timer placeholder={PLACEHOLDERS[state]} bind:this={timer} />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
disabled={state == 'wait' || state == 'ready'}
|
||||||
|
on:click={() => {
|
||||||
|
if (state == 'idle') {
|
||||||
|
start();
|
||||||
|
} else if (state == 'running') {
|
||||||
|
timer.reset();
|
||||||
|
state = 'idle';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if state == 'idle'}
|
||||||
|
Start!
|
||||||
|
{:else if state == 'running'}
|
||||||
|
Reset!
|
||||||
|
{:else}
|
||||||
|
Wait ...
|
||||||
|
{/if}
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<Alert color="yellow">Connecting...</Alert>
|
<Alert color="yellow">Connecting...</Alert>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -3,6 +3,19 @@
|
||||||
import { buzzerState } from '../stores';
|
import { buzzerState } from '../stores';
|
||||||
import { Button } from 'flowbite-svelte';
|
import { Button } from 'flowbite-svelte';
|
||||||
|
|
||||||
|
export const start = () => {
|
||||||
|
timerStartedAt = BigInt(Math.floor(performance.now()));
|
||||||
|
timerStoppedAt = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reset = () => {
|
||||||
|
timerStartedAt = undefined;
|
||||||
|
timerStoppedAt = undefined;
|
||||||
|
currentTimerValue = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export let placeholder: string = '';
|
||||||
|
|
||||||
let timerStartedAt: bigint | undefined;
|
let timerStartedAt: bigint | undefined;
|
||||||
let timerStoppedAt: bigint | undefined;
|
let timerStoppedAt: bigint | undefined;
|
||||||
|
|
||||||
|
@ -48,22 +61,19 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col items-center gap-3">
|
<div class="flex flex-col items-center gap-3 pb-6">
|
||||||
<div class="w-full flex flex-row flex-wrap gap-3 justify-center">
|
<div class="w-full flex flex-row flex-wrap gap-3 justify-center">
|
||||||
<div class="flex flex-grow flex-col items-center">
|
<div class="flex flex-grow flex-col items-center">
|
||||||
|
{#if placeholder.length > 0}
|
||||||
|
<span class="text-6xl font-bold text-white py-6 text-center"> {placeholder}</span>
|
||||||
|
{:else}
|
||||||
<span
|
<span
|
||||||
class="text-9xl font-bold"
|
class="text-9xl font-bold"
|
||||||
style="color: {getTimerColor(timerStartedAt, timerStoppedAt)};"
|
style="color: {getTimerColor(timerStartedAt, timerStoppedAt)};"
|
||||||
>
|
>
|
||||||
{(Number(currentTimerValue ?? 0) / 1000).toFixed(3)}
|
{(Number(currentTimerValue ?? 0) / 1000).toFixed(3)}
|
||||||
</span>
|
</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
|
||||||
on:click={() => {
|
|
||||||
timerStartedAt = BigInt(Math.floor(performance.now()));
|
|
||||||
timerStoppedAt = undefined;
|
|
||||||
}}>Start!</Button
|
|
||||||
>
|
|
||||||
|
|
BIN
static/sound/ok-ready-go.mp3
Normal file
BIN
static/sound/ok-ready-go.mp3
Normal file
Binary file not shown.
Loading…
Reference in a new issue