- finished implementing protocol

- some changes and cleanup
This commit is contained in:
Dorian Zedler 2020-10-14 23:54:54 +02:00
parent ce6d436c85
commit d74da783b3
Signed by: dorian
GPG key ID: D3B255CB8BC7CD37
9 changed files with 506 additions and 353 deletions

View file

@ -5,6 +5,8 @@
"deque": "cpp", "deque": "cpp",
"string": "cpp", "string": "cpp",
"vector": "cpp", "vector": "cpp",
"unordered_map": "cpp" "unordered_map": "cpp",
"random": "cpp",
"memory": "cpp"
} }
} }

View file

@ -9,6 +9,42 @@
class BluetoothLeUartServerCallbacks; class BluetoothLeUartServerCallbacks;
/*!
* \brief The BluetoothLeUartServer class can be used to connect to another Bluetooth LE device (like an Android phone) effordlessly.
*
* Example use
* \code
* #include <Arduino.h>
* #include "OmobiLedDisplay.h"
*
* BluetoothLeUartServer* server;
*
* class MyCallbacks : public BluetoothLeUartServerCallbacks
* {
* virtual void onDeviceConnectedChanged(bool deviceConnected)
* {
* Serial.println("Device connected changed");
* };
* virtual void onDataReceived(String data)
* {
* Serial.println("Got some data: " + data);
* };
* };
*
* void setup()
* {
* server = new BluetoothLeUartServer("OmobiLedDisplay1", "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e");
* server->setCallbacks(new MyCallbacks());
* }
*
* void loop()
* {
* if(server->getDeviceConnected())
* server->sendData("PING");
* delay(1000);
* }
* \endcode
*/
class BluetoothLeUartServer : protected BLEServerCallbacks, protected BLECharacteristicCallbacks class BluetoothLeUartServer : protected BLEServerCallbacks, protected BLECharacteristicCallbacks
{ {
@ -34,15 +70,18 @@ protected:
void onWrite(BLECharacteristic *rxCharacteristic) override; void onWrite(BLECharacteristic *rxCharacteristic) override;
private: private:
// service and characteristic UUIDs
const char *uartServiceUUID; const char *uartServiceUUID;
const char *rxUUID; const char *rxUUID;
const char *txUUID; const char *txUUID;
// BLE Objects
BLEServer *bleServer; BLEServer *bleServer;
BLEService *bleService; BLEService *bleService;
BLECharacteristic *txCharacteristic; BLECharacteristic *txCharacteristic;
BLECharacteristic *rxCharacteristic; BLECharacteristic *rxCharacteristic;
// helpers
bool deviceConnected = false; bool deviceConnected = false;
BluetoothLeUartServerCallbacks *callbacks; BluetoothLeUartServerCallbacks *callbacks;
}; };
@ -52,7 +91,7 @@ class BluetoothLeUartServerCallbacks
public: public:
virtual ~BluetoothLeUartServerCallbacks(){}; virtual ~BluetoothLeUartServerCallbacks(){};
const char* test = "testlol"; const char *test = "testlol";
virtual void onDeviceConnectedChanged(bool deviceConnected); virtual void onDeviceConnectedChanged(bool deviceConnected);
virtual void onDataReceived(String data); virtual void onDataReceived(String data);

View file

