This commit is contained in:
vanarebane 2025-02-27 11:34:53 +02:00
parent eed2a53460
commit a50a2d3cb6
5 changed files with 154 additions and 87 deletions

View File

@ -23,7 +23,7 @@
<label for="position_cur" class="pwroff">Position:</label>
<input style="text-align: right;" name="position_cur" value="0" type="text" disabled>
<span style="text-align: center; width: 10px;" >/</span>
<input name="position" value="0" type="text" disabled>
<input name="position_set" value="0" type="text" disabled>
</div>
<div class="profilegroup">
<label for="light" class="pwroff">Light:</label>
@ -98,7 +98,11 @@
sk.addListener('handlePositionNotifications', (e)=>{
$('[name="position_cur"]').val(e.detail.value)
})
sk.addListener('handleScaleNotifications', (e)=>{
sk.addListener('handlePositionSetNotifications', (e)=>{
$('[name="position_set"]').val(e.detail.value)
})
sk.addListener('handlePushNotifications', (e)=>{
if(e.detail.value == 1){
$('#strain_push').addClass('active')
}
@ -106,6 +110,12 @@
$('#strain_push').removeClass('active')
}
})
sk.addListener('handleScaleNotifications', (e)=>{
$('[name="strain_raw"]').val(e.detail.value)
})
sk.addListener('handleButtonNotifications', (e)=>{
$('[name="knob_button"]').val(e.detail.value)
})
/////////////////////////////////////////////////

View File

@ -43,13 +43,12 @@ const SmartKnob = class {
'error': "Error"
}
// isConnected = new CustomEvent('isConnected', {detail: {'message': this.debug_messages.connected, 'type': "success"}})
// isDisconnected = new CustomEvent('isDisconnected', {})
serviceUuid = 0x340f // Primary service
serviceCharacteristics = []
useSingleCharacteristics = true
characteristicUuids = {
'ambient': {
'uuid': "0000420f-0000-1000-8000-00805f9b34fb",
@ -89,7 +88,7 @@ const SmartKnob = class {
navigator.bluetooth.addEventListener("availabilitychanged", this.onavailabilitychanged)
// try {
try {
this.eventDisconnected(this.debug_messages.connecting, "processing")
this.log('Requesting Bluetooth Device...');
@ -108,47 +107,42 @@ const SmartKnob = class {
let serviceCharacteristicsList = await service.getCharacteristics()
this.log(serviceCharacteristicsList)
let i=0
// for(let i=0; i<serviceCharacteristicsList.length; i++){
if(this.useSingleCharacteristics){
let i=0 // Just use the first Characteristics
let charac = serviceCharacteristicsList[i]
console.log("startNotifications on "+charac.uuid)
this.serviceCharacteristics[i] = charac //await service.getCharacteristic(charac.uuid);
console.log(this.serviceCharacteristics[i])
// let value = await this.serviceCharacteristics[i].readValue()
// console.log("value: "+ value)
await this.serviceCharacteristics[i].startNotifications();
this.log('> Notifications started on '+charac.uuid);
this.serviceCharacteristics[i].addEventListener('characteristicvaluechanged', this.handleNotifications);
// }
this.serviceCharacteristics[i].addEventListener('characteristicvaluechanged', this.handleCombinedNotifications);
}
else{
for(let i=0; i<serviceCharacteristicsList.length; i++){
let charac = serviceCharacteristicsList[i]
console.log("startNotifications on "+charac.uuid)
this.serviceCharacteristics[i] = charac //await service.getCharacteristic(charac.uuid);
console.log(this.serviceCharacteristics[i])
// let value = await this.serviceCharacteristics[i].readValue()
// console.log("value: "+ value)
await this.serviceCharacteristics[i].startNotifications();
this.log('> Notifications started on '+charac.uuid);
this.serviceCharacteristics[i].addEventListener('characteristicvaluechanged', this.handleNotifications);
}
}
this.eventConnected()
// log('Getting Service 2...');
// const service2 = await server.getPrimaryService(serviceUuid2);
// log('Getting Characteristic 2...');
// powerCharacteristic = await service2.getCharacteristic(powerCharacteristicUuid);
// await powerCharacteristic.startNotifications();
// log('> Notifications started');
// powerCharacteristic.addEventListener('characteristicvaluechanged', handlePwrNotifications);
// document.querySelector('#writeButton').disabled = false;
// log('Reading Alert Level...');
// const value = await serviceCharacteristic.readValue();
// log('> Alert Level: ' + getAlertLevel(value));
// } catch(error) {
// // document.querySelector('#writeButton').disabled = true;
// // NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
// this.log('! BT Connection error' + error);
// this.eventDisconnected(this.debug_messages.tryagain, "error")
// }
} catch(error) {
// NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
this.log('! BT Connection error' + error);
this.eventDisconnected(this.debug_messages.tryagain, "error")
}
}
disconnect(){
@ -179,6 +173,50 @@ const SmartKnob = class {
}
}
handleCombinedNotifications(event) {
let buffer = event.target.value;
console.log(buffer)
// Display raw hex
let a = [];
for (let i = 0; i < buffer.byteLength; i++) {
a.push('0x' + ('00' + buffer.getUint8(i).toString(16)).slice(-2));
}
console.log('>> ' + a.join(' '));
// var data = new Int32Array(buffer);
//let data = bufferToString(value)
// let data = new DataView(buffer, 0)
//let data = new Uint8Array(buffer)
// bit(0) is for boolean values, like push/button
let bools = buffer.getUint8(0)
let button = ((bools>>0)&1)
let push = ((bools>>1)&1)
document.dispatchEvent(new CustomEvent('handleButtonNotifications', {detail: {'value': button}}))
document.dispatchEvent(new CustomEvent('handlePushNotifications', {detail: {'value': push}}))
console.log("Bool values: ", button, push)
// bit(1) is placeholder, not used now
// buffer.getUint8(1)
// bit(2-5) are for current position
let value = buffer.getUint8(2)+(buffer.getUint8(3)*256)+(buffer.getUint8(4)*256)+(buffer.getUint8(5)*256)
if(buffer.getUint8(4) > 0){ // if last two last bits have any value, the value is in negative
value = (value-196096)
}
document.dispatchEvent(new CustomEvent('handlePositionNotifications', {detail: {'value': value}}))
// bit(6-7) are for position config
let position_set = buffer.getUint8(6)+(buffer.getUint8(7)*256)
document.dispatchEvent(new CustomEvent('handlePositionSetNotifications', {detail: {'value': position_set}}))
}
handleNotifications(event) {
console.log(event.currentTarget.uuid)
@ -198,7 +236,8 @@ const SmartKnob = class {
//let data = new Uint8Array(buffer)
switch(event.currentTarget.uuid){
case "602f75a0-697d-4690-8dd5-fa52781446d1":{
// Position
case SmartKnob.characteristicUuids.position.uuid:{
let value = buffer.getUint8(0)+(buffer.getUint8(1)*256)+(buffer.getUint8(2)*256)+(buffer.getUint8(3)*256)
if(buffer.getUint8(2) > 0){
value = (value-196096)
@ -207,19 +246,14 @@ const SmartKnob = class {
document.dispatchEvent(new CustomEvent('handlePositionNotifications', {detail: {'value': value}}))
break;
}
case "0000421f-0000-1000-8000-00805f9b34fb":{
// Scale
case SmartKnob.characteristicUuids.scale.uuid:{
let value = buffer.getUint8(0)
document.dispatchEvent(new CustomEvent('handleScaleNotifications', {detail: {'value': value}}))
break;
}
}
// $('[name="position_cur"]').val(value)
//console.log(value);
//processNotificationState(data)
//document.dispatchEvent(new CustomEvent('handleNotifications', {detail: {'value': value}}))
}

View File

@ -255,6 +255,8 @@ void InterfaceTask::updateHardware() {
#if SK_STRAIN
if (scale.wait_ready_timeout(100)) {
int32_t reading = scale.read();
ble_task_.updateScale(reading);
static uint32_t last_reading_display;
if (millis() - last_reading_display > 1000) {
@ -274,10 +276,12 @@ void InterfaceTask::updateHardware() {
static bool pressed;
if (!pressed && press_value_unit > 0.75) {
motor_task_.playHaptic(true);
ble_task_.updateScale(true);
pressed = true;
changeConfig(true);
} else if (pressed && press_value_unit < 0.25) {
motor_task_.playHaptic(false);
ble_task_.updateScale(false);
pressed = false;
}
}

View File

@ -37,9 +37,7 @@ void BLETask::run() {
// https://www.uuidgenerator.net/
#define SERVICE_UUID "0000340f-0000-1000-8000-00805f9b34fb"
#define SCALE_UUID "0000421f-0000-1000-8000-00805f9b34fb"
#define BUTTON_UUID "0000422f-0000-1000-8000-00805f9b34fb"
#define POSITION_CUR_UUID "602f75a0-697d-4690-8dd5-fa52781446d1"
#define CHARACTERISTIC_UUID "602f75a0-697d-4690-8dd5-fa52781446d1"
// Create the BLE Device
BLEDevice::init("SmartKnob_0123");
@ -54,37 +52,16 @@ void BLETask::run() {
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Characteristic
pCharacteristic1 = pService->createCharacteristic(
POSITION_CUR_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Create a BLE Descriptor
pCharacteristic1->addDescriptor(new BLE2902());
pCharacteristic->addDescriptor(new BLE2902());
// // Create a BLE Characteristic
// pCharacteristic2 = pService->createCharacteristic(
// SCALE_UUID,
// BLECharacteristic::PROPERTY_READ |
// BLECharacteristic::PROPERTY_WRITE |
// BLECharacteristic::PROPERTY_NOTIFY |
// BLECharacteristic::PROPERTY_INDICATE
// );
// // Create a BLE Descriptor
// pCharacteristic2->addDescriptor(new BLE2902());
// // Create a BLE Characteristic
// pCharacteristic3 = pService->createCharacteristic(
// BUTTON_UUID,
// BLECharacteristic::PROPERTY_READ |
// BLECharacteristic::PROPERTY_WRITE |
// BLECharacteristic::PROPERTY_NOTIFY |
// BLECharacteristic::PROPERTY_INDICATE
// );
// // Create a BLE Descriptor
// pCharacteristic3->addDescriptor(new BLE2902());
// Start the service
pService->start();
@ -115,6 +92,7 @@ void BLETask::run() {
//pCharacteristic->notify(); // DOES NOT WORK
}
// Old method here, skip everything if no update from knob
if (xQueueReceive(knob_state_queue_, &state, portMAX_DELAY) == pdFALSE) {
continue;
}
@ -122,10 +100,40 @@ void BLETask::run() {
// notify changed value
if (deviceConnected) {
if (current_position != state.current_position){
pCharacteristic1->setValue((uint8_t*)&state.current_position, 4);
pCharacteristic1->notify();
current_position = state.current_position;
// if (xQueueReceive(knob_state_queue_, &state, portMAX_DELAY) == pdFALSE) {
if (current_position != state.current_position){
current_position = state.current_position;
hasUpdate = true;
}
if (num_positions != state.config.num_positions){
num_positions = state.config.num_positions;
hasUpdate = true;
}
// }
if(hasUpdate){
hasUpdate = false;
// formulate response
response = 0;
if(button_state_) response += 1;
if(press_value_unit_) response += 2;
// if(...) response += 4;
// if(...) response += 8;
// if(...) response += 16;
// if(...) response += 32;
// if(...) response += 64;
// if(...) response += 128;
// if(...) response += 256;
// current position into bit 2-5
response += current_position*65536;
// current position_set into bit 7-8
response += num_positions*(256^7);
pCharacteristic->setValue((uint8_t*)&response, 16);
pCharacteristic->notify();
delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
}
@ -170,6 +178,17 @@ void BLETask::run() {
void BLETask::updateScale(int32_t new_press_value_unit){
press_value_unit_ = new_press_value_unit;
// hasUpdate = true;
}
void BLETask::updateScale(bool new_press_value_state){
press_value_state_ = new_press_value_state;
hasUpdate = true;
}
void BLETask::updateButton(bool new_button_state){
button_state_ = new_button_state;
hasUpdate = true;
}
void BLETask::addListener(QueueHandle_t queue) {

View File

@ -36,11 +36,10 @@ class BLETask : public Task<BLETask> {
public:
BLETask(const uint8_t task_core);
~BLETask();
// void setConfig(const PB_SmartKnobConfig& config);
// void playHaptic(bool press);
// void runCalibration();
void updateScale(int32_t press_value_unit);
void updateScale(bool press_value_state);
void updateButton(bool button_state);
QueueHandle_t getKnobStateQueue();
void addListener(QueueHandle_t queue);
@ -58,14 +57,15 @@ class BLETask : public Task<BLETask> {
// BLE Setup
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic1 = NULL;
BLECharacteristic* pCharacteristic2 = NULL;
BLECharacteristic* pCharacteristic3 = NULL;
BLECharacteristic* pCharacteristic = NULL;
// bool BLE_CONNECTED;
bool oldDeviceConnected = false;
int32_t response = 0;
bool hasUpdate = false;
int32_t press_value_unit_;
int32_t press_value_unit_old;
bool press_value_state_;
bool button_state_;
int32_t current_position;
int32_t num_positions;