ソースを参照

Release beta version 0.9

master
gituser 1週間前
コミット
4f395cc4cc
6個のファイルの変更194行の追加88行の削除
  1. 88
    35
      Display.cpp
  2. 12
    6
      Display.h
  3. 15
    7
      EchoLot.ino
  4. 76
    35
      EchoLotSetup.cpp
  5. 2
    4
      EchoLotSetup.h
  6. 1
    1
      sloeber.ino.cpp

+ 88
- 35
Display.cpp ファイルの表示

@@ -41,7 +41,6 @@
****************/
Display::Display() : tft(Adafruit_ST7735(CS, DC, RST)) { // @suppress("Abstract class cannot be instantiated")
starttime = 0;
configValue = 0.0;
configUnit = "m/s";
distance = 0;
environment = 1;
@@ -128,27 +127,13 @@ void Display::showInitialization(void) {
drawXCenteredText("EchoLoT", &titillium_web_regular16pt7b, 1, ST7735_CYAN, 36);
drawXCenteredText("designed by", &FreeSans9pt7b, 1, ST7735_WHITE, 64);
showBrand(16, 84);
delay(500);
delay(2000);

redrawFrame();
drawText("powered by", &FreeSans9pt7b, 1, ST7735_CYAN, 35, 30);
tft.fillRoundRect(46, 42, 68, 68, 7, ST7735_STM32BLUE);
drawBitmap(48, 44, 64, 64, epd_bitmap_stm32duino_logo_icon, ST7735_WHITE);

// tft.drawBitmap(5, 100, epd_bitmap_gear, 24, 24, ST7735_YELLOW);
// tft.drawBitmap(40, 100, epd_bitmap_Zzz_24, 24, 24, ST7735_CYAN);
// tft.drawBitmap(75, 100, epd_bitmap_Measure_25, 25, 25, ST7735_RED);
// tft.fillTriangle(75, 98, 80, 102, 75, 107, ST7735_RED);
// tft.fillTriangle(82, 98, 87, 102, 82, 107, ST7735_RED);
// tft.fillTriangle(89, 98, 94, 102, 89, 107, ST7735_RED);
// tft.fillTriangle(96, 98, 101, 102, 96, 107, ST7735_RED);
//
// tft.drawBitmap(110, 100, epd_bitmap_air, 24, 24, ST7735_CYAN);
// tft.drawBitmap(110, 100, epd_bitmap_water, 24, 24, ST7735_BLUE);
// tft.drawBitmap(110, 100, epd_bitmap_water_s, 24, 24, ST7735_BLUE);
// tft.drawBitmap(1, 160 - 32, thermometer_icon_32, 32, 32, 0xE71C);

delay(500);
delay(2000);
}

void Display::display(void) {
@@ -181,15 +166,18 @@ void Display::showFrame(Status status) {
}
}

void Display::setStatusValues(float airTemp, float waterTemp) {
void Display::setStatusValues(float airTemp, float waterTemp, float sonicSpeedAir, uint8_t saltPromilleWater) {
this->airTemp = airTemp;
this->waterTemp = waterTemp;
this->sonicSpeedAir = sonicSpeedAir;
this->saltPromilleWater = saltPromilleWater;
}

void Display::setEnvironment(int environment) {
if (this->environment != environment) {
this->environment = environment;
redrawEnvIcon();
redrawTempIcon();
}
}

@@ -200,6 +188,28 @@ void Display::setDistance(uint32_t distance) {
}
}

void Display::setConfigOption(String configOption) {
if (!this->configOption.equals(configOption)) {
this->configOption = configOption;
redrawConfigOption();
}
}

void Display::setConfigText(String configText) {
if (!this->configValue.equals(configText)) {
this->configValue = configText;
redrawConfigValue();
}
}

void Display::setConfigUnit(String configUnit) {
if (!this->configUnit.equals(configUnit)) {
this->configUnit = configUnit;
redrawConfigUnit();
}

}

/* ===== Private methods ===== */
void Display::drawBitmap(int x, int y, int w, int h, const uint8_t bitmap[], uint16_t col) {
tft.drawBitmap(x, y, bitmap, w, h, col);
@@ -215,14 +225,14 @@ void Display::redrawFrame() {
tft.drawRoundRect(1, 1, 158, 126, 8, ST7735_CYAN);
}

void Display::redrawGrid() {
void Display::redrawGrid(bool cfg) {
redrawFrame();
tft.drawLine(0, 31, 160, 31, ST7735_CYAN);
tft.drawLine(0, 32, 160, 32, ST7735_CYAN);
tft.drawLine(0, 89, 160, 89, ST7735_CYAN);
tft.drawLine(0, 90, 160, 90, ST7735_CYAN);
tft.drawLine(80, 90, 80, 128, ST7735_CYAN);
tft.drawLine(81, 90, 81, 128, ST7735_CYAN);
tft.drawLine(cfg ? 120 : 80, 90, cfg ? 120 : 80, 128, ST7735_CYAN);
tft.drawLine(cfg ? 121 : 81, 90, cfg ? 121 : 81, 128, ST7735_CYAN);
}

void Display::redrawIdleStatus() {
@@ -230,22 +240,26 @@ void Display::redrawIdleStatus() {
tft.drawBitmap(25, 4, epd_bitmap_Zzz_24, 24, 24, ST7735_CYAN);
drawText("OPERATIV", &titillium_web_semibold8pt7b, 1, ST7735_WHITE, 55, 21);

float temp = environment == 1 ? airTemp : waterTemp;
uint16_t col = temp <= 17.0 ? ST7735_WHITE : temp <= 24.0 ? ST7735_GREEN : ST7735_ORANGE;
uint16_t thH = temp <= 17.0 ? 0 : temp <= 24.0 ? 5 : 9;
tft.drawBitmap(0, 92, thermometer_icon_32, 32, 32, col);
tft.drawRect(15, 107 - thH, 2, thH, col);
drawText(String(temp, 1), &titillium_web_semibold8pt7b, 1, col, 35, 114);
drawCircle(72, 102, 2, col);
// float temp = environment == 1 ? airTemp : waterTemp;
// uint16_t col = temp <= 17.0 ? ST7735_WHITE : temp <= 24.0 ? ST7735_GREEN : ST7735_ORANGE;
// uint16_t thH = temp <= 17.0 ? 0 : temp <= 24.0 ? 5 : 9;
// tft.drawBitmap(0, 92, thermometer_icon_32, 32, 32, col);
// tft.drawRect(15, 107 - thH, 2, thH, col);
// drawRightAlignedText(String(temp, 1), &titillium_web_semibold8pt7b, 1, col, 96, 114);
// drawCircle(72, 104, 2, col);
redrawTempIcon();
redrawEnvIcon();
redrawDistance();
}

void Display::redrawConfigStatus() {
redrawGrid();
redrawGrid(true);
tft.drawBitmap(35, 4, epd_bitmap_gear, 24, 24, ST7735_YELLOW);
drawText("KONFIG.", &titillium_web_semibold8pt7b, 1, ST7735_WHITE, 65, 21);
drawText("KONFIG.", &titillium_web_semibold8pt7b, 1, ST7735_YELLOW, 65, 21);

redrawConfigValue();
redrawConfigOption();
redrawConfigUnit();
}

void Display::redrawEnvIcon() {
@@ -255,6 +269,17 @@ void Display::redrawEnvIcon() {
tft.drawBitmap(108, 97, environmentIcon, 24, 24, col);
}

void Display::redrawTempIcon() {
float temp = environment == 1 ? airTemp : waterTemp;
uint16_t col = temp <= 17.0 ? ST7735_WHITE : temp <= 24.0 ? ST7735_GREEN : ST7735_ORANGE;
uint16_t thH = temp <= 17.0 ? 0 : temp <= 24.0 ? 5 : 9;
tft.fillRect(4, 92, 75, 30, ST7735_BLACK);
tft.drawBitmap(0, 92, thermometer_icon_32, 32, 32, col);
tft.drawRect(15, 107 - thH, 2, thH, col);
drawRightAlignedText(String(temp, 1), &titillium_web_semibold8pt7b, 1, col, 96, 114);
drawCircle(72, 104, 2, col);
}

void Display::runMeasureAnimation(bool run) {
if (!this->doMeasureAnimation && run) {
this->starttime = millis();
@@ -301,16 +326,44 @@ void Display::runMeasureAnimation(bool run) {
}

void Display::redrawDistance() {
tft.fillRect(4, 34, 152, 56, ST7735_BLACK);
tft.fillRect(4, 34, 152, 54, ST7735_BLACK);
if (distance == 0) {
drawXCenteredText("- - -", &titillium_web_regular16pt7b, 1, ST7735_CYAN, 69);
drawXCenteredText("- - -", &titillium_web_regular16pt7b, 1, ST7735_WHITE, 69);
} else {
if (environment == 1) {
uint16_t dist_CM = distance / 10;
drawXCenteredText(String(dist_CM) + " cm", &titillium_web_regular16pt7b, 1, ST7735_CYAN, 69);
drawXCenteredText(String(dist_CM) + " cm", &titillium_web_regular16pt7b, 1, ST7735_WHITE, 69);
} else {
float dist_M = float(distance) / 1000;
drawXCenteredText(String(dist_M, 1) + " m", &titillium_web_regular16pt7b, 1, ST7735_CYAN, 69);
drawXCenteredText(String(dist_M, 1) + " m", &titillium_web_regular16pt7b, 1, ST7735_WHITE, 69);
}
}
}

void Display::redrawConfigValue() {
tft.fillRect(4, 34, 152, 54, ST7735_BLACK);
drawXCenteredText(configValue, &titillium_web_regular16pt7b, 1, ST7735_ORANGE, 69);
}

void Display::redrawConfigOption() {
tft.fillRect(4, 92, 116, 30, ST7735_BLACK);
drawText(configOption, &titillium_web_semibold8pt7b, 1, ST7735_WHITE, 6, 113);
}

void Display::redrawConfigUnit() {
int16_t x1, y1; // Top-left corner of text
uint16_t w, h; // Width and height
tft.getTextBounds(configUnit, 0, 0, &x1, &y1, &w, &h);

tft.fillRect(123, 92, 35, 30, ST7735_BLACK);
drawRightAlignedText(configUnit, &titillium_web_semibold8pt7b, 1, ST7735_WHITE, (37 - w) / 2 + 2, 113);
if (configUnit.equals(" C")) {
drawCircle(121 + ((37 - w) / 2), 105, 2, ST7735_WHITE);
} else if (configUnit.equals(" / ")) {
drawCircle(124 + ((37 - w) / 2), 105, 2, ST7735_WHITE);
drawCircle(124 + ((37 - w) / 2) + 10, 110, 2, ST7735_WHITE);
drawCircle(124 + ((37 - w) / 2) + 15, 110, 2, ST7735_WHITE);
}

}


+ 12
- 6
Display.h ファイルの表示

@@ -21,27 +21,31 @@
class Display {
private:
Adafruit_ST7735 tft; // @suppress("Abstract class cannot be instantiated")
String configText;
String configValue;
String configOption;
float configValue;
String configUnit;
bool refreshScreen;
bool doMeasureAnimation;
unsigned long starttime;
float airTemp;
float waterTemp;
float sonicSpeedAir;
uint8_t saltPromilleWater;
int environment;
uint16_t distance;

void drawBitmap(int x, int y, int w, int h, const uint8_t bitmap[], uint16_t col);
void drawRGBBitmap(int x, int y, int w, int h, const uint16_t bitmap[]);
void redrawFrame();
void redrawGrid();
void redrawGrid(bool cfg = false);
void redrawIdleStatus();
void redrawConfigStatus();
void redrawEnvIcon();
void redrawIdleIcon();
void redrawTempIcon();
void redrawDistance();
void redrawConfigValue();
void redrawConfigOption();
void redrawConfigUnit();

public:
Display();
@@ -56,11 +60,13 @@ class Display {
void drawRightAlignedText(String txt, const GFXfont *font, uint8_t s, uint16_t c, int16_t xOffset, int16_t y);
void drawText(String txt, const GFXfont *font, uint8_t s, uint16_t c, int16_t x, int16_t y);
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
void setStatusValues(float airTemp, float waterTemp);
void setStatusValues(float airTemp, float waterTemp, float sonicSpeedAir, uint8_t saltPromilleWater);
void setEnvironment(int environment);
void setDistance(uint32_t distance);
void runMeasureAnimation(bool run);

void setConfigOption(String configOption);
void setConfigText(String configText);
void setConfigUnit(String configUnit);
};

#endif /* DISPLAY_H_ */

+ 15
- 7
EchoLot.ino ファイルの表示

@@ -36,6 +36,8 @@ EchoLotSetup echoLotSetup(display);
void Initialize() {
display.showInitialization();
echoLotSetup.initialize();
echoLotSetup.drawInitScreen();
delay(2000);
}
void setup() {
@@ -73,15 +75,21 @@ void loop() {
rotaryControler.loop();
if (originStatus != CONFIGURATION) {
display.setRefreshScreen();
display.showFrame(actualStatus);
echoLotSetup.initialize();
}
if (rotaryControler.isSwitchPressed()) {
echoLotSetup.onRotaryControlerSwitch();
}
display.showFrame(actualStatus);
echoLotSetup.onRotaryControlerTurn(rotaryControler.getEncoderMove());
if (rotaryControler.isSwitchLongPressed()) {
Serial.println("RotaryEnc Long SwitchPressed");
delay(50);
// TODO: Save the edited config values
echoLotSetup.onRotaryControlerLongSwitch();
echoLotSetup.initialize();
SetActualStatus(IDLE);
}
@@ -104,13 +112,13 @@ void loop() {
SetActualStatus(CONFIGURATION);
}
environmentPostion = threePositionSwitch.getPosition();
display.setEnvironment(environmentPostion);
if (measureBtn.isPressing()) {
SetActualStatus(MEASURING);
}
environmentPostion = threePositionSwitch.getPosition();
display.setEnvironment(environmentPostion);
originStatus = IDLE;
delay(50);
break;
@@ -126,11 +134,11 @@ void loop() {
delayMicroseconds(20);
digitalWrite(trigPin, LOW);
//TODO: calculate real distanz according settings
uint32_t duration = pulseIn(echoPin, HIGH);
uint32_t distance = calculateDistance(duration);
display.setDistance(distance);
display.runMeasureAnimation(true);
delay(200);
} else {
display.setDistance(0);

+ 76
- 35
EchoLotSetup.cpp ファイルの表示

@@ -6,8 +6,8 @@
*/

#include "EchoLotSetup.h"
#include "fonts/titillium_web_regular16pt7b.h"
#include "fonts/FreeSans7pt7b.h"
//#include <Fonts/FreeSans9pt7b.h>

#define ADDR_AIR_TEMP 0 // WORD
#define ADDR_WATER_TEMP 2 // +2 WORDs
@@ -31,17 +31,19 @@ EchoLotSetup::EchoLotSetup(Display &display) : display(display) {
// Initialisierung
// --------------------------------------------------
void EchoLotSetup::initialize() {
EEPROM.init();
readFromEEPROM();
display.setStatusValues(airTemp, waterTemp);

display.clearDisplay();
display.showFrame(INITIALIZATION);
printValues();
delay(2000);
if (doInitialization) {
EEPROM.init();
readFromEEPROM();
configStepIndex = 0;

configStepIndex = 0;
doInitialization = false;
String stepTxt = ConfigStep[configStepIndex];
String unit = getCfgOptUnitForStepIndex(configStepIndex);
display.setStatusValues(airTemp, waterTemp, sonicSpeedAir, saltPromilleWater);
display.setConfigText(String(airTemp, 1));
display.setConfigOption(stepTxt);
display.setConfigUnit(unit);
doInitialization = false;
}
}

// --------------------------------------------------
@@ -49,40 +51,56 @@ void EchoLotSetup::initialize() {
// --------------------------------------------------
void EchoLotSetup::onRotaryControlerSwitch() {
configStepIndex++;
if (configStepIndex >= 5) {
if (configStepIndex > 3) {
configStepIndex = 0;
}

display.setConfigText(getCfgValueForStepIndex(configStepIndex));
display.setConfigOption(ConfigStep[configStepIndex]);
display.setConfigUnit(getCfgOptUnitForStepIndex(configStepIndex));
}

// --------------------------------------------------
// Rotary Switch (lang)
// --------------------------------------------------
void EchoLotSetup::onRotaryControlerLongSwitch() {

save();
doInitialization = true;
}

// --------------------------------------------------
// Rotary Drehung
// --------------------------------------------------
void EchoLotSetup::onRotaryControlerTurn(RotaryEncoder::Direction turn)
{
float delta = (turn == RotaryEncoder::Direction::CLOCKWISE) ? 1.0f : -1.0f;
void EchoLotSetup::onRotaryControlerTurn(RotaryEncoder::Direction turn) {

switch (configStepIndex) {
case 0:
airTemp += delta;
break;
case 1:
waterTemp += delta;
break;
case 2:
sonicSpeedAir += delta;
break;
case 3:
saltPromilleWater += delta;
break;
default:
break;
if (turn != RotaryEncoder::Direction::NOROTATION) {

String value = "";
int index = 0;
int sign = (turn == RotaryEncoder::Direction::CLOCKWISE) ? 1 : -1;

switch (configStepIndex) {
case 0:
setAirTemp(min(max(0.0, getAirTemp() + 0.5 * sign), 40.0));
value = String(getAirTemp(), 1);
break;
case 1:
setWaterTemp(min(max(0.0, getWaterTemp() + 0.5 * sign), 40.0));
value = String(getWaterTemp(), 1);
break;
case 2:
setSonicSpeedAir(min(max(330.0, getSonicSpeedAir() + 0.5 * sign), 343.5));
value = String(getSonicSpeedAir(), 1);
break;
case 3:
setSaltPromilleWater(min(max(0, getSaltPromilleWater() + sign), 50));
value = String(getSaltPromilleWater());
break;
default:
break;
}

display.setConfigText(value);
}

}
@@ -98,7 +116,7 @@ void EchoLotSetup::save() {
// Abbrechen
// --------------------------------------------------
void EchoLotSetup::cancel() {
readFromEEPROM();
doInitialization = true;
}

// --------------------------------------------------
@@ -108,6 +126,15 @@ void EchoLotSetup::clear() {
display.clearDisplay();
}

// --------------------------------------------------
// Initial screen zeichnen
// --------------------------------------------------
void EchoLotSetup::drawInitScreen() {
display.clearDisplay();
display.showFrame(INITIALIZATION);
printValues();
}

// --------------------------------------------------
// EEPROM lesen
// --------------------------------------------------
@@ -167,12 +194,26 @@ String EchoLotSetup::getCfgOptUnitForStepIndex(byte index) {
switch (index) {
case 0:
case 1:
return "°C";
return " C";
case 2:
case 3:
return "m/s";
default:
return "";
return " / "; // for Promille painting
}
}

String EchoLotSetup::getCfgValueForStepIndex(byte configStepIndex) {
switch (configStepIndex) {
case 0:
return String(getAirTemp(), 1);
case 1:
return String(getWaterTemp(), 1);
case 2:
return String(getSonicSpeedAir(), 1);
case 3:
return String(getSaltPromilleWater());
default:
return "- - -";
}
}


+ 2
- 4
EchoLotSetup.h ファイルの表示

@@ -36,6 +36,7 @@ class EchoLotSetup {
byte configStepIndex;
String getCfgOptForStepIndex(byte configStepIndex);
String getCfgOptUnitForStepIndex(byte configStepIndex);
String getCfgValueForStepIndex(byte configStepIndex);

void writeFloatToEEPROM(uint16_t addr, float value);
float readFloatFromEEPROM(uint16_t addr);
@@ -43,12 +44,9 @@ class EchoLotSetup {
int readIntegerFromEEPROM(uint16_t addr);

public:
// int eeprom_start_adress = 0;
const static int eeprom_signatur = 1024;
const static uint8_t version = 1;

EchoLotSetup(Display &display);
void initialize();
void drawInitScreen();
void onRotaryControlerSwitch();
void onRotaryControlerLongSwitch();
void onRotaryControlerTurn(RotaryEncoder::Direction turn);

+ 1
- 1
sloeber.ino.cpp ファイルの表示

@@ -2,7 +2,7 @@
//This is a automatic generated file
//Please do not modify this file
//If you touch this file your change will be overwritten during the next build
//This file has been generated on 2026-01-25 22:30:05
//This file has been generated on 2026-01-27 21:30:42

#include "Arduino.h"
#include "Arduino.h"

読み込み中…
キャンセル
保存