big update:

- display update
- timer changed to ms
- allow connections just when connected
This commit is contained in:
Peter Buchegger 2021-03-27 22:02:43 +01:00
parent c96a0310ae
commit 2c78a002ab
19 changed files with 332 additions and 351 deletions

View file

@ -2,7 +2,7 @@
#include <TaskManager.h> #include <TaskManager.h>
#include <logger.h> #include <logger.h>
Display::Display() : _disp(0), _statusFrame(0), _displayOff(false), _displaySaveMode(false) { Display::Display() : _disp(0), _statusFrame(0), _displaySaveMode(false) {
} }
Display::~Display() { Display::~Display() {
@ -22,10 +22,12 @@ void Display::setup(std::shared_ptr<BoardConfig> boardConfig) {
Bitmap bitmap(_disp->getWidth(), _disp->getHeight()); Bitmap bitmap(_disp->getWidth(), _disp->getHeight());
_disp->display(&bitmap); _disp->display(&bitmap);
_displayTimeout.setTimeout(10);
_frameTimeout.setTimeout(15); _displayFrameRate.setTimeout(500);
_displayUpdateRate.setTimeout(1); _displayFrameRate.start();
_displayUpdateRate.start();
_frameTimeout.setTimeout(15 * 1000);
_displaySaveModeTimer.setTimeout(10 * 1000);
} }
void Display::turn180() { void Display::turn180() {
@ -36,49 +38,45 @@ void Display::activateDisplaySaveMode() {
_displaySaveMode = true; _displaySaveMode = true;
} }
void Display::setDisplayTimeout(time_t timeout) { void Display::setDisplaySaveTimeout(uint32_t timeout) {
_displayTimeout.setTimeout(timeout); _displaySaveModeTimer.setTimeout(timeout * 1000);
} }
void Display::update() { void Display::update() {
if (_displayUpdateRate.check()) { if (_displayFrameRate.check()) {
if (_frameTimeout.check()) {
if (_statusFrame->isPrio()) {
Bitmap bitmap(_disp.get());
_statusFrame->drawStatusPage(bitmap);
activateDisplay();
_disp->display(&bitmap);
return;
}
if (_frames.size() > 0) { if (_frames.size() > 0) {
std::shared_ptr<DisplayFrame> frame = *_frames.begin(); std::shared_ptr<DisplayFrame> frame = *_frames.begin();
Bitmap bitmap(_disp.get()); Bitmap bitmap(_disp.get());
frame->drawStatusPage(bitmap); frame->drawStatusPage(bitmap);
activateDisplay(); _disp->display(&bitmap);
_disp->display(&bitmap);
_frames.pop_front(); if (!_frameTimeout.isActive()) {
_frameTimeout.start(); _frameTimeout.start();
return; _displaySaveModeTimer.reset();
} else if (_frameTimeout.check()) {
_frames.pop_front();
_frameTimeout.reset();
} }
} else {
if (!_displayOff && !_displayTimeout.isActive()) { if (_disp->isDisplayOn()) {
Bitmap bitmap(_disp.get()); Bitmap bitmap(_disp.get());
_statusFrame->drawStatusPage(bitmap); _statusFrame->drawStatusPage(bitmap);
activateDisplay();
_disp->display(&bitmap); _disp->display(&bitmap);
if (_displaySaveMode) { if (_displaySaveMode) {
_displayTimeout.start(); if (_displaySaveModeTimer.isActive() && _displaySaveModeTimer.check()) {
_disp->displayOff();
_displaySaveModeTimer.reset();
} else if (!_displaySaveModeTimer.isActive()) {
_displaySaveModeTimer.start();
}
} }
return;
}
if (_displayTimeout.check()) {
deactivateDisplay();
_displayTimeout.reset();
} }
} }
_displayUpdateRate.start();
}; _displayFrameRate.start();
}
} }
void Display::addFrame(std::shared_ptr<DisplayFrame> frame) { void Display::addFrame(std::shared_ptr<DisplayFrame> frame) {
@ -98,16 +96,11 @@ void Display::showSpashScreen(String firmwareTitle, String version) {
_disp->display(&bitmap); _disp->display(&bitmap);
} }
void Display::activateDisplay() { void Display::showStatusScreen(String header, String text) {
if (_displayOff) { Bitmap bitmap(_disp.get());
_disp->displayOn(); bitmap.drawString(0, 0, header);
_displayOff = false; bitmap.drawStringLF(0, 10, text);
} _disp->display(&bitmap);
}
void Display::deactivateDisplay() {
_disp->displayOff();
_displayOff = true;
} }
void TextFrame::drawStatusPage(Bitmap &bitmap) { void TextFrame::drawStatusPage(Bitmap &bitmap) {

View file

@ -29,32 +29,30 @@ public:
~Display(); ~Display();
void setup(std::shared_ptr<BoardConfig> boardConfig); void setup(std::shared_ptr<BoardConfig> boardConfig);
// setup functions
void showSpashScreen(String firmwareTitle, String version);
void setStatusFrame(std::shared_ptr<StatusFrame> frame);
void showStatusScreen(String header, String text);
void turn180(); void turn180();
void activateDisplaySaveMode(); void activateDisplaySaveMode();
void setDisplayTimeout(time_t timeout); void setDisplaySaveTimeout(uint32_t timeout);
// functions for update loop
void update(); void update();
void addFrame(std::shared_ptr<DisplayFrame> frame); void addFrame(std::shared_ptr<DisplayFrame> frame);
void setStatusFrame(std::shared_ptr<StatusFrame> frame);
void showSpashScreen(String firmwareTitle, String version);
private: private:
std::shared_ptr<OLEDDisplay> _disp; std::shared_ptr<OLEDDisplay> _disp;
Timer _displayFrameRate;
std::shared_ptr<StatusFrame> _statusFrame;
std::list<std::shared_ptr<DisplayFrame>> _frames; std::list<std::shared_ptr<DisplayFrame>> _frames;
std::shared_ptr<StatusFrame> _statusFrame;
Timer _frameTimeout; Timer _frameTimeout;
Timer _displayTimeout;
bool _displayOff;
bool _displaySaveMode; bool _displaySaveMode;
Timer _displaySaveModeTimer;
Timer _displayUpdateRate;
void activateDisplay();
void deactivateDisplay();
}; };
class TextFrame : public DisplayFrame { class TextFrame : public DisplayFrame {

View file

@ -31,181 +31,171 @@
#include "OLEDDisplay.h" #include "OLEDDisplay.h"
OLEDDisplay::OLEDDisplay(OLEDDISPLAY_GEOMETRY g) OLEDDisplay::OLEDDisplay(OLEDDISPLAY_GEOMETRY g) : _geometry(g), _displayIsOn(false) {
: _geometry(g)
{
} }
OLEDDisplay::~OLEDDisplay() OLEDDisplay::~OLEDDisplay() {
{
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::displayOn() void OLEDDisplay::displayOn() {
{ sendCommand(DISPLAYON);
sendCommand(DISPLAYON); _displayIsOn = true;
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::displayOff() bool OLEDDisplay::isDisplayOn() const {
{ return _displayIsOn;
sendCommand(DISPLAYOFF);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::invertDisplay() void OLEDDisplay::displayOff() {
{ sendCommand(DISPLAYOFF);
sendCommand(INVERTDISPLAY); _displayIsOn = false;
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::normalDisplay() bool OLEDDisplay::isDisplayOff() const {
{ return !_displayIsOn;
sendCommand(NORMALDISPLAY);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect) void OLEDDisplay::invertDisplay() {
{ sendCommand(INVERTDISPLAY);
sendCommand(SETPRECHARGE); //0xD9
sendCommand(precharge); //0xF1 default, to lower the contrast, put 1-1F
sendCommand(SETCONTRAST);
sendCommand(contrast); // 0-255
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
sendCommand(comdetect); //0x40 default, to lower the contrast, put 0
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(DISPLAYON);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::setBrightness(uint8_t brightness) void OLEDDisplay::normalDisplay() {
{ sendCommand(NORMALDISPLAY);
uint8_t contrast = brightness * 1.171 - 43;
if (brightness < 128)
{
// Magic values to get a smooth/ step-free transition
contrast = brightness * 1.171;
}
uint8_t precharge = 241;
if (brightness == 0)
{
precharge = 0;
}
uint8_t comdetect = brightness / 8;
setContrast(contrast, precharge, comdetect);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::resetOrientation() void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect) {
{ sendCommand(SETPRECHARGE); // 0xD9
sendCommand(SEGREMAP); sendCommand(precharge); // 0xF1 default, to lower the contrast, put 1-1F
sendCommand(COMSCANINC); sendCommand(SETCONTRAST);
sendCommand(contrast); // 0-255
sendCommand(SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast)
sendCommand(comdetect); // 0x40 default, to lower the contrast, put 0
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(DISPLAYON);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::flipScreenVertically() void OLEDDisplay::setBrightness(uint8_t brightness) {
{ uint8_t contrast = brightness * 1.171 - 43;
sendCommand(SEGREMAP | 0x01); if (brightness < 128) {
sendCommand(COMSCANDEC); // Magic values to get a smooth/ step-free transition
contrast = brightness * 1.171;
}
uint8_t precharge = 241;
if (brightness == 0) {
precharge = 0;
}
uint8_t comdetect = brightness / 8;
setContrast(contrast, precharge, comdetect);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::mirrorScreen() void OLEDDisplay::resetOrientation() {
{ sendCommand(SEGREMAP);
sendCommand(SEGREMAP); sendCommand(COMSCANINC);
sendCommand(COMSCANDEC);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::clear() void OLEDDisplay::flipScreenVertically() {
{ sendCommand(SEGREMAP | 0x01);
sendCommand(COMSCANDEC);
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
uint OLEDDisplay::getWidth() void OLEDDisplay::mirrorScreen() {
{ sendCommand(SEGREMAP);
switch(_geometry) sendCommand(COMSCANDEC);
{ }
case GEOMETRY_128_64:
case GEOMETRY_128_32: void OLEDDisplay::display(Bitmap *bitmap) {
return 128; if (isDisplayOff()) {
case GEOMETRY_64_48: displayOn();
case GEOMETRY_64_32: }
return 64; internDisplay(bitmap);
}
return 0;
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
uint OLEDDisplay::getHeight() void OLEDDisplay::clear() {
{
switch(_geometry)
{
case GEOMETRY_128_64:
return 64;
case GEOMETRY_64_48:
return 48;
case GEOMETRY_128_32:
case GEOMETRY_64_32:
return 32;
}
return 0;
} }
// cppcheck-suppress unusedFunction // cppcheck-suppress unusedFunction
void OLEDDisplay::sendInitCommands() uint OLEDDisplay::getWidth() {
{ switch (_geometry) {
sendCommand(DISPLAYOFF); case GEOMETRY_128_64:
sendCommand(SETDISPLAYCLOCKDIV); case GEOMETRY_128_32:
sendCommand(0xF0); // Increase speed of the display max ~96Hz return 128;
sendCommand(SETMULTIPLEX); case GEOMETRY_64_48:
sendCommand(this->getHeight() - 1); case GEOMETRY_64_32:
sendCommand(SETDISPLAYOFFSET); return 64;
sendCommand(0x00); }
if(_geometry == GEOMETRY_64_32) return 0;
{ }
sendCommand(0x00);
} // cppcheck-suppress unusedFunction
else uint OLEDDisplay::getHeight() {
{ switch (_geometry) {
sendCommand(SETSTARTLINE); case GEOMETRY_128_64:
} return 64;
sendCommand(CHARGEPUMP); case GEOMETRY_64_48:
sendCommand(0x14); return 48;
sendCommand(MEMORYMODE); case GEOMETRY_128_32:
sendCommand(0x00); case GEOMETRY_64_32:
sendCommand(SEGREMAP); return 32;
sendCommand(COMSCANINC); }
sendCommand(SETCOMPINS); return 0;
}
if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32)
{ // cppcheck-suppress unusedFunction
sendCommand(0x12); void OLEDDisplay::sendInitCommands() {
} sendCommand(DISPLAYOFF);
else if (_geometry == GEOMETRY_128_32) sendCommand(SETDISPLAYCLOCKDIV);
{ sendCommand(0xF0); // Increase speed of the display max ~96Hz
sendCommand(0x02); sendCommand(SETMULTIPLEX);
} sendCommand(this->getHeight() - 1);
sendCommand(SETDISPLAYOFFSET);
sendCommand(SETCONTRAST); sendCommand(0x00);
if (_geometry == GEOMETRY_64_32) {
if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32) sendCommand(0x00);
{ } else {
sendCommand(0xCF); sendCommand(SETSTARTLINE);
} }
else if (_geometry == GEOMETRY_128_32) sendCommand(CHARGEPUMP);
{ sendCommand(0x14);
sendCommand(0x8F); sendCommand(MEMORYMODE);
} sendCommand(0x00);
sendCommand(SEGREMAP);
sendCommand(SETPRECHARGE); sendCommand(COMSCANINC);
sendCommand(0xF1); sendCommand(SETCOMPINS);
sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)
sendCommand(0x40); //0x40 default, to lower the contrast, put 0 if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32) {
sendCommand(DISPLAYALLON_RESUME); sendCommand(0x12);
sendCommand(NORMALDISPLAY); } else if (_geometry == GEOMETRY_128_32) {
sendCommand(0x2e); // stop scroll sendCommand(0x02);
sendCommand(DISPLAYON); }
sendCommand(SETCONTRAST);
if (_geometry == GEOMETRY_128_64 || _geometry == GEOMETRY_64_48 || _geometry == GEOMETRY_64_32) {
sendCommand(0xCF);
} else if (_geometry == GEOMETRY_128_32) {
sendCommand(0x8F);
}
sendCommand(SETPRECHARGE);
sendCommand(0xF1);
sendCommand(SETVCOMDETECT); // 0xDB, (additionally needed to lower the contrast)
sendCommand(0x40); // 0x40 default, to lower the contrast, put 0
sendCommand(DISPLAYALLON_RESUME);
sendCommand(NORMALDISPLAY);
sendCommand(0x2e); // stop scroll
sendCommand(DISPLAYON);
} }

View file

@ -32,100 +32,109 @@
#ifndef OLEDDISPLAY_h #ifndef OLEDDISPLAY_h
#define OLEDDISPLAY_h #define OLEDDISPLAY_h
#include <Arduino.h>
#include "Bitmap.h" #include "Bitmap.h"
#include <Arduino.h>
//#include "OLEDDisplayFonts.h" //#include "OLEDDisplayFonts.h"
// Display commands // Display commands
#define CHARGEPUMP 0x8D #define CHARGEPUMP 0x8D
#define COLUMNADDR 0x21 #define COLUMNADDR 0x21
#define COMSCANDEC 0xC8 #define COMSCANDEC 0xC8
#define COMSCANINC 0xC0 #define COMSCANINC 0xC0
#define DISPLAYALLON 0xA5 #define DISPLAYALLON 0xA5
#define DISPLAYALLON_RESUME 0xA4 #define DISPLAYALLON_RESUME 0xA4
#define DISPLAYOFF 0xAE #define DISPLAYOFF 0xAE
#define DISPLAYON 0xAF #define DISPLAYON 0xAF
#define EXTERNALVCC 0x1 #define EXTERNALVCC 0x1
#define INVERTDISPLAY 0xA7 #define INVERTDISPLAY 0xA7
#define MEMORYMODE 0x20 #define MEMORYMODE 0x20
#define NORMALDISPLAY 0xA6 #define NORMALDISPLAY 0xA6
#define PAGEADDR 0x22 #define PAGEADDR 0x22
#define SEGREMAP 0xA0 #define SEGREMAP 0xA0
#define SETCOMPINS 0xDA #define SETCOMPINS 0xDA
#define SETCONTRAST 0x81 #define SETCONTRAST 0x81
#define SETDISPLAYCLOCKDIV 0xD5 #define SETDISPLAYCLOCKDIV 0xD5
#define SETDISPLAYOFFSET 0xD3 #define SETDISPLAYOFFSET 0xD3
#define SETHIGHCOLUMN 0x10 #define SETHIGHCOLUMN 0x10
#define SETLOWCOLUMN 0x00 #define SETLOWCOLUMN 0x00
#define SETMULTIPLEX 0xA8 #define SETMULTIPLEX 0xA8
#define SETPRECHARGE 0xD9 #define SETPRECHARGE 0xD9
#define SETSEGMENTREMAP 0xA1 #define SETSEGMENTREMAP 0xA1
#define SETSTARTLINE 0x40 #define SETSTARTLINE 0x40
#define SETVCOMDETECT 0xDB #define SETVCOMDETECT 0xDB
#define SWITCHCAPVCC 0x2 #define SWITCHCAPVCC 0x2
enum OLEDDISPLAY_GEOMETRY enum OLEDDISPLAY_GEOMETRY
{ {
GEOMETRY_128_64 = 0, GEOMETRY_128_64 = 0,
GEOMETRY_128_32 = 1, GEOMETRY_128_32 = 1,
GEOMETRY_64_48 = 2, GEOMETRY_64_48 = 2,
GEOMETRY_64_32 = 3 GEOMETRY_64_32 = 3
}; };
class OLEDDisplay class OLEDDisplay {
{
public: public:
OLEDDisplay(OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64); OLEDDisplay(OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64);
virtual ~OLEDDisplay(); virtual ~OLEDDisplay();
// Turn the display on // Turn the display on
void displayOn(); void displayOn();
// Turn the display offs // Is the Display on?
void displayOff(); bool isDisplayOn() const;
// Inverted display mode // Turn the display offs
void invertDisplay(); void displayOff();
// Normal display mode // Is the Display off?
void normalDisplay(); bool isDisplayOff() const;
// Set display contrast // Inverted display mode
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0 void invertDisplay();
// normal brightness & contrast: contrast = 100
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
// Convenience method to access // Normal display mode
void setBrightness(uint8_t brightness); void normalDisplay();
// Reset display rotation or mirroring // Set display contrast
void resetOrientation(); // really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
// normal brightness & contrast: contrast = 100
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
// Turn the display upside down // Convenience method to access
void flipScreenVertically(); void setBrightness(uint8_t brightness);
// Mirror the display (to be used in a mirror or as a projector) // Reset display rotation or mirroring
void mirrorScreen(); void resetOrientation();
// Write the buffer to the display memory // Turn the display upside down
virtual void display(Bitmap * bitmap) = 0; void flipScreenVertically();
// Clear the local pixel buffer // Mirror the display (to be used in a mirror or as a projector)
void clear(); void mirrorScreen();
// Get screen geometry // Write the buffer to the display memory
uint getWidth(); void display(Bitmap *bitmap);
uint getHeight();
// Clear the local pixel buffer
void clear();
// Get screen geometry
uint getWidth();
uint getHeight();
protected: protected:
// Send all the init commands // Send all the init commands
void sendInitCommands(); void sendInitCommands();
private: private:
OLEDDISPLAY_GEOMETRY _geometry; OLEDDISPLAY_GEOMETRY _geometry;
// Send a command to the display (low level function) // Send a command to the display (low level function)
virtual void sendCommand(uint8_t com) = 0; virtual void sendCommand(uint8_t com) = 0;
virtual void internDisplay(Bitmap *bitmap) = 0;
bool _displayIsOn;
}; };
#endif #endif

View file

@ -1,42 +1,35 @@
#include "SSD1306.h" #include "SSD1306.h"
SSD1306::SSD1306(TwoWire * wire, uint8_t address, OLEDDISPLAY_GEOMETRY g) SSD1306::SSD1306(TwoWire *wire, uint8_t address, OLEDDISPLAY_GEOMETRY g) : OLEDDisplay(g), _wire(wire), _address(address) {
: OLEDDisplay(g), _wire(wire), _address(address) sendInitCommands();
{
sendInitCommands();
} }
SSD1306::~SSD1306() SSD1306::~SSD1306() {
{
} }
void SSD1306::display(Bitmap * bitmap) void SSD1306::internDisplay(Bitmap *bitmap) {
{ sendCommand(PAGEADDR);
sendCommand(PAGEADDR); sendCommand(0x0);
sendCommand(0x0); sendCommand(0xFF);
sendCommand(0xFF);
sendCommand(COLUMNADDR); sendCommand(COLUMNADDR);
sendCommand(0x0); sendCommand(0x0);
sendCommand(getWidth() - 1); sendCommand(getWidth() - 1);
for (int i = 0; i < getWidth() * getHeight() / 8; ) for (int i = 0; i < getWidth() * getHeight() / 8;) {
{ Wire.beginTransmission(_address);
Wire.beginTransmission(_address); Wire.write(0x40);
Wire.write(0x40); for (uint8_t x = 0; x < 16; x++) {
for (uint8_t x = 0; x < 16; x++) Wire.write(bitmap->_buffer[i]);
{ i++;
Wire.write(bitmap->_buffer[i]); }
i++; Wire.endTransmission();
} }
Wire.endTransmission();
}
} }
void SSD1306::sendCommand(uint8_t command) void SSD1306::sendCommand(uint8_t command) {
{ _wire->beginTransmission(_address);
_wire->beginTransmission(_address); _wire->write(0x80);
_wire->write(0x80); _wire->write(command);
_wire->write(command); _wire->endTransmission();
_wire->endTransmission();
} }

View file

@ -34,20 +34,19 @@
#include "OLEDDisplay.h" #include "OLEDDisplay.h"
#include <Wire.h> #include <Wire.h>
class SSD1306 : public OLEDDisplay class SSD1306 : public OLEDDisplay {
{
public: public:
SSD1306(TwoWire * wire, uint8_t address, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64); SSD1306(TwoWire *wire, uint8_t address, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64);
virtual ~SSD1306(); virtual ~SSD1306();
virtual void display(Bitmap * bitmap) override; virtual void internDisplay(Bitmap *bitmap) override;
private: private:
TwoWire * _wire = NULL; TwoWire *_wire = NULL;
uint8_t _address; uint8_t _address;
bool _doI2cAutoInit = false; bool _doI2cAutoInit = false;
virtual void sendCommand(uint8_t command) override; virtual void sendCommand(uint8_t command) override;
}; };
#endif #endif

View file

@ -22,3 +22,11 @@ TaskManager &System::getTaskManager() {
Display &System::getDisplay() { Display &System::getDisplay() {
return _display; return _display;
} }
bool System::isWifiEthConnected() const {
return _isWifiEthConnected;
}
void System::connectedViaWifiEth(bool status) {
_isWifiEthConnected = status;
}

View file

@ -17,12 +17,15 @@ public:
std::shared_ptr<Configuration> getUserConfig() const; std::shared_ptr<Configuration> getUserConfig() const;
TaskManager & getTaskManager(); TaskManager & getTaskManager();
Display & getDisplay(); Display & getDisplay();
bool isWifiEthConnected() const;
void connectedViaWifiEth(bool status);
private: private:
std::shared_ptr<BoardConfig> _boardConfig; std::shared_ptr<BoardConfig> _boardConfig;
std::shared_ptr<Configuration> _userConfig; std::shared_ptr<Configuration> _userConfig;
TaskManager _taskManager; TaskManager _taskManager;
Display _display; Display _display;
bool _isWifiEthConnected;
}; };
#endif #endif

View file

@ -75,9 +75,3 @@ void StatusFrame::drawStatusPage(Bitmap &bitmap) {
y += getSystemFont()->heightInPixel; y += getSystemFont()->heightInPixel;
} }
} }
bool StatusFrame::isPrio() const {
return std::any_of(_tasks.begin(), _tasks.end(), [](std::shared_ptr<Task> task) {
return task->getState() != Okay;
});
}

View file

@ -81,8 +81,6 @@ public:
} }
void drawStatusPage(Bitmap &bitmap) override; void drawStatusPage(Bitmap &bitmap) override;
bool isPrio() const;
private: private:
std::list<std::shared_ptr<Task>> _tasks; std::list<std::shared_ptr<Task>> _tasks;
}; };

View file

@ -1,28 +1,28 @@
#include "Timer.h" #include "Timer.h"
Timer::Timer() : _timeout_sec(0), _timeout(0) { Timer::Timer() : _timeout_ms(0), _nextTimeout(0) {
} }
void Timer::setTimeout(const time_t timeout_sec) { void Timer::setTimeout(const uint32_t timeout_ms) {
_timeout_sec = timeout_sec; _timeout_ms = timeout_ms;
} }
time_t Timer::getTriggerTime() const { time_t Timer::getTriggerTimeInSec() const {
return _timeout; return (_nextTimeout - millis()) / 1000;
} }
bool Timer::isActive() const { bool Timer::isActive() const {
return _timeout != 0; return _nextTimeout != 0;
} }
void Timer::reset() { void Timer::reset() {
_timeout = 0; _nextTimeout = 0;
} }
bool Timer::check() { bool Timer::check() {
return now() > _timeout; return millis() > _nextTimeout;
} }
void Timer::start() { void Timer::start() {
_timeout = now() + _timeout_sec; _nextTimeout = millis() + _timeout_ms;
} }

View file

@ -7,8 +7,8 @@ class Timer {
public: public:
Timer(); Timer();
void setTimeout(const time_t timeout_sec); void setTimeout(const uint32_t timeout_ms);
time_t getTriggerTime() const; time_t getTriggerTimeInSec() const;
bool isActive() const; bool isActive() const;
@ -18,8 +18,8 @@ public:
void start(); void start();
private: private:
time_t _timeout_sec; uint32_t _timeout_ms;
time_t _timeout; uint32_t _nextTimeout;
}; };
#endif #endif

View file

@ -34,9 +34,6 @@ void setup() {
logPrintlnW("LoRa APRS iGate by OE5BPA (Peter Buchegger)"); logPrintlnW("LoRa APRS iGate by OE5BPA (Peter Buchegger)");
logPrintlnW("Version: " VERSION); logPrintlnW("Version: " VERSION);
ProjectConfigurationManagement confmg;
std::shared_ptr<Configuration> userConfig = confmg.readConfiguration();
std::list<std::shared_ptr<BoardConfig>> boardConfigs; std::list<std::shared_ptr<BoardConfig>> boardConfigs;
// clang-format off // clang-format off
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26))); boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26)));
@ -49,8 +46,10 @@ void setup() {
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26))); boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26)));
// clang-format on // clang-format on
BoardFinder finder(boardConfigs); ProjectConfigurationManagement confmg;
std::shared_ptr<BoardConfig> boardConfig = finder.getBoardConfig(userConfig->board); std::shared_ptr<Configuration> userConfig = confmg.readConfiguration();
BoardFinder finder(boardConfigs);
std::shared_ptr<BoardConfig> boardConfig = finder.getBoardConfig(userConfig->board);
if (boardConfig == 0) { if (boardConfig == 0) {
boardConfig = finder.searchBoardConfig(); boardConfig = finder.searchBoardConfig();
if (boardConfig == 0) { if (boardConfig == 0) {
@ -80,9 +79,7 @@ void setup() {
powerManagement->deactivateGPS(); powerManagement->deactivateGPS();
} }
load_config(boardConfig);
LoRaSystem = std::shared_ptr<System>(new System(boardConfig, userConfig)); LoRaSystem = std::shared_ptr<System>(new System(boardConfig, userConfig));
LoRaSystem->getTaskManager().addTask(std::shared_ptr<Task>(new DisplayTask())); LoRaSystem->getTaskManager().addTask(std::shared_ptr<Task>(new DisplayTask()));
LoRaSystem->getTaskManager().addTask(std::shared_ptr<Task>(new LoraTask())); LoRaSystem->getTaskManager().addTask(std::shared_ptr<Task>(new LoraTask()));
if (boardConfig->Type == eETH_BOARD) { if (boardConfig->Type == eETH_BOARD) {
@ -101,6 +98,13 @@ void setup() {
LoRaSystem->getDisplay().showSpashScreen("LoRa APRS iGate", VERSION); LoRaSystem->getDisplay().showSpashScreen("LoRa APRS iGate", VERSION);
if (userConfig->callsign == "NOCALL-10") {
logPrintlnE("You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!");
LoRaSystem->getDisplay().showStatusScreen("ERROR", "You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!");
while (true)
;
}
if (userConfig->display.overwritePin != 0) { if (userConfig->display.overwritePin != 0) {
pinMode(userConfig->display.overwritePin, INPUT); pinMode(userConfig->display.overwritePin, INPUT);
pinMode(userConfig->display.overwritePin, INPUT_PULLUP); pinMode(userConfig->display.overwritePin, INPUT_PULLUP);

View file

@ -15,7 +15,7 @@ AprsIsTask::~AprsIsTask() {
} }
bool AprsIsTask::setup(std::shared_ptr<System> system) { bool AprsIsTask::setup(std::shared_ptr<System> system) {
_beacon_timer.setTimeout(minutesToTime_t(system->getUserConfig()->beacon.timeout)); _beacon_timer.setTimeout(system->getUserConfig()->beacon.timeout * 60 * 1000);
_aprs_is = std::shared_ptr<APRS_IS>(new APRS_IS(system->getUserConfig()->callsign, system->getUserConfig()->aprs_is.passcode, "ESP32-APRS-IS", "0.2")); _aprs_is = std::shared_ptr<APRS_IS>(new APRS_IS(system->getUserConfig()->callsign, system->getUserConfig()->aprs_is.passcode, "ESP32-APRS-IS", "0.2"));
_beaconMsg = std::shared_ptr<APRSMessage>(new APRSMessage()); _beaconMsg = std::shared_ptr<APRSMessage>(new APRSMessage());
@ -29,6 +29,9 @@ bool AprsIsTask::setup(std::shared_ptr<System> system) {
} }
bool AprsIsTask::loop(std::shared_ptr<System> system) { bool AprsIsTask::loop(std::shared_ptr<System> system) {
if (!system->isWifiEthConnected()) {
return false;
}
if (!_aprs_is->connected()) { if (!_aprs_is->connected()) {
if (!connect(system)) { if (!connect(system)) {
_stateInfo = "not connected"; _stateInfo = "not connected";
@ -54,8 +57,8 @@ bool AprsIsTask::loop(std::shared_ptr<System> system) {
system->getDisplay().addFrame(std::shared_ptr<DisplayFrame>(new TextFrame("BEACON", _beaconMsg->toString()))); system->getDisplay().addFrame(std::shared_ptr<DisplayFrame>(new TextFrame("BEACON", _beaconMsg->toString())));
_beacon_timer.start(); _beacon_timer.start();
} }
time_t diff = _beacon_timer.getTriggerTime() - now(); time_t diff = _beacon_timer.getTriggerTimeInSec();
_stateInfo = "beacon " + String(minute(diff)) + ":" + String(second(diff)); _stateInfo = "beacon " + String(diff / 60) + ":" + String(diff % 60);
_state = Okay; _state = Okay;
return true; return true;
} }

View file

@ -19,7 +19,7 @@ bool DisplayTask::setup(std::shared_ptr<System> system) {
system->getDisplay().setStatusFrame(statusFrame); system->getDisplay().setStatusFrame(statusFrame);
if (!system->getUserConfig()->display.alwaysOn) { if (!system->getUserConfig()->display.alwaysOn) {
system->getDisplay().activateDisplaySaveMode(); system->getDisplay().activateDisplaySaveMode();
system->getDisplay().setDisplayTimeout(system->getUserConfig()->display.timeout); system->getDisplay().setDisplaySaveTimeout(system->getUserConfig()->display.timeout);
} }
_stateInfo = system->getUserConfig()->callsign; _stateInfo = system->getUserConfig()->callsign;
return true; return true;

View file

@ -75,10 +75,12 @@ bool EthTask::setup(std::shared_ptr<System> system) {
bool EthTask::loop(std::shared_ptr<System> system) { bool EthTask::loop(std::shared_ptr<System> system) {
if (!eth_connected) { if (!eth_connected) {
system->connectedViaWifiEth(false);
_stateInfo = "Ethernet not connected"; _stateInfo = "Ethernet not connected";
_state = Error; _state = Error;
return false; return false;
} }
system->connectedViaWifiEth(true);
_stateInfo = ETH.localIP().toString(); _stateInfo = ETH.localIP().toString();
_state = Okay; _state = Okay;
return true; return true;

View file

@ -17,6 +17,9 @@ bool NTPTask::setup(std::shared_ptr<System> system) {
} }
bool NTPTask::loop(std::shared_ptr<System> system) { bool NTPTask::loop(std::shared_ptr<System> system) {
if (!system->isWifiEthConnected()) {
return false;
}
if (!_beginCalled) { if (!_beginCalled) {
_ntpClient->begin(); _ntpClient->begin();
_beginCalled = true; _beginCalled = true;

View file

@ -27,6 +27,7 @@ bool WifiTask::setup(std::shared_ptr<System> system) {
bool WifiTask::loop(std::shared_ptr<System> system) { bool WifiTask::loop(std::shared_ptr<System> system) {
const uint8_t wifi_status = _wiFiMulti->run(); const uint8_t wifi_status = _wiFiMulti->run();
if (wifi_status != WL_CONNECTED) { if (wifi_status != WL_CONNECTED) {
system->connectedViaWifiEth(false);
logPrintlnE("WiFi not connected!"); logPrintlnE("WiFi not connected!");
_oldWifiStatus = wifi_status; _oldWifiStatus = wifi_status;
_stateInfo = "WiFi not connected"; _stateInfo = "WiFi not connected";
@ -38,6 +39,7 @@ bool WifiTask::loop(std::shared_ptr<System> system) {
_oldWifiStatus = wifi_status; _oldWifiStatus = wifi_status;
return false; return false;
} }
system->connectedViaWifiEth(true);
_stateInfo = WiFi.localIP().toString(); _stateInfo = WiFi.localIP().toString();
_state = Okay; _state = Okay;
return true; return true;

View file

@ -97,21 +97,3 @@ void ProjectConfigurationManagement::writeProjectConfiguration(std::shared_ptr<C
data["board"] = conf->board; data["board"] = conf->board;
} }
std::shared_ptr<Configuration> load_config(std::shared_ptr<BoardConfig> boardConfig) {
ProjectConfigurationManagement confmg;
std::shared_ptr<Configuration> config = confmg.readConfiguration();
if (config->callsign == "NOCALL-10") {
logPrintlnE("You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!");
// show_display("ERROR", "You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!");
while (true) {
}
}
/*if(KEY_BUILTIN != 0 && Config->display.overwritePin == 0)
{
Config->display.overwritePin = KEY_BUILTIN;
}*/
logPrintlnI("Configuration loaded!");
return config;
}