@ -11,88 +11,106 @@
class LedDisplayController class LedDisplayController
{ {
public: public:
explicit LedDisplayController(const byte pin); explicit LedDisplayController(Adafruit_NeoMatrix *matrix);
~LedDisplayController(); ~LedDisplayController();
enum text_align_t enum text_align_t
{ {
TEXTLEFT, AlignLeft,
TEXTCENTER, AlignCenter,
TEXTRIGHT AlignRight
}; };
enum set_param_index_t enum DisplayTextSetParameter
{ {
PTEXT, TextParameter = 0,
PTIME, ActiveParameter,
PCOLOR, RuntimeParameter,
PALIGN, ColorParameter,
PSCROLL, AlignmentParameter,
PSCROLL_RUNS, ScrollParameter,
PACTIVE ScrollSpeedParameter,
ScrollCountParameter,
IndexParameter,
DisplayTextSetParameterCount
}; };
static const uint16_t text_nr_sets = 2; enum GetSetTextSetParameterExitCode
static const uint16_t MAX_TXT_LENGTH = 256;
static const int nr_param_names = 7;
typedef struct text_set_t
{ {
char text[MAX_TXT_LENGTH]; Success,
uint16_t time_ms; InvalidParameterError,
uint16_t color; ParameterNotWritableError,
text_align_t align; ValueOutOfRangeError,
bool text_scroll; IndexOutOfRangeError,
uint16_t text_scroll_pass; ValueIsNullptrError,
bool active; InternalError
} text_set_t; };
typedef struct sets_t static const uint16_t MaximumTextSets = 6;
{ static const uint16_t MaximumTextLength = 256;
text_set_t sets[text_nr_sets];
char valid[3];
} sets_t;
void disp_update(); void loop();
void setTexts(sets_t texts); // modifiers for the internal text sets
sets_t getTexts(); String getTextSetParameter(int index, DisplayTextSetParameter parameter);
GetSetTextSetParameterExitCode setTextSetParameter(int index, DisplayTextSetParameter parameter, String value);
uint16_t Color(uint8_t r, uint8_t g, uint8_t b); // brightness control
int getBrightness();
bool setBrightness(int brightness);
private: private:
// matrix objects
TaskHandle_t displayUpdateTask; TaskHandle_t displayUpdateTask;
Adafruit_NeoMatrix *matrix;
Adafruit_NeoMatrix* matrix; // matrix variables
const String set_param_name[nr_param_names] = {"text_", "time_", "color_", "align_", "scroll_", "scroll_runs_", "active_"};
const uint16_t DISP_STRUCT_SIZE = sizeof(sets_t);
sets_t text_sets;
uint16_t text_curr_nr; uint16_t text_curr_nr;
uint32_t text_set_starttime; uint32_t text_set_starttime;
int text_pos; int text_pos;
unsigned int text_pass; unsigned int text_pass;
unsigned int textpixel; unsigned int textpixel;
int disp_brightness;
bool disp_show; bool disp_show;
void storeDisplaySet(); // matrix control
bool loadDisplaySet();
void disp_scroll_text();
void disp_switch_text();
void disp_start_set();
void disp_init(); void disp_init();
void show_matrix(const char *text, int pos, uint16_t color); void disp_start_set();
String get_paramstring_from_struct(String name); void disp_scroll_text();
void set_param_to_struct(String name, String value); void show_matrix(const char *text, int pos, const char *color);
String getset_param_at_struct(String name, String value, bool set); uint16_t colorFromHex(String hex);
// storage structs
typedef struct text_set_t
{
char text[MaximumTextLength];
bool active;
uint16_t runtime;
char color[7];
text_align_t alignment;
bool scroll;
int scrollSpeed;
uint16_t scrollCount;
} text_set_t;
typedef struct sets_t
{
text_set_t sets[MaximumTextSets];
char valid[3];
} sets_t;
// storage variables
sets_t text_sets;
// storage control
GetSetTextSetParameterExitCode getSetTextSetParameter(int index, DisplayTextSetParameter parameter, String *value, bool set = false);
void storeTextSets();
bool loadTextSets();
}; };
void updateDisplayGlobal(void*); // function for updater task on core 0
void updateDisplayGlobal(void *);
extern LedDisplayController *ledDisplayControllerGlobal; extern LedDisplayController *ledDisplayControllerGlobal;
#endif // LED_DISPLAY_CONTROLLER #endif // LED_DISPLAY_CONTROLLER

View file

@ -6,22 +6,39 @@
#include "BluetoothLeUartServer.h" #include "BluetoothLeUartServer.h"
#include "LedDisplayController.h" #include "LedDisplayController.h"
class OmobiLedDisplay : protected BluetoothLeUartServerCallbacks { class OmobiLedDisplay : protected BluetoothLeUartServerCallbacks
{
public: public:
explicit OmobiLedDisplay(String deviceName, const byte ledPin); explicit OmobiLedDisplay(String deviceName, Adafruit_NeoMatrix *ledDisplayMatrix);
// befriend for callbacks // befriend for callbacks
friend class BluetoothLeUartServer; friend class BluetoothLeUartServer;
protected: protected:
// calbacks for BluetoothLeUartServerCallbacks // calbacks for BluetoothLeUartServerCallbacks
void onDeviceConnectedChanged(bool deviceConnected) override; void onDeviceConnectedChanged(bool deviceConnected) override;
void onDataReceived(String data) override; void onDataReceived(String data) override;
private: private:
LedDisplayController* ledDisplayController; enum OmobiDisplayCommand
BluetoothLeUartServer * bleServer; {
GetAllTextSetsCommand = 10,
GetTextSetParameterCommand = 11,
GetDisplayBrightnessCommand = 12,
SetTextSetParameterCommand = 20,
SetDisplayBrightnessCommand = 21
};
enum OmobiDisplayStatusCode
{
Success = 200,
InternalError = 500,
DisplayControllerError = 501
};
LedDisplayController *ledDisplayController;
BluetoothLeUartServer *bleServer;
}; };
#endif // OMOBI_LED_DISPLAY #endif // OMOBI_LED_DISPLAY

View file

