LedDisplay/vscode/OmobiLEDdisplayBluetooth/src/LedDisplayController.cpp

355 lines
10 KiB
C++
Raw Normal View History

#include "LedDisplayController.h"
LedDisplayController *ledDisplayControllerGlobal = nullptr;
LedDisplayController::LedDisplayController(Adafruit_NeoMatrix *matrix)
{
ledDisplayControllerGlobal = this;
this->loadTextSets();
this->matrix = matrix;
this->matrix->begin();
this->matrix->setTextWrap(false);
this->matrix->setBrightness(40);
text_curr_nr = 0;
text_set_starttime = 0;
text_pass = 0;
textpixel = 0;
disp_brightness = 5;
disp_show = false;
this->disp_init();
// create updater task
xTaskCreatePinnedToCore(updateDisplayGlobal, "DisplayUpdateTask", 10000, NULL, 1, &displayUpdateTask, 0);
}
// --------------------
// - Public functions -
// --------------------
void LedDisplayController::loop()
{
if (this->disp_show)
{
disp_start_set();
if (true == text_sets.sets[text_curr_nr].active)
{
if (text_sets.sets[text_curr_nr].text != '\0')
{
if (text_sets.sets[text_curr_nr].scroll)
{
disp_scroll_text();
}
}
}
}
}
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()
{
text_curr_nr = 0;
text_set_starttime = 0;
text_pass = 0;
text_pos = this->matrix->width();
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()
{
this->matrix->fillScreen(0);
show_matrix(text_sets.sets[text_curr_nr].text, text_pos, text_sets.sets[text_curr_nr].color);
(int)text_pos--;
if (int(text_pos + textpixel) < 0)
{
text_pos = this->matrix->width();
text_pass++;
//Serial.printf("Pass[%d] - set nr %d, Text: '%s' \n", text_pass, text_curr_nr, text_sets.sets[text_curr_nr].text);
}
delay(100);
}
void LedDisplayController::show_matrix(const char *text, int pos, const char *color)
{
//Serial.printf("TEXT: %s (pos=%d, color=%d)\n", text, pos, this->colorFromHex(String(color)));
this->matrix->setTextColor(this->colorFromHex(String(color)));
this->matrix->setCursor(pos, 0);
this->matrix->print(text);
portDISABLE_INTERRUPTS();
this->matrix->show();
portENABLE_INTERRUPTS();
}
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
EEPROM.begin(sizeof(sets_t));
//for (size_t i = 0 ; i < DISP_STRUCT_SIZE ; i++)
//{
// EEPROM.write(i, 0);
//}
strncpy(text_sets.valid, "OK", sizeof(text_sets.valid));
EEPROM.put(0, text_sets);
EEPROM.commit();
EEPROM.end();
}
bool LedDisplayController::loadTextSets()
{
bool rc = false;
sets_t buf = {};
// read conf from EEPROM
EEPROM.begin(sizeof(sets_t));
EEPROM.get(0, buf);
EEPROM.end();
if (strcmp(buf.valid, "OK") == 0)
{
rc = true;
memcpy(&text_sets, &buf, sizeof(text_sets));
}
else
{
// 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;
}
// ----------
// - Extern -
// ----------
void updateDisplayGlobal(void *)
{
for (;;)
{
esp_task_wdt_reset();
delay(1);
ledDisplayControllerGlobal->loop();
}
}