diff --git a/G29Mount/.gitignore b/G29Mount/.gitignore new file mode 100644 index 0000000..2b6c5bc --- /dev/null +++ b/G29Mount/.gitignore @@ -0,0 +1,2 @@ +*.stl +*.FCStd1 diff --git a/G29Mount/g29Mount.FCStd b/G29Mount/g29Mount.FCStd new file mode 100644 index 0000000..20a5064 Binary files /dev/null and b/G29Mount/g29Mount.FCStd differ diff --git a/lib/cursesAtHome/src/UIBar.cpp b/lib/cursesAtHome/src/UIBar.cpp new file mode 100644 index 0000000..1c3032d --- /dev/null +++ b/lib/cursesAtHome/src/UIBar.cpp @@ -0,0 +1,103 @@ +#include "UIBar.h" +#include "UIDrawing.h" + +UIBar::UIBar(Arduino_GFX *d, UIDimensions dims, UIDecorations *decor, + char *title) + : UIElement(d, dims, decor, title) {} + +void UIBar::Update(char* v) { + unsigned long time = millis(); + if ((time - this->lastUpdate) <= this->refreshRate) { + return; + } + + // Conver the string to an integer + uint32_t newVal = atoi(v); + + if (this->value == newVal) { + // If the value hasn't changed we do not need to re-render + return; + } + + this->DrawBar(&this->value, &newVal); + this->value = newVal; +} + +void UIBar::DrawBar(uint32_t *oldValue, uint32_t *newValue) { + // We can help identifying cur RPM visually by using different + // colors on the bar, for example, at a given distance of the ideal shift + // we can change the color gradually + + // If the new value is larger than the old one + // we just paint a new rectangle + // If the new value is smaller than the old one + // we have to delete a chunk of the old rectangle + int16_t startX = 0; + int16_t len = 0; + uint16_t colour = WHITE; + + if (*newValue > *oldValue) { // Increment the bar + int32_t newV = + (*newValue * (uint32_t)(this->dims.width - 4)) / (this->range * 1000); + int32_t oldV = + (this->value * (uint32_t)(this->dims.width - 4)) / (this->range * 1000); + + startX = oldV; + len = newV - oldV; + + } else { // Decrement the bar + int32_t newV = + (*newValue * (uint32_t)(this->dims.width - 4)) / (this->range * 1000); + int32_t oldV = + (this->value * (uint32_t)(this->dims.width - 4)) / (this->range * 1000); + + startX = newV; + len = oldV - newV; + colour = BLACK; + } + this->display->fillRect(this->dims.x + 2 + startX, this->dims.y + 2, len, + this->dims.height - 4, colour); + + this->value = *newValue; +} + +void UIBar::renderBlank() { + this->display->setCursor(this->dims.x, this->dims.y); + this->display->print("!RANGE"); +} + +void UIBar::Box() { + // If the range was not set, we cannot draw our ruler + if (this->range <= 0) { + this->renderBlank(); + return; + } + + // Bounding box for the bar + this->display->drawRect(this->dims.x, this->dims.y, this->dims.width, + this->dims.height, RED); + + // Now we can draw the scale (this should be easy to modify if needed) + // dividirs will be the range of the tach - 8 = 8000rpm + + // Calculate step size as a float for accurate positioning + float step = (float)this->dims.width / this->range; + for (int k = 0; k <= this->range; k++) { + uint16_t x = round(k * step) + this->dims.x; + + // To ensure it doesn't go beyond the bounding box + if (x >= this->dims.x + this->dims.width) { + x = this->dims.x + this->dims.width - 1; + } + + this->display->setTextColor(RED); + this->display->drawFastVLine(x, this->dims.y + this->dims.height, 7, RED); + this->display->setCursor(x, this->dims.y + this->dims.height + 7 + 2); + this->display->setTextColor(WHITE); + + char legend[5]; + sprintf(legend, "%d", k); + this->display->setTextSize(this->decor->textSize); + this->display->print(legend); + } +} diff --git a/lib/cursesAtHome/src/UIBar.h b/lib/cursesAtHome/src/UIBar.h new file mode 100644 index 0000000..cc17014 --- /dev/null +++ b/lib/cursesAtHome/src/UIBar.h @@ -0,0 +1,20 @@ +#ifndef _UI_BAR +#define _UI_BAR + +#include "UIComponent.h" + +struct UIBar : UIElement { + // This might be the only when where its more efficient to have the data + // as integers instead + uint32_t value = 0; // current tach value + uint8_t range = 0; // define the tach range, ie: 8 for 8000rpm + + UIBar(Arduino_GFX *d, UIDimensions dims, UIDecorations *decor, char *title); + + void Update(char *val); + void DrawBar(uint32_t *oldValue, uint32_t *newValue); + void renderBlank(); + void Box(); +}; + +#endif diff --git a/lib/cursesAtHome/src/UIString.cpp b/lib/cursesAtHome/src/UIString.cpp index 66c0198..e8f73e4 100644 --- a/lib/cursesAtHome/src/UIString.cpp +++ b/lib/cursesAtHome/src/UIString.cpp @@ -43,7 +43,6 @@ void UIString::Update(const char *v) { sprintf(oldVal, "%s", this->value); // Figure out the x0 and y0 for the text - replaceString(oldVal, newVal); // <- It crashes here somewhere - // + replaceString(oldVal, newVal); strncpy(this->value, v, this->bufferSize); } diff --git a/src/main.cpp b/src/main.cpp index c9ff651..48066cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,7 @@ Arduino_GFX *gfx = new Arduino_RGB_Display(TFT_HOR_RES, TFT_VER_RES, panel, 16); // UIelements DashUI *ui = new DashUI(); +UIDecorations *rpmBarDecor = new UIDecorations(); UIDecorations *rpmTextDecor = new UIDecorations(); UIDecorations *speedTextDecor = new UIDecorations(); UIDecorations *gearTextDecor = new UIDecorations(); @@ -59,6 +60,7 @@ UIDecorations *fuelConsumptionDecor = new UIDecorations(); UIDecorations *brakeBiasDecor = new UIDecorations(); UIDecorations *relativeDecor = new UIDecorations(); +UIBar rpmBar(gfx, UIDimensions(0, 0, 0, 0), rpmBarDecor, (char *)"Tach"); UIString rpmText(gfx, UIDimensions(0, 0, 0, 0), rpmTextDecor, (char *)"RPM"); UIString speedText(gfx, UIDimensions(0, 0, 0, 0), speedTextDecor, (char *)"Speed"); @@ -108,12 +110,27 @@ void setup() { relative->drawBox(); ui->relative = relative; + // Setup the rpmBar box + rpmBarDecor->textSize = 3; + rpmBar.dims.height = 50; + rpmBar.dims.width = 350; + rpmBar.horizontalCenter(); + rpmBar.range = 8; + rpmBar.refreshRate = 50; + ui->barTacho = &rpmBar; + ui->barTacho->Box(); + ui->barTacho->Update((char*)""); + // Setup the rpmText box rpmTextDecor->textSize = 7; rpmText.dims.height = calculateHeight(rpmTextDecor->titleSize, rpmTextDecor->textSize, 1); rpmText.dims.width = calculateWidth(rpmTextDecor->textSize, 5); rpmText.horizontalCenter(); + rpmText.placeBelow(&rpmBar); + rpmText.dims.y += 40; // We gotta fix how the bar declares its height instead + // of doing this here + rpmText.refreshRate = 100; ui->digiTacho = &rpmText; ui->digiTacho->drawBox(); ui->digiTacho->Update("-----"); @@ -123,7 +140,10 @@ void setup() { speedText.dims.height = calculateHeight(speedTextDecor->titleSize, speedTextDecor->textSize, 1); speedText.dims.width = calculateWidth(speedTextDecor->textSize, 4); + speedText.placeBelow(&rpmBar); speedText.placeRight(&rpmText); + speedText.dims.y += 40; // We gotta fix how the bar declares its height + // instead of doing this here ui->digiSpeedo = &speedText; ui->digiSpeedo->drawBox(); ui->digiSpeedo->Update("---"); @@ -133,8 +153,8 @@ void setup() { gearText.dims.height = calculateHeight(gearTextDecor->titleSize, gearTextDecor->textSize, 1); gearText.dims.width = calculateWidth(gearTextDecor->textSize, 2); - gearText.horizontalCenter(); gearText.dims.y = rpmText.dims.height + 5; + gearText.placeBelow(&rpmText); ui->digiGear = &gearText; ui->digiGear->drawBox(); ui->digiGear->Update("-"); diff --git a/src/ui.cpp b/src/ui.cpp index 810a9a4..6ab3abf 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1,11 +1,14 @@ #include "ui.h" +#include "HardwareSerial.h" #include "data.h" +#include DashUI::DashUI() {} void DashUI::Update(DataPacket *p) { - this->digiSpeedo->Update(p->speed); + this->barTacho->Update(p->rpm); this->digiTacho->Update(p->rpm); + this->digiSpeedo->Update(p->speed); this->digiGear->Update(p->gear); this->lapDelta->Update(p->DeltaToBestLap); this->bestLap->Update(p->bestLapTime); diff --git a/src/ui.h b/src/ui.h index 5985e27..ba984e8 100644 --- a/src/ui.h +++ b/src/ui.h @@ -4,9 +4,11 @@ #include "Arduino_GFX.h" #include "UIString.h" #include "UITable.h" +#include "UIBar.h" #include "data.h" struct DashUI { + UIBar *barTacho; UIString *digiTacho; UIString *digiSpeedo; UIString *digiGear;