@ -57,7 +57,8 @@ void BluetoothLeUartServer::sendData(String data)
void BluetoothLeUartServer::onConnect(BLEServer *pServer) void BluetoothLeUartServer::onConnect(BLEServer *pServer)
{ {
this->deviceConnected = true; this->deviceConnected = true;
if (this->callbacks != nullptr) { if (this->callbacks != nullptr)
{
this->callbacks->onDeviceConnectedChanged(this->deviceConnected); this->callbacks->onDeviceConnectedChanged(this->deviceConnected);
} }
} }

View file

@ -2,15 +2,12 @@
LedDisplayController *ledDisplayControllerGlobal = nullptr; LedDisplayController *ledDisplayControllerGlobal = nullptr;
LedDisplayController::LedDisplayController(const byte pin) LedDisplayController::LedDisplayController(Adafruit_NeoMatrix *matrix)
{ {
ledDisplayControllerGlobal = this; ledDisplayControllerGlobal = this;
this->loadTextSets();
this->matrix = new Adafruit_NeoMatrix(8, 8, 1, 1, pin, this->matrix = matrix;
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS + NEO_TILE_PROGRESSIVE +
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_TILE_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);
this->matrix->begin(); this->matrix->begin();
this->matrix->setTextWrap(false); this->matrix->setTextWrap(false);
this->matrix->setBrightness(40); this->matrix->setBrightness(40);
@ -19,6 +16,7 @@ LedDisplayController::LedDisplayController(const byte pin)
text_set_starttime = 0; text_set_starttime = 0;
text_pass = 0; text_pass = 0;
textpixel = 0; textpixel = 0;
disp_brightness = 5;
disp_show = false; disp_show = false;
this->disp_init(); this->disp_init();
@ -27,7 +25,11 @@ LedDisplayController::LedDisplayController(const byte pin)
xTaskCreatePinnedToCore(updateDisplayGlobal, "DisplayUpdateTask", 10000, NULL, 1, &displayUpdateTask, 0); xTaskCreatePinnedToCore(updateDisplayGlobal, "DisplayUpdateTask", 10000, NULL, 1, &displayUpdateTask, 0);
} }
void LedDisplayController::disp_update() // --------------------
// - Public functions -
// --------------------
void LedDisplayController::loop()
{ {
if (this->disp_show) if (this->disp_show)
{ {
@ -36,7 +38,7 @@ void LedDisplayController::disp_update()
{ {
if (text_sets.sets[text_curr_nr].text != '\0') if (text_sets.sets[text_curr_nr].text != '\0')
{ {
if (text_sets.sets[text_curr_nr].text_scroll) if (text_sets.sets[text_curr_nr].scroll)
{ {
disp_scroll_text(); disp_scroll_text();
} }
@ -45,6 +47,39 @@ void LedDisplayController::disp_update()
} }
} }
String LedDisplayController::getTextSetParameter(int index, DisplayTextSetParameter parameter)
{
if (index < 0 || index > this->MaximumTextSets || parameter < 0 || parameter >= DisplayTextSetParameterCount)
return "";
String value = "";
this->getSetTextSetParameter(index, parameter, &value);
return value;
}
LedDisplayController::GetSetTextSetParameterExitCode LedDisplayController::setTextSetParameter(int index, DisplayTextSetParameter parameter, String value)
{
return this->getSetTextSetParameter(index, parameter, &value, true);
}
int LedDisplayController::getBrightness()
{
return this->disp_brightness;
}
bool LedDisplayController::setBrightness(int brightness)
{
if (brightness < 0 || brightness > 10)
return false;
this->disp_brightness = brightness;
return true;
}
// ------------------
// - Matrix control -
// ------------------
void LedDisplayController::disp_init() void LedDisplayController::disp_init()
{ {
text_curr_nr = 0; text_curr_nr = 0;
@ -54,6 +89,50 @@ void LedDisplayController::disp_init()
disp_show = true; disp_show = true;
} }
void LedDisplayController::disp_start_set()
{
if ((0 == text_set_starttime) ||
(text_sets.sets[text_curr_nr].text == '\0') ||
text_sets.sets[text_curr_nr].active == false ||
((text_sets.sets[text_curr_nr].scroll == false) && (text_sets.sets[text_curr_nr].runtime > 0) && ((millis() - text_set_starttime) >= text_sets.sets[text_curr_nr].runtime)) ||
((text_sets.sets[text_curr_nr].scroll == true) && (text_sets.sets[text_curr_nr].scrollCount > 0) && (text_pass >= text_sets.sets[text_curr_nr].scrollCount)) ||
(((text_sets.sets[text_curr_nr].scrollCount == 0) || text_sets.sets[text_curr_nr].scroll == false) && (text_sets.sets[text_curr_nr].runtime == 0) && ((millis() - text_set_starttime) >= 10000)))
{
//Serial.printf("[%lu] Meet start set condition. Curr set is %d. \n", millis(), text_curr_nr);
if (0 < text_set_starttime || text_sets.sets[text_curr_nr].text == '\0' || text_sets.sets[text_curr_nr].active == false)
text_curr_nr++;
if (text_curr_nr == MaximumTextSets)
text_curr_nr = 0;
text_pass = 0;
if (text_sets.sets[text_curr_nr].text != '\0' && text_sets.sets[text_curr_nr].active == true)
{
//Serial.printf("[%lu] Set %d. Runtime %d. Text:'%s'\n", millis(), text_curr_nr, text_sets.sets[text_curr_nr].runtime, text_sets.sets[text_curr_nr].text);
this->matrix->fillScreen(0);
textpixel = 6 * strlen(text_sets.sets[text_curr_nr].text);
switch (text_sets.sets[text_curr_nr].alignment)
{
case AlignLeft:
text_pos = 0;
break;
case AlignRight:
text_pos = this->matrix->width();
break;
case AlignCenter:
text_pos = this->matrix->width() - textpixel;
text_pos = text_pos / 2;
break;
}
show_matrix(text_sets.sets[text_curr_nr].text, text_pos, text_sets.sets[text_curr_nr].color);
text_set_starttime = millis();
}
}
else
{
//Serial.printf("[%lu] Don't meet start set condition. Text is: %s. Active is: %d\n", millis(), text_sets.sets[text_curr_nr].text, text_sets.sets[text_curr_nr].active);
}
}
void LedDisplayController::disp_scroll_text() void LedDisplayController::disp_scroll_text()
{ {
this->matrix->fillScreen(0); this->matrix->fillScreen(0);
@ -63,58 +142,15 @@ void LedDisplayController::disp_scroll_text()
{ {
text_pos = this->matrix->width(); text_pos = this->matrix->width();
text_pass++; text_pass++;
Serial.printf("Pass[%d] - set nr %d, Text: '%s' \n", text_pass, text_curr_nr, text_sets.sets[text_curr_nr].text); //Serial.printf("Pass[%d] - set nr %d, Text: '%s' \n", text_pass, text_curr_nr, text_sets.sets[text_curr_nr].text);
} }
delay(100); delay(100);
} }
void LedDisplayController::disp_start_set() void LedDisplayController::show_matrix(const char *text, int pos, const char *color)
{ {
if ((0 == text_set_starttime) || //Serial.printf("TEXT: %s (pos=%d, color=%d)\n", text, pos, this->colorFromHex(String(color)));
(text_sets.sets[text_curr_nr].text == '\0') || this->matrix->setTextColor(this->colorFromHex(String(color)));
text_sets.sets[text_curr_nr].active == false ||
((text_sets.sets[text_curr_nr].text_scroll == false) && (text_sets.sets[text_curr_nr].time_ms > 0) && ((millis() - text_set_starttime) >= text_sets.sets[text_curr_nr].time_ms)) ||
((text_sets.sets[text_curr_nr].text_scroll == true) && (text_sets.sets[text_curr_nr].text_scroll_pass > 0) && (text_pass >= text_sets.sets[text_curr_nr].text_scroll_pass)) ||
(((text_sets.sets[text_curr_nr].text_scroll_pass == 0) || text_sets.sets[text_curr_nr].text_scroll == false) && (text_sets.sets[text_curr_nr].time_ms == 0) && ((millis() - text_set_starttime) >= 10000)))
{
//Serial.printf("[%lu] Meet start set condition. Curr set is %d. \n", millis(), text_curr_nr);
if (0 < text_set_starttime || text_sets.sets[text_curr_nr].text == '\0' || text_sets.sets[text_curr_nr].active == false)
text_curr_nr++;
if (text_curr_nr == text_nr_sets)
text_curr_nr = 0;
text_pass = 0;
if (text_sets.sets[text_curr_nr].text != '\0' && text_sets.sets[text_curr_nr].active == true)
{
Serial.printf("[%lu] Set %d. Runtime %d. Text:'%s'\n", millis(), text_curr_nr, text_sets.sets[text_curr_nr].time_ms, text_sets.sets[text_curr_nr].text);
this->matrix->fillScreen(0);
textpixel = 6 * strlen(text_sets.sets[text_curr_nr].text);
switch (text_sets.sets[text_curr_nr].align)
{
case TEXTLEFT:
text_pos = 0;
break;
case TEXTRIGHT:
text_pos = this->matrix->width();
break;
case TEXTCENTER:
text_pos = this->matrix->width() - textpixel;
text_pos = text_pos / 2;
break;
}
show_matrix(text_sets.sets[text_curr_nr].text, text_pos, text_sets.sets[text_curr_nr].color);
text_set_starttime = millis();
}
}
else {
//Serial.printf("[%lu] Don't meet start set condition. Text is: %s. Active is: %d\n", millis(), text_sets.sets[text_curr_nr].text, text_sets.sets[text_curr_nr].active);
}
}
void LedDisplayController::show_matrix(const char *text, int pos, uint16_t color)
{
Serial.printf("TEXT: %s (pos=%d, color=%d)\n", text, pos, color);
this->matrix->setTextColor(color);
this->matrix->setCursor(pos, 0); this->matrix->setCursor(pos, 0);
this->matrix->print(text); this->matrix->print(text);
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
@ -122,10 +158,135 @@ void LedDisplayController::show_matrix(const char *text, int pos, uint16_t color
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
void LedDisplayController::storeDisplaySet() uint16_t LedDisplayController::colorFromHex(String hex)
{
hex.replace("#", "");
long number = (long)strtol(&hex[0], NULL, 16);
int r = number >> 16;
int g = number >> 8 & 0xFF;
int b = number & 0xFF;
//Serial.println("Color is: " + hex + " rgb are: r: " + r + " b: " + b + " g: " + g);
return this->matrix->Color(r, g, b);
}
// -------------------
// - Storage control -
// -------------------
LedDisplayController::GetSetTextSetParameterExitCode LedDisplayController::getSetTextSetParameter(int index, DisplayTextSetParameter parameter, String *value, bool set)
{
if (parameter < 0 || parameter >= DisplayTextSetParameterCount)
return InvalidParameterError;
else if (index < 0 || index >= this->MaximumTextSets)
return IndexOutOfRangeError;
else if (value == nullptr)
return ValueIsNullptrError;
else if (strcmp(this->text_sets.valid, "OK") != 0)
return InternalError;
text_set_t *currentTextSet = &this->text_sets.sets[index];
String returnValue = "";
switch (parameter)
{
case TextParameter:
if (set)
strncpy(currentTextSet->text, value->c_str(), sizeof(currentTextSet->text));
else
returnValue = String(currentTextSet->text);
break;
case ActiveParameter:
if (set)
currentTextSet->active = *value == "true";
else
returnValue = currentTextSet->active ? "true" : "false";
break;
case RuntimeParameter:
if (set)
currentTextSet->runtime = value->toInt();
else
returnValue = String(currentTextSet->runtime);
break;
case ColorParameter:
if (set)
strncpy(currentTextSet->color, value->c_str(), sizeof(currentTextSet->color));
else
returnValue = String(currentTextSet->color);
break;
case AlignmentParameter:
if (set)
{
if (value->toInt() < 0 || value->toInt() > AlignRight)
return ValueOutOfRangeError;
currentTextSet->alignment = text_align_t(value->toInt());
}
else
returnValue = String(currentTextSet->alignment);
break;
case ScrollParameter:
if (set)
currentTextSet->scroll = *value == "true";
else
returnValue = currentTextSet->scroll ? "true" : "false";
break;
case ScrollSpeedParameter:
if (set)
{
if (value->toInt() < 0 || value->toInt() > 10)
return ValueOutOfRangeError;
currentTextSet->scrollSpeed = value->toInt();
}
else
returnValue = String(currentTextSet->scrollSpeed);
break;
case ScrollCountParameter:
if (set)
{
if (value->toInt() < 0)
return ValueOutOfRangeError;
currentTextSet->scrollCount = value->toInt();
}
else
returnValue = String(currentTextSet->scrollCount);
break;
case IndexParameter:
if (set)
return ParameterNotWritableError;
else
returnValue = String(index);
break;
default:
break;
}
if (set)
{
this->storeTextSets();
return Success;
}
else
{
*value = returnValue;
return Success;
}
}
void LedDisplayController::storeTextSets()
{ {
// write conf to EEPROM // write conf to EEPROM
EEPROM.begin(DISP_STRUCT_SIZE); EEPROM.begin(sizeof(sets_t));
//for (size_t i = 0 ; i < DISP_STRUCT_SIZE ; i++) //for (size_t i = 0 ; i < DISP_STRUCT_SIZE ; i++)
//{ //{
// EEPROM.write(i, 0); // EEPROM.write(i, 0);
@ -136,12 +297,12 @@ void LedDisplayController::storeDisplaySet()
EEPROM.end(); EEPROM.end();
} }
bool LedDisplayController::loadDisplaySet() bool LedDisplayController::loadTextSets()
{ {
bool rc = false; bool rc = false;
sets_t buf = {}; sets_t buf = {};
// read conf from EEPROM // read conf from EEPROM
EEPROM.begin(DISP_STRUCT_SIZE); EEPROM.begin(sizeof(sets_t));
EEPROM.get(0, buf); EEPROM.get(0, buf);
EEPROM.end(); EEPROM.end();
if (strcmp(buf.valid, "OK") == 0) if (strcmp(buf.valid, "OK") == 0)
@ -151,108 +312,44 @@ bool LedDisplayController::loadDisplaySet()
} }
else else
{ {
memset(&text_sets, 0, sizeof(text_sets)); // There was an error reading the sets -> rebuild with default values!
sets_t defaultTextSets;
strncpy(defaultTextSets.valid, "OK", sizeof(defaultTextSets.valid));
for (int i = 0; i < this->MaximumTextSets; i++)
{
text_set_t defaultTextSet{
"",
false,
0,
"",
AlignCenter,
false,
0,
0};
defaultTextSets.sets[i] = defaultTextSet;
}
this->text_sets = defaultTextSets;
this->storeTextSets();
} }
return rc; return rc;
} }
String LedDisplayController::get_paramstring_from_struct(String name) // ----------
{ // - Extern -
return (getset_param_at_struct(name, "", false)); // ----------
}
void LedDisplayController::set_param_to_struct(String name, String value)
{
getset_param_at_struct(name, value, true);
}
String LedDisplayController::getset_param_at_struct(String name, String value, bool set)
{
String name_value = "";
int name_setnr_index = name.lastIndexOf("_");
int name_setnr = -1;
int name_index = -1;
String name_name = "unknown";
if (name_setnr_index > 0)
{
name_setnr = name.substring(name_setnr_index + 1).toInt();
name_name = name.substring(0, name_setnr_index + 1);
for (int pnr = 0; pnr < nr_param_names; pnr++)
{
if (name_name == set_param_name[pnr])
{
name_index = pnr;
break;
}
}
//Serial.printf("Param: (name=%s,set=%d, index=%d) %s = %s \n", name_name.c_str(), name_setnr, name_index, name.c_str(), value.c_str());
if (name_index != -1 && name_setnr != -1 && name_name != "unknown")
{
name_value += name_name + String(name_setnr) + "=";
switch (name_index)
{
case PCOLOR:
//if (true == set)
//text_sets.sets[name_setnr].color = (unint16_t)value.toInt();
name_value += String(text_sets.sets[name_setnr].color);
break;
case PTEXT:
if (true == set)
snprintf((char *)text_sets.sets[name_setnr].text, MAX_TXT_LENGTH, value.c_str());
name_value += String(text_sets.sets[name_setnr].text);
break;
case PTIME:
if (true == set)
text_sets.sets[name_setnr].time_ms = value.toInt() * 1000;
name_value += String(text_sets.sets[name_setnr].time_ms / 1000);
break;
case PSCROLL:
if (true == set)
text_sets.sets[name_setnr].text_scroll = (value == "true") ? true : false;
name_value += String(text_sets.sets[name_setnr].text_scroll);
break;
case PACTIVE:
if (true == set)
text_sets.sets[name_setnr].active = (value == "true") ? true : false;
name_value += String(text_sets.sets[name_setnr].active);
break;
case PALIGN:
if (true == set)
text_sets.sets[name_setnr].align = (text_align_t)value.toInt();
name_value += String(text_sets.sets[name_setnr].align);
break;
case PSCROLL_RUNS:
if (true == set)
text_sets.sets[name_setnr].text_scroll_pass = value.toInt();
name_value += String(text_sets.sets[name_setnr].text_scroll_pass);
break;
}
//Serial.printf("get/set %s\n", name_value.c_str());
}
}
return (name_value);
}
void LedDisplayController::setTexts(sets_t texts) {
this->text_sets = texts;
this->storeDisplaySet();
}
LedDisplayController::sets_t LedDisplayController::getTexts() {
return this->text_sets;
}
uint16_t LedDisplayController::Color(uint8_t r, uint8_t g, uint8_t b) {
return this->matrix->Color(r,g,b);
}
void updateDisplayGlobal(void *) void updateDisplayGlobal(void *)
{ {
for(;;) { for (;;)
{
esp_task_wdt_reset(); esp_task_wdt_reset();
delay(1); delay(1);
ledDisplayControllerGlobal->disp_update(); ledDisplayControllerGlobal->loop();
} }
} }

View file

@ -1,17 +1,12 @@
#include "OmobiLedDisplay.h" #include "OmobiLedDisplay.h"
OmobiLedDisplay::OmobiLedDisplay(String deviceName, const byte ledPin) OmobiLedDisplay::OmobiLedDisplay(String deviceName, Adafruit_NeoMatrix *ledDisplayMatrix)
{ {
this->ledDisplayController = new LedDisplayController(ledPin); // init led display controller
this->ledDisplayController = new LedDisplayController(ledDisplayMatrix);
this->ledDisplayController->setTexts(LedDisplayController::sets_t{ this->ledDisplayController->setTextSetParameter(0, LedDisplayController::ActiveParameter, "true");
{// TEXT , SHOWTIME, COLOR, ALIGNMENT, SCROLL, SCROLLNR, ACTIVE
{"itsblue", 5000, ledDisplayController->Color(0, 0, 255), LedDisplayController::TEXTCENTER, false, 1, true},
{"", 0, ledDisplayController->Color(0, 0, 255), LedDisplayController::TEXTCENTER, false, 4, false}
},
"OK"});
// init ble server
this->bleServer = new BluetoothLeUartServer(deviceName, "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e"); this->bleServer = new BluetoothLeUartServer(deviceName, "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e");
this->bleServer->setCallbacks(this); this->bleServer->setCallbacks(this);
} }
@ -20,121 +15,109 @@ void OmobiLedDisplay::onDeviceConnectedChanged(bool deviceConnected)
{ {
if (deviceConnected) if (deviceConnected)
Serial.println("Device connected"); Serial.println("Device connected");
else
Serial.println("Device disconnected");
} }
void OmobiLedDisplay::onDataReceived(String data) void OmobiLedDisplay::onDataReceived(String dataString)
{ {
if (data.startsWith("GET_TEXTS")) // process JSON
const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
DynamicJsonDocument requestDoc(capacity);
DeserializationError error = deserializeJson(requestDoc, dataString);
// return on error
if(error != DeserializationError::Ok)
return;
// get reuqest data
OmobiDisplayCommand requestHeader = requestDoc["header"];
JsonObject requestData = requestDoc["data"];
// prepare reply data
DynamicJsonDocument replyDoc(capacity);
replyDoc["header"] = requestHeader;
OmobiDisplayStatusCode replyStatus = InternalError;
JsonObject replyData = replyDoc.createNestedObject("data");
switch (requestHeader)
{ {
const size_t capacity = JSON_ARRAY_SIZE(LedDisplayController::text_nr_sets) + LedDisplayController::text_nr_sets * (JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(8)); case GetAllTextSetsCommand:
{
// cycle through all text sets
for (int textSetIndex = 0; textSetIndex < LedDisplayController::MaximumTextSets; textSetIndex++)
{
if (this->ledDisplayController->getTextSetParameter(textSetIndex, LedDisplayController::TextParameter) == "")
continue;
//Serial.println("Adding index " + String(textSetIndex) + " with text: " + this->ledDisplayController->getTextSetParameter(textSetIndex, LedDisplayController::TextParameter));
// if a set isn't empty, go through all parameters
for (int textSetParameter = 0; textSetParameter < LedDisplayController::DisplayTextSetParameterCount; textSetParameter++)
{
// send each parameter to the client
const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
DynamicJsonDocument doc(capacity); DynamicJsonDocument doc(capacity);
for (int i = 0; i < LedDisplayController::text_nr_sets; i++) doc["header"] = GetTextSetParameterCommand;
{
LedDisplayController::text_set_t textSet = this->ledDisplayController->getTexts().sets[i];
JsonObject doc_0 = doc.createNestedObject();
doc_0["active"] = textSet.active;
doc_0["alignment"] = textSet.align;
JsonObject doc_0_color = doc_0.createNestedObject("color"); JsonObject data = doc.createNestedObject("data");
doc_0_color["r"] = 0; data["index"] = textSetIndex;
doc_0_color["g"] = 0; data["parameter"] = textSetParameter;
doc_0_color["b"] = 0; data["value"] = this->ledDisplayController->getTextSetParameter(
textSetIndex,
doc_0["runtime"] = textSet.time_ms; LedDisplayController::DisplayTextSetParameter(textSetParameter));
doc_0["scroll"] = textSet.text_scroll;
doc_0["scrollCount"] = textSet.text_scroll_pass;
doc_0["scrollSpeed"] = 5;
doc_0["text"] = textSet.text;
}
String json; String json;
serializeJson(doc, json); serializeJson(doc, json);
this->bleServer->sendData("GET_TEXTS:" + json); this->bleServer->sendData(json);
}
} }
else if (data.startsWith("SET_TEXTS:"))
{
const size_t capacity = JSON_ARRAY_SIZE(LedDisplayController::text_nr_sets) + LedDisplayController::text_nr_sets * JSON_OBJECT_SIZE(8) + 270;
DynamicJsonDocument doc(capacity);
data.replace("SET_TEXTS:", ""); replyStatus = Success;
Serial.println("Got new SET TEXT:" + data); replyData["maximumTextSets"] = LedDisplayController::MaximumTextSets;
// TODO: handle Error! replyData["maximumTextLength"] = LedDisplayController::MaximumTextLength;
DeserializationError err = deserializeJson(doc, data);
Serial.println("deserialization result: " + String(err.c_str()));
if(err != DeserializationError::Ok)
return;
JsonArray textsArray = doc.as<JsonArray>();
LedDisplayController::sets_t textSets;
strncpy(textSets.valid, "OK", sizeof(textSets.valid));
for (int i = 0; i < textsArray.size(); i++)
{
Serial.println(" | Processing index " + String(i));
if (i >= LedDisplayController::text_nr_sets)
break; break;
}
JsonObject textObject = textsArray[i].as<JsonObject>(); case GetDisplayBrightnessCommand:
{
if( replyData["displayBrightness"] = this->ledDisplayController->getBrightness();
!textObject.containsKey("text") || replyStatus = Success;
!textObject.containsKey("runtime") || break;
//!textObject.containsKey("color") ||
!textObject.containsKey("scroll") ||
!textObject.containsKey("scrollCount") ||
!textObject.containsKey("active") ||
!textObject.containsKey("alignment")
)
continue;
LedDisplayController::text_set_t textSet;
const char* text = textObject["text"];
strncpy(textSet.text, text, sizeof(textSet.text));
uint16_t runtime = textObject["runtime"];
textSet.time_ms = runtime;
//JsonObject colorObject = textObject["color"].as<JsonObject>();
//uint16_t color = this->ledDisplayController->Color(colorObject["r"], colorObject["color"]["g"], colorObject["color"]["b"]);
//textSet.color = color;
bool scroll = textObject["scroll"];
textSet.text_scroll = scroll;
uint16_t scrollCount = textObject["scrollCount"];
textSet.text_scroll_pass = scrollCount;
bool active = textObject["active"];
textSet.active = active;
int alignment = textObject["alignment"];
textSet.align = LedDisplayController::text_align_t(alignment);
Serial.println(
" | Got set: text: " + String(textSet.text) +
" time: " + String(textSet.time_ms) +
" color: " + String(textSet.color) +
" scroll: " + String(textSet.text_scroll) +
" scrollCount: " + String(textSet.text_scroll_pass) +
" active: " + String(textSet.active)
);
textSets.sets[i] = textSet;
} }
this->ledDisplayController->setTexts(textSets); case SetTextSetParameterCommand:
{
int index = requestData["index"];
int parameter = requestData["parameter"];
String value = requestData["value"];
this->bleServer->sendData("SET_TEXTS:OK"); LedDisplayController::GetSetTextSetParameterExitCode res = this->ledDisplayController->setTextSetParameter(index, LedDisplayController::DisplayTextSetParameter(parameter), value);
if (res == LedDisplayController::Success)
replyStatus = Success;
else
{
replyStatus = DisplayControllerError;
replyData["displayControllerError"] = res;
} }
else if (data.startsWith("GET_BRIGHTNESS"))
this->bleServer->sendData("GET_BRIGHTNESS:5"); break;
else if (data.startsWith("SET_BRIGHTNESS:")) }
this->bleServer->sendData("SET_BRIGHTNESS:OK"); case SetDisplayBrightnessCommand:
{
this->ledDisplayController->setBrightness(requestData["displayBrightness"]);
replyStatus = Success;
break;
}
default:
break;
}
// reply to the client
replyDoc["status"] = replyStatus;
String json;
serializeJson(replyDoc, json);
this->bleServer->sendData(json);
} }

View file

@ -1,33 +1,31 @@
#include <Arduino.h> #include <Arduino.h>
//#include "BluetoothLeUartServer.h"
#include "OmobiLedDisplay.h" #include "OmobiLedDisplay.h"
#define PIN 4 #define PIN 4
OmobiLedDisplay* display; OmobiLedDisplay *display;
class MyCallbacks : public BluetoothLeUartServerCallbacks {
virtual void onDeviceConnectedChanged(bool deviceConnected) {
Serial.println("Device connected changed");
};
virtual void onDataReceived(String data) {
Serial.println("Got some data: " + data);
};
};
//BluetoothLeUartServer* server;
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.printf("Los\n"); Serial.printf("Los\n");
display = new OmobiLedDisplay("OmobiLedDisplay1", PIN); Adafruit_NeoMatrix *displayMatrix = new Adafruit_NeoMatrix(
//server = new BluetoothLeUartServer("OmobiLedDisplay1", "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e"); 8,
//server->setCallbacks(new MyCallbacks()); 8,
1,
1,
PIN,
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS + NEO_TILE_PROGRESSIVE +
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_TILE_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);
// create our display
display = new OmobiLedDisplay("OmobiLedDisplay1", displayMatrix);
} }
void loop() void loop()
{ {
// nothing to do in loop
delay(1000); delay(1000);
} }