-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from everevian/nobra
NobraControl integration
- Loading branch information
Showing
5 changed files
with
130 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Nobra Integration | ||
|
||
Basic integration for Nobra devices is included with the Edge-O-Matic-3000. | ||
|
||
### Setup | ||
1. Turn on your Nobra device. | ||
2. A green light indicates 'AzureFang' is enabled. | ||
3. If the light is not green, press the outer two buttons on the control box at the same time and power cycle the device. | ||
4. Turn the main control knob so that the Nobra device is vibrating slightly. | ||
5. With your EOM3k, push the knob and select "Network Settings > Bluetooth Pair". | ||
6. Select "NobraControl" to pair. | ||
7. The EOM3k is now controlling your Nobra device. | ||
|
||
### Configuration | ||
The Nobra's main intensity knob essentially takes over the EOM3k's clamping of motor speed. This is why step 4 in Setup suggests to turn the intensity up until it's vibrating slightly - otherwise, it can appear the 'AzureFang' connection is not working. | ||
|
||
Put another way, you want to configure your EOM3k's "Motor Max Speed" to be the highest it will go (255). This lets you fully adjust the intensity on the NobraControl device. | ||
|
||
So the basic procedure after the 'AzureFang' connection is established is to enter manual mode, turn the EOM3k to max, and configure the NobraControl knobs to a suitable maximum intensity. Then you are ready for the automated modes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#ifndef __drivers_Nobra_h | ||
#define __drivers_Nobra_h | ||
|
||
#include "drivers/Device.h" | ||
|
||
#define CMD_MAX_LEN 40 | ||
|
||
namespace BluetoothDriver { | ||
class Nobra : public Device { | ||
public: | ||
Nobra(const char *name, NimBLEClient *client, NimBLERemoteCharacteristic *remote) : | ||
Device(name, client), remote(remote) {}; | ||
|
||
static Device* detect(NimBLEAdvertisedDevice *device, NimBLEClient *client, NimBLERemoteService *service); | ||
|
||
bool setSpeed(uint8_t speed) override; | ||
|
||
protected: | ||
char mapSpeed(uint8_t speed); | ||
bool send(const char *cmd); | ||
bool sendf(const char *fmt, ...); | ||
|
||
private: | ||
NimBLERemoteCharacteristic *remote; | ||
char lastSentSpeed; | ||
}; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#include "drivers/Nobra.h" | ||
#include <cmath> | ||
|
||
using namespace BluetoothDriver; | ||
|
||
static const char* TAG = "BluetoothDriver::Nobra"; | ||
|
||
char Nobra::mapSpeed(uint8_t speed) { | ||
const uint8_t nobraSpeedResolution = 15; | ||
float proportion = float(speed) / 255.0; | ||
uint8_t nobraSpeed = round(nobraSpeedResolution * proportion); | ||
if (nobraSpeed == 0) { | ||
return 'p'; | ||
} | ||
char output = 'a' - 1 + nobraSpeed; | ||
return output; | ||
} | ||
|
||
bool Nobra::setSpeed(uint8_t speed) { | ||
char speedCommand = mapSpeed(speed); | ||
|
||
bool isShiftingGears = lastSentSpeed != speedCommand; | ||
if (!isShiftingGears) { | ||
return false; | ||
} | ||
|
||
return this->sendf("%c", speedCommand); | ||
} | ||
|
||
bool Nobra::send(const char* cmd) { | ||
if (!this->isConnected()) { | ||
ESP_LOGE(TAG, "Client was disconnected."); | ||
return false; | ||
} | ||
|
||
std::string cmdStr(cmd); | ||
if (!this->remote->writeValue(cmdStr, false)) { | ||
ESP_LOGE(TAG, "Write failed, disconnect."); | ||
this->disconnect(); | ||
return false; | ||
} | ||
|
||
ESP_LOGD(TAG, "- remote = %s", this->remote->getUUID().toString().c_str()); | ||
ESP_LOGI(TAG, "Send command: \"%s\"", cmd); | ||
return true; | ||
} | ||
|
||
bool Nobra::sendf(const char* fmt, ...) { | ||
char cmd[CMD_MAX_LEN + 1] = ""; | ||
va_list args; | ||
va_start(args, fmt); | ||
vsniprintf(cmd, CMD_MAX_LEN, fmt, args); | ||
va_end(args); | ||
return send(cmd); | ||
} | ||
|
||
Device* Nobra::detect(NimBLEAdvertisedDevice* device, NimBLEClient* client, NimBLERemoteService* service) { | ||
std::vector<NimBLERemoteCharacteristic*> *chars = service->getCharacteristics(true); | ||
NimBLERemoteCharacteristic *writeChar = nullptr; | ||
|
||
for (NimBLERemoteCharacteristic* c : *chars) { | ||
if (c->canWriteNoResponse()) { | ||
writeChar = c; | ||
} | ||
} | ||
const char *deviceName = device->getName().c_str(); | ||
bool writeCharacteristicFound = writeChar != nullptr; | ||
bool looksLikeNobra = std::string(deviceName).find("NobraControl") != std::string::npos; | ||
if (writeCharacteristicFound && looksLikeNobra) { | ||
Nobra *nobraDevice = new Nobra(deviceName, client, writeChar); | ||
return (BluetoothDriver::Device *)nobraDevice; | ||
} | ||
} |