small changes and many new sensors

This commit is contained in:
2023-10-30 14:30:02 +01:00
parent 07917fe5ba
commit aad07c1b0a
21 changed files with 1642 additions and 297 deletions

View File

@@ -27,6 +27,7 @@
//#pragma message "Using ESP32" //#pragma message "Using ESP32"
#define DELAY_US(us) ets_delay_us(us) #define DELAY_US(us) ets_delay_us(us)
#define DELAY_MS(ms) vTaskDelay(ms / portTICK_PERIOD_MS);
#define IN_FLASH #define IN_FLASH
#elif (IS_ESP8266) #elif (IS_ESP8266)
@@ -63,7 +64,7 @@
//} //}
#if IS_ESP8266 #if IS_ESP8266
#define sprintf os_sprintf //#define sprintf os_sprintf
extern "C" { extern "C" {
// #include "ets_sys.h" // #include "ets_sys.h"
// #include "c_types.h" // #include "c_types.h"

View File

@@ -5,7 +5,11 @@
#include "../../Debug.h" #include "../../Debug.h"
#ifndef usleep
void usleep(int val) {
vTaskDelay(val / 1000 / portTICK_PERIOD_MS);
}
#endif
/** /**
* base-class for Waveshare SPI E-Ink displays * base-class for Waveshare SPI E-Ink displays
@@ -20,7 +24,7 @@ template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class
public: public:
Waveshare(SPI& spi) : spi(spi) { Waveshare(SPI& spi) : spi(spi) {
debugMod4(NAME, "ctor() CS:%d BUSY:%d RST:%d DC:%d", PIN_CS, PIN_BUSY, PIN_RST, PIN_DC); Log::addInfo(NAME, "ctor() CS:%d BUSY:%d RST:%d DC:%d", PIN_CS, PIN_BUSY, PIN_RST, PIN_DC);
MyGPIO::setInput(PIN_BUSY); MyGPIO::setInput(PIN_BUSY);
MyGPIO::setOutput(PIN_RST); MyGPIO::setOutput(PIN_RST);
MyGPIO::setOutput(PIN_DC); MyGPIO::setOutput(PIN_DC);
@@ -30,7 +34,7 @@ public:
protected: protected:
void reset() { void reset() {
debugMod(NAME, "reset()"); Log::addInfo(NAME, "reset()");
MyGPIO::clear(PIN_RST); MyGPIO::clear(PIN_RST);
usleep(200*1000); usleep(200*1000);
MyGPIO::set(PIN_RST); MyGPIO::set(PIN_RST);
@@ -54,9 +58,9 @@ protected:
} }
void waitUntilIdle() { void waitUntilIdle() {
debugMod(NAME, "waitUntilIdle()"); Log::addInfo(NAME, "waitUntilIdle()");
while(MyGPIO::get(PIN_BUSY) == 0) {usleep(200*1000);} while(MyGPIO::get(PIN_BUSY) == 0) {usleep(200*1000);}
debugMod(NAME, "OK"); Log::addInfo(NAME, "OK");
} }
void lut(uint8_t c, uint8_t l, const uint8_t* p) { void lut(uint8_t c, uint8_t l, const uint8_t* p) {

View File

@@ -1,10 +1,52 @@
#include "Waveshare.h" #include "Waveshare.h"
// www.waveshare.com/wiki/4.2inch_e-Paper_Module_(B)
// https://www.waveshare.com/wiki/4.2inch_e-Paper_Module_(B)_Manual#Overview
template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class Waveshare_4_2 : public Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI> { template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class Waveshare_4_2 : public Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI> {
static constexpr const char* NAME = "E-Ink 4.2\""; static constexpr const char* NAME = "E-Ink 4.2\"";
static constexpr const uint8_t PANEL_SETTING = 0x00;
static constexpr const uint8_t POWER_SETTING = 0x01;
static constexpr const uint8_t POWER_OFF = 0x02;
static constexpr const uint8_t POWER_OFF_SEQUENCE_SETTING = 0x03;
static constexpr const uint8_t POWER_ON = 0x04;
static constexpr const uint8_t POWER_ON_MEASURE = 0x05;
static constexpr const uint8_t BOOSTER_SOFT_START = 0x06;
static constexpr const uint8_t DEEP_SLEEP = 0x07;
static constexpr const uint8_t DATA_START_TRANSMISSION_1 = 0x10;
static constexpr const uint8_t DATA_STOP = 0x11;
static constexpr const uint8_t DISPLAY_REFRESH = 0x12;
static constexpr const uint8_t DATA_START_TRANSMISSION_2 = 0x13;
static constexpr const uint8_t LUT_FOR_VCOM = 0x20;
static constexpr const uint8_t LUT_WHITE_TO_WHITE = 0x21;
static constexpr const uint8_t LUT_BLACK_TO_WHITE = 0x22;
static constexpr const uint8_t LUT_WHITE_TO_BLACK = 0x23;
static constexpr const uint8_t LUT_BLACK_TO_BLACK = 0x24;
static constexpr const uint8_t PLL_CONTROL = 0x30;
static constexpr const uint8_t TEMPERATURE_SENSOR_COMMAND = 0x40;
static constexpr const uint8_t TEMPERATURE_SENSOR_SELECTION = 0x41;
static constexpr const uint8_t TEMPERATURE_SENSOR_WRITE = 0x42;
static constexpr const uint8_t TEMPERATURE_SENSOR_READ = 0x43;
static constexpr const uint8_t VCOM_AND_DATA_INTERVAL_SETTING = 0x50;
static constexpr const uint8_t LOW_POWER_DETECTION = 0x51;
static constexpr const uint8_t TCON_SETTING = 0x60;
static constexpr const uint8_t RESOLUTION_SETTING = 0x61;
static constexpr const uint8_t GSST_SETTING = 0x65;
static constexpr const uint8_t GET_STATUS = 0x71;
static constexpr const uint8_t AUTO_MEASUREMENT_VCOM = 0x80;
static constexpr const uint8_t READ_VCOM_VALUE = 0x81;
static constexpr const uint8_t VCM_DC_SETTING = 0x82;
static constexpr const uint8_t PARTIAL_WINDOW = 0x90;
static constexpr const uint8_t PARTIAL_IN = 0x91;
static constexpr const uint8_t PARTIAL_OUT = 0x92;
static constexpr const uint8_t PROGRAM_MODE = 0xA0;
static constexpr const uint8_t ACTIVE_PROGRAMMING = 0xA1;
static constexpr const uint8_t READ_OTP = 0xA2;
static constexpr const uint8_t POWER_SAVING = 0xE3;
public: public:
enum class Mode { enum class Mode {
@@ -42,53 +84,55 @@ public:
} }
void enableWindow() { void enableWindow() {
this->sendCommand(0x91); this->sendCommand(PARTIAL_IN);
} }
void disableWindow() { void disableWindow() {
this->sendCommand(0x92); this->sendCommand(PARTIAL_OUT);
} }
void init(Mode mode) { void init(Mode mode) {
debugMod(NAME, "init()"); Log::addInfo(NAME, "init()");
this->reset(); this->reset();
this->send3(0x06, 0x17, 0x17, 0x17); // BOOSTER_SOFT_START this->send3(BOOSTER_SOFT_START, 0x17, 0x17, 0x17);
this->sendCommand(0x04); // POWER_ON this->sendCommand(POWER_ON);
this->waitUntilIdle(); this->waitUntilIdle();
uint8_t cfg = 0x0F; uint8_t cfg = 0x0F;
if (mode == Mode::BLACK_WHITE) {cfg |= (1<<4);} if (mode == Mode::BLACK_WHITE) {cfg |= (1<<4);}
this->send1(0x00, cfg); // PANEL_SETTING this->send1(PANEL_SETTING, cfg);
this->send1(0x50, 0xF7); // VCOM_AND_DATA_INTERVAL_SETTING this->send1(VCOM_AND_DATA_INTERVAL_SETTING, 0xF7);
//this->sendCommand(0x10);//DATA_START_TRANSMISSION_1 //this->sendCommand(0x10);//DATA_START_TRANSMISSION_1
//usleep(10*1000); //usleep(10*1000);
debugMod(NAME, "init() complete"); Log::addInfo(NAME, "init() complete");
} }
/** load black data, bit-set = black pixel, nullptr input = clear all */
void loadBlack(const uint8_t* black) { void loadBlack(const uint8_t* black) {
this->sendCommand(0x10); this->sendCommand(DATA_START_TRANSMISSION_1);
if (black) { if (black) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(black[i]));} for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(black[i]));}
} else { } else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);} for (int i = 0; i < 400*300/8; ++i) {this->sendData(0);} // 0 = pixel not set (blank)
} }
this->sendCommand(0x11); this->sendCommand(DATA_STOP);
} }
/** load black data, bit-set = red pixel, nullptr input = clear all */
void loadRed(const uint8_t* red) { void loadRed(const uint8_t* red) {
this->sendCommand(0x13); this->sendCommand(DATA_START_TRANSMISSION_2);
if (red) { if (red) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(red[i]));} for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(red[i]));}
} else { } else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);} for (int i = 0; i < 400*300/8; ++i) {this->sendData(0);} // 0 = pixel not set (blank)
} }
this->sendCommand(0x11); this->sendCommand(DATA_STOP);
} }
static uint8_t reverse(uint8_t a) { static uint8_t reverse(uint8_t a) {
@@ -101,19 +145,19 @@ public:
void show() { void show() {
debugMod(NAME, "refresh"); Log::addInfo(NAME, "refresh");
this->sendCommand(0x12);//DISPLAY_REFRESH this->sendCommand(DISPLAY_REFRESH);
usleep(100*1000); usleep(100*1000);
this->waitUntilIdle(); this->waitUntilIdle();
debugMod(NAME, "refresh done"); Log::addInfo(NAME, "refresh done");
debugMod(NAME, "sleep"); Log::addInfo(NAME, "sleep");
this->send1(0x50, 0x17);//VCOM_AND_DATA_INTERVAL_SETTING this->send1(VCOM_AND_DATA_INTERVAL_SETTING, 0x17);
this->send1(0x82, 0x00);//VCM_DC_SETTING_REGISTER, to solve Vcom drop this->send1(VCM_DC_SETTING, 0x00); //to solve Vcom drop
this->send4(0x01, 0x02, 0x00, 0x00, 0x00);//POWER_SETTING this->send4(POWER_SETTING, 0x02, 0x00, 0x00, 0x00);
this->waitUntilIdle(); this->waitUntilIdle();
this->sendCommand(0x02);//POWER_OFF this->sendCommand(POWER_OFF);
debugMod(NAME, "sleep done"); Log::addInfo(NAME, "sleep done");
} }

147
ext/lcd/SH1106.h Normal file
View File

@@ -0,0 +1,147 @@
#pragma once
#include "../../io/SoftI2C.h"
// https://www.displayfuture.com/Display/datasheet/controller/SH1106.pdf
// Note: the SH1106 is almost the same as SSD1306,
// except for some addressing modes, when writing the whole display at once
// the device address is also the same
template <typename I2C, uint8_t w, uint8_t h> class SH1106 {
private:
static constexpr uint8_t ADDR7 = 0b0111100;
static constexpr uint8_t CMD_COL_ADDR_LO = 0x00;
static constexpr uint8_t CMD_COL_ADDR_HI = 0x10;
static constexpr uint8_t CMD_PUMP_VOLTAGE = 0x30;
static constexpr uint8_t CMD_START_LINE = 0x40;
static constexpr uint8_t CMD_DISPLAY_OFF = 0xAE | 0;
static constexpr uint8_t CMD_DISPLAY_ON = 0xAE | 1;
static constexpr uint8_t CMD_PAGE_ADDR = 0xB0;
private:
bool inited = false;
I2C& i2c;
public:
SH1106(I2C& i2c) : i2c(i2c) {
}
bool isPresent() {
return i2c.query(ADDR7);
}
/** checks if LCD is present and initializes it once / when it was gone */
bool isPresentAndInit() {
bool present = isPresent();
if (!present) {inited = false;}
if ( present && !inited) {initOnce();}
return present;
}
void initOnce() {
if (inited) {return;}
init();
inited = true;
}
void flush(const uint8_t* data) {
for (uint8_t y = 0; y < h/8; ++y) {
sendCommand(CMD_COL_ADDR_LO | 0);
sendCommand(CMD_COL_ADDR_HI | 0);
sendCommand(CMD_PAGE_ADDR | y);
startDataTransfer();
for (uint8_t x = 0; x < w; ++x) {
writeData(*data); ++data;
}
stopDataTransfer();
}
}
private:
inline void startDataTransfer() {
i2c.startWrite(ADDR7);
i2c.writeByteAndCheck(0x40);
}
inline void writeData(uint8_t val) {
i2c.writeByteAndCheck(val);
}
inline void stopDataTransfer() {
i2c.stop();
}
void init() {
sendCommand(CMD_DISPLAY_OFF);
// Init
sendCommand(CMD_DISPLAY_ON);
}
private:
void sendCommand(uint8_t cmd) {
bool ok;
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n");}
ok = i2c.writeByteAndCheck(0x00); // command
if (!ok) {os_printf("failed command mode\n");}
ok = i2c.writeByteAndCheck(cmd);
if (!ok) {os_printf("failed command\n");}
i2c.stop();
}
void sendCommand(uint8_t cmd, uint8_t v1) {
sendCommand(cmd);
sendCommand(v1);
}
void sendCommand(uint8_t cmd, uint8_t v1, uint8_t v2) {
sendCommand(cmd);
sendCommand(v1);
sendCommand(v2);
}
void sendCommand2(uint8_t cmd, uint8_t v1) {
i2c.startWrite(ADDR7);
i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(cmd);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v1);
i2c.stop();
}
void sendCommand2(uint8_t cmd, uint8_t v1, uint8_t v2) {
i2c.startWrite(ADDR7);
i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(cmd);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v1);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v2);
i2c.stop();
}
};

View File

@@ -3,6 +3,9 @@
#include "../../io/SoftI2C.h" #include "../../io/SoftI2C.h"
// NOTE: this is almost the same as SH1106
// https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
//#define SSD1306_128_64 1 //#define SSD1306_128_64 1
//#define SSD1306_64_48 1 // https://github.com/mcauser/Adafruit_SSD1306/blob/esp8266-64x48/Adafruit_SSD1306.cpp //#define SSD1306_64_48 1 // https://github.com/mcauser/Adafruit_SSD1306/blob/esp8266-64x48/Adafruit_SSD1306.cpp
@@ -89,6 +92,14 @@ public:
return i2c.query(ADDR7); return i2c.query(ADDR7);
} }
/** checks if LCD is present and initializes it once / when it was gone */
bool isPresentAndInit() {
bool present = isPresent();
if (!present) {inited = false;}
if ( present && !inited) {initOnce();}
return present;
}
void initOnce() { void initOnce() {
if (inited) {return;} if (inited) {return;}
init(); init();
@@ -98,20 +109,29 @@ public:
void flush(const uint8_t* data) { void flush(const uint8_t* data) {
sendCommand(SSD1306_COLUMNADDR);
// special handling for 64x48 oled shield // special handling for 64x48 oled shield
#if SSD1306_LCDWIDTH == 64 && SSD1306_LCDHEIGHT == 48 #if SSD1306_LCDWIDTH == 64 && SSD1306_LCDHEIGHT == 48
sendCommand(SSD1306_COLUMNADDR);
sendCommand(32); sendCommand(32);
sendCommand(32 + SSD1306_LCDWIDTH - 1); sendCommand(32 + SSD1306_LCDWIDTH - 1);
#else #else
sendCommand(0); // Column start address (0 = reset) sendCommand(SSD1306_COLUMNADDR, 0, SSD1306_LCDWIDTH-1);
sendCommand(SSD1306_LCDWIDTH-1); // Column end address (127 = reset) //sendCommand(SSD1306_COLUMNADDR);
//sendCommand(0); // Column start address (0 = reset)
//sendCommand(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
#endif #endif
sendCommand(SSD1306_PAGEADDR);
sendCommand(0); // Page start address (0 = reset) sendCommand(SSD1306_PAGEADDR, 0, (SSD1306_LCDHEIGHT/8)-1);
sendCommand( (SSD1306_LCDHEIGHT/8)-1 ); // Page end address //sendCommand(SSD1306_PAGEADDR);
//sendCommand(0); // Page start address (0 = reset)
//sendCommand( (SSD1306_LCDHEIGHT/8)-1 ); // Page end address
// #if SSD1306_LCDHEIGHT == 64 // #if SSD1306_LCDHEIGHT == 64
// sendCommand(7); // Page end address // sendCommand(7); // Page end address
// #endif // #endif
@@ -147,7 +167,8 @@ public:
bool ok = i2c.writeByteAndCheck(0x40); bool ok = i2c.writeByteAndCheck(0x40);
if (!ok) {os_printf("failed write data\n");} if (!ok) {os_printf("failed write data\n");}
for (uint16_t i=0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) { //for (uint16_t i=0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
for (uint16_t i=0; i < 16; i++) {
i2c.writeByteAndCheck(data[i]); i2c.writeByteAndCheck(data[i]);
} }
@@ -163,25 +184,32 @@ private:
uint8_t vccstate = 0; uint8_t vccstate = 0;
sendCommand(SSD1306_DISPLAYOFF); // 0xAE sendCommand(SSD1306_DISPLAYOFF); // 0xAE
sendCommand(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 sendCommand(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
sendCommand(0x80); // the suggested ratio 0x80 sendCommand(0x80); // the suggested ratio 0x80
sendCommand(SSD1306_SETMULTIPLEX); // 0xA8 sendCommand(SSD1306_SETMULTIPLEX); // 0xA8: multiplexer (31 == 32MUX, 63 == 64MUX)
sendCommand(SSD1306_LCDHEIGHT - 1); sendCommand(SSD1306_LCDHEIGHT - 1);
sendCommand(SSD1306_SETDISPLAYOFFSET); // 0xD3 sendCommand(SSD1306_SETDISPLAYOFFSET); // 0xD3: vertical shift 0-63
sendCommand(0x0); // no offset sendCommand(0x0); // no offset
sendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0 sendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
sendCommand(SSD1306_CHARGEPUMP); // 0x8D sendCommand(SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC) { if (vccstate == SSD1306_EXTERNALVCC) {
sendCommand(0x10); sendCommand(0x10);
} else { } else {
sendCommand(0x14); sendCommand(0x14);
} }
sendCommand(SSD1306_MEMORYMODE); // 0x20
sendCommand(0x00); // 0x0 act like ks0108
sendCommand(SSD1306_SEGREMAP | 0x1);
//sendCommand(SSD1306_MEMORYMODE); // 0x20: memory mode: hor/ver/page
//sendCommand(0x02); // 0x0 act like ks0108
sendCommand(SSD1306_MEMORYMODE, 0x00); // 0x20: memory mode: hor/ver/page
sendCommand(SSD1306_SEGREMAP | 0x0);
//sendCommand(SSD1306_COMSCANINC); // rotate 0
sendCommand(SSD1306_COMSCANDEC); // rotate 180? sendCommand(SSD1306_COMSCANDEC); // rotate 180?
// OLD // OLD
@@ -244,6 +272,8 @@ private:
private: private:
void sendCommand(uint8_t cmd) { void sendCommand(uint8_t cmd) {
bool ok; bool ok;
ok = i2c.startWrite(ADDR7); ok = i2c.startWrite(ADDR7);
@@ -255,6 +285,37 @@ private:
i2c.stop(); i2c.stop();
} }
void sendCommand(uint8_t cmd, uint8_t v1) {
bool ok;
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n");}
ok = i2c.writeByteAndCheck(0x00); // command
if (!ok) {os_printf("failed command mode\n");}
ok = i2c.writeByteAndCheck(cmd);
if (!ok) {os_printf("failed command\n");}
ok = i2c.writeByteAndCheck(0x00); // command
ok = i2c.writeByteAndCheck(v1);
if (!ok) {os_printf("failed command\n");}
i2c.stop();
}
void sendCommand(uint8_t cmd, uint8_t v1, uint8_t v2) {
bool ok;
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n");}
ok = i2c.writeByteAndCheck(0x00); // command
if (!ok) {os_printf("failed command mode\n");}
ok = i2c.writeByteAndCheck(cmd);
if (!ok) {os_printf("failed command\n");}
ok = i2c.writeByteAndCheck(0x00); // command
ok = i2c.writeByteAndCheck(v1);
if (!ok) {os_printf("failed command\n");}
ok = i2c.writeByteAndCheck(0x00); // command
ok = i2c.writeByteAndCheck(v2);
if (!ok) {os_printf("failed command\n");}
i2c.stop();
}
}; };

324
ext/lcd/SSD1306.h.testing Normal file
View File

@@ -0,0 +1,324 @@
#ifndef LCD_SSD1306
#define LCD_SSD1306
#include "../../io/SoftI2C.h"
// https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
//#define SSD1306_128_64 1
//#define SSD1306_64_48 1 // https://github.com/mcauser/Adafruit_SSD1306/blob/esp8266-64x48/Adafruit_SSD1306.cpp
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#elif defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 32
#elif defined SSD1306_96_16
#define SSD1306_LCDWIDTH 96
#define SSD1306_LCDHEIGHT 16
#elif defined SSD1306_64_48
#define SSD1306_LCDWIDTH 64
#define SSD1306_LCDHEIGHT 48
#else
#error "SSD1306 display size not defined"
#endif
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR 0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
// Scrolling #defines
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
template <typename I2C> class SSD1306 {
private:
static constexpr uint8_t ADDR7 = 0b0111100;
bool inited = false;
I2C& i2c;
public:
SSD1306(I2C& i2c) : i2c(i2c) {
}
bool isPresent() {
return i2c.query(ADDR7);
}
/** checks if LCD is present and initializes it once / when it was gone */
bool isPresentAndInit() {
bool present = isPresent();
if (!present) {inited = false;}
if ( present && !inited) {initOnce();}
return present;
}
void initOnce() {
if (inited) {return;}
init();
inited = true;
}
void flush(const uint8_t* data) {
sendCommand(0xC0);
sendCommand2(0x20, 0b11111100);
// special handling for 64x48 oled shield
#if SSD1306_LCDWIDTH == 64 && SSD1306_LCDHEIGHT == 48
sendCommand(SSD1306_COLUMNADDR);
sendCommand(32);
sendCommand(32 + SSD1306_LCDWIDTH - 1);
#else
//sendCommand2(SSD1306_COLUMNADDR, 0, SSD1306_LCDWIDTH-1);
sendCommand(SSD1306_COLUMNADDR);
sendCommand(0); // Column start address (0 = reset)
sendCommand(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
#endif
//sendCommand2(SSD1306_PAGEADDR, 0, (SSD1306_LCDHEIGHT/8)-1);
sendCommand(SSD1306_PAGEADDR);
sendCommand(0); // Page start address (0 = reset)
sendCommand( (SSD1306_LCDHEIGHT/8)-1 ); // Page end address
sendCommand(0x00 | 0x00);
sendCommand(0x10 | 0x00);
sendCommand(0xB0 | 0x02);
// #if SSD1306_LCDHEIGHT == 64
// sendCommand(7); // Page end address
// #endif
// #if SSD1306_LCDHEIGHT == 48
// sendCommand(3); // Page end address
// #endif
// #if SSD1306_LCDHEIGHT == 32
// sendCommand(3); // Page end address
// #endif
// #if SSD1306_LCDHEIGHT == 16
// sendCommand(1); // Page end address
// #endif
// for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
// // send a bunch of data in one xmission
// i2c::startWrite(ADDR7);
// bool ok = i2c::writeByteAndCheck(0x40);
// if (!ok) {os_printf("failed line\n");}
// for (uint8_t x = 0; x < 16; ++x) {
// i2c::writeByteAndCheck(data[i]);
// ++i;
// }
// i--;
// i2c::stop();
// }
i2c.startWrite(ADDR7);
bool ok = i2c.writeByteAndCheck(0x40);
if (!ok) {os_printf("failed write data\n");}
//for (uint16_t i=0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
for (uint16_t i=0; i < 16; i++) {
i2c.writeByteAndCheck(data[i]);
usleep(1000);
}
i2c.stop();
}
private:
void init() {
uint8_t vccstate = 0;
sendCommand(SSD1306_DISPLAYOFF); // 0xAE
sendCommand(SSD1306_SETDISPLAYCLOCKDIV, 0x80); // 0xD5, the suggested ratio 0x80
sendCommand(SSD1306_SETMULTIPLEX, SSD1306_LCDHEIGHT-1); // 0xA8: multiplexer (31 == 32MUX, 63 == 64MUX)
sendCommand(SSD1306_SETDISPLAYOFFSET, 0x00); // 0xD3: vertical shift 0-63, no offset
sendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
if (vccstate == SSD1306_EXTERNALVCC) {
sendCommand(SSD1306_CHARGEPUMP, 0x10); // 0x8D
} else {
sendCommand(SSD1306_CHARGEPUMP, 0x14); // 0x8D
}
sendCommand(SSD1306_MEMORYMODE, 0x00); // 0x20: memory mode(hor/ver/page) -> hor
sendCommand(SSD1306_SEGREMAP | 0x0);
//sendCommand(SSD1306_COMSCANINC); // rotate 0
sendCommand(SSD1306_COMSCANDEC); // rotate 180?
// OLD
// #if defined SSD1306_128_32
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
// sendCommand(0x02);
// sendCommand(SSD1306_SETCONTRAST); // 0x81
// sendCommand(0x8F);
// #elif defined SSD1306_128_64
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
// sendCommand(0x12);
// sendCommand(SSD1306_SETCONTRAST); // 0x81
// if (vccstate == SSD1306_EXTERNALVCC)
// { sendCommand(0x9F); }
// else
// { sendCommand(0xCF); }
// #elif defined SSD1306_96_16
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
// sendCommand(0x2); //ada x12
// sendCommand(SSD1306_SETCONTRAST); // 0x81
// if (vccstate == SSD1306_EXTERNALVCC)
// { sendCommand(0x10); }
// else
// { sendCommand(0xAF); }
// #endif
// NEW
sendCommand(SSD1306_SETCOMPINS, 0x12); // 0xDA
if (vccstate == SSD1306_EXTERNALVCC) {
sendCommand(0x9F);
} else {
sendCommand(0xCF);
}
if (vccstate == SSD1306_EXTERNALVCC) {
sendCommand(SSD1306_SETPRECHARGE, 0x22); // 0xd9
} else {
sendCommand(SSD1306_SETPRECHARGE, 0xF1); // 0xd9
}
sendCommand(SSD1306_SETVCOMDETECT, 0x40); // 0xDB
sendCommand(SSD1306_DISPLAYALLON_RESUME); // 0xA4
sendCommand(SSD1306_NORMALDISPLAY); // 0xA6
sendCommand(SSD1306_DEACTIVATE_SCROLL);
sendCommand(SSD1306_DISPLAYON); //--turn on oled panel
}
private:
void sendCommand(uint8_t cmd) {
bool ok;
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n");}
ok = i2c.writeByteAndCheck(0x00); // command
if (!ok) {os_printf("failed command mode\n");}
ok = i2c.writeByteAndCheck(cmd);
if (!ok) {os_printf("failed command\n");}
i2c.stop();
}
void sendCommand(uint8_t cmd, uint8_t v1) {
sendCommand(cmd);
sendCommand(v1);
}
void sendCommand(uint8_t cmd, uint8_t v1, uint8_t v2) {
sendCommand(cmd);
sendCommand(v1);
sendCommand(v2);
}
void sendCommand2(uint8_t cmd, uint8_t v1) {
i2c.startWrite(ADDR7);
i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(cmd);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v1);
i2c.stop();
}
void sendCommand2(uint8_t cmd, uint8_t v1, uint8_t v2) {
i2c.startWrite(ADDR7);
i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(cmd);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v1);
//i2c.writeByteAndCheck(0x00);
i2c.writeByteAndCheck(v2);
i2c.stop();
}
};
#endif

98
ext/sens/AHT2x.h Normal file
View File

@@ -0,0 +1,98 @@
#pragma once
/**
* humidity and temperature sensor
* https://asairsensors.com/wp-content/uploads/2021/09/Data-Sheet-AHT21-Humidity-and-Temperature-Sensor-ASAIR-V1.0.03.pdf
*/
template <typename I2C> class AHT2x {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0x38;
static constexpr const char* NAME = "AHT2x";
static constexpr const uint8_t BIT_BUSY = 0x80;
static constexpr const uint8_t BIT_CALIBRATED = 0x08;
public:
struct Result {
float temp;
float humi;
};
public:
AHT2x(I2C& i2c) : i2c(i2c) {
}
void init() {
softReset();
int ok = calibrate();
printf("aht calib: %d\n", ok);
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
void softReset() {
uint8_t cmd = 0xBA;
i2c.writeRaw(ADDR, 1, &cmd);
DELAY_MS(100);
}
bool calibrate() {
uint8_t cmdCalibrate[3] = {0xBE, 0x08, 0x00};
i2c.writeRaw(ADDR, 3, cmdCalibrate);
waitUntilDone();
return readStatus() & BIT_CALIBRATED;
}
void waitUntilDone() {
for (uint8_t i = 0; i < 200; ++i) {
printf(".");
if (!(readStatus() & BIT_BUSY)) {break;}
DELAY_MS(1);
}
printf("x\n");
}
uint8_t readStatus() {
uint8_t status = 0;
i2c.readRaw(ADDR, 1, &status);
return status;
}
Result measure() {
// trigger measurement
uint8_t cmdMeasure[3] = {0xAC, 0x33, 0x00};
i2c.writeRaw(ADDR, 3, cmdMeasure);
// fetch result, also waits until the busy-bit is cleared
uint8_t raw[6];
for(uint8_t i = 0; i < 50; ++i) {
DELAY_MS(10);
i2c.readRaw(ADDR, 6, raw);
bool busy = (raw[0] & BIT_BUSY);
if (!busy) {break;}
}
// calculate
Result res;
uint32_t _humi = ((raw[1] << 16) | (raw[2] << 8) | (raw[3] << 0)) >> 4;
res.humi = _humi * 100 / 1048576.0f;
uint32_t _temp = ((raw[3] & 0x0F) << 16) | (raw[4] << 8) | (raw[5] << 0);
res.temp = (_temp * 200 / 1048576.0f) - 50;
return res;
}
};

View File

@@ -4,14 +4,28 @@
#include "../../Platforms.h" #include "../../Platforms.h"
#include "../../Debug.h" #include "../../Debug.h"
// https://www.mouser.com/datasheet/2/783/BST-BME280-DS002-1509607.pdf
template <typename I2C> class BME280 { template <typename I2C> class BME280 {
I2C& i2c;
static constexpr const char* NAME = "BME280"; static constexpr const char* NAME = "BME280";
static constexpr uint8_t ADDR7 = 0b1110110; static constexpr uint8_t ADDR7_1 = 0b1110110; // 0x76
static constexpr uint8_t ADDR7_2 = 0b1110111; // 0x77
static constexpr uint8_t MODE_SLEEP = 0b00;
static constexpr uint8_t MODE_FORCED = 0b01; // manual sampling
static constexpr uint8_t MODE_NORMAL = 0b11; // periodic background sampling
uint8_t ADDR7;
static constexpr uint8_t REG_CTRL1 = 0xF2; // humidity static constexpr uint8_t REG_CTRL1 = 0xF2; // humidity
static constexpr uint8_t REG_CTRL2 = 0xF4; // temp, pressure, mode static constexpr uint8_t REG_CTRL2 = 0xF4; // temp, pressure, mode
static constexpr uint8_t REG_CONFIG = 0xF5;
static constexpr uint8_t REG_STATUS = 0xF3; static constexpr uint8_t REG_STATUS = 0xF3;
static constexpr uint8_t REG_PRESSURE = 0xF7; static constexpr uint8_t REG_PRESSURE = 0xF7;
@@ -22,9 +36,6 @@ template <typename I2C> class BME280 {
static constexpr uint8_t REG_DIG_T2 = 0x8A; static constexpr uint8_t REG_DIG_T2 = 0x8A;
static constexpr uint8_t REG_DIG_T3 = 0x8C; static constexpr uint8_t REG_DIG_T3 = 0x8C;
public:
bool started = false; bool started = false;
/** internal sensor calibration values */ /** internal sensor calibration values */
@@ -53,23 +64,140 @@ public:
} cal; } cal;
public:
I2C& i2c; struct Result {
float temp;
float humi;
float pres;
};
BME280(I2C& i2c) : i2c(i2c) { enum class Interval : uint8_t {
INT_500_US = 0b000,
INT_62_MS = 0b001,
INT_125_MS = 0b010,
INT_250_MS = 0b011,
INT_500_MS = 0b100,
INT_1000_MS = 0b101,
INT_10_MS = 0b110,
INT_20_MS = 0b111,
};
enum class Oversample : uint8_t {
X1 = 0b001,
X2 = 0b010,
X4 = 0b011,
X8 = 0b100,
X16 = 0b101,
};
private:
struct Config {
Oversample temp = Oversample::X2;
Oversample pres = Oversample::X16;
Oversample humi = Oversample::X2;
uint8_t mode = MODE_NORMAL;
Interval interval = Interval::INT_500_MS;
uint8_t fir = 0b000; // fir filter disabled
} cfg;
public:
BME280(I2C& i2c, uint8_t addrOffset = 0) : i2c(i2c), ADDR7(ADDR7_1 + addrOffset) {
} }
bool isPresent() { bool isPresent() {
return i2c.query(ADDR7); return i2c.query(ADDR7);
} }
void init() {
readCalib();
}
void setSampling(Oversample temp, Oversample pres, Oversample humi) {
cfg.temp = temp;
cfg.pres = pres;
cfg.humi = humi;
}
uint8_t getStatus() {
uint8_t res[1];
i2c.readReg(ADDR7, REG_STATUS, 1, res);
return 0;
}
/** start periodic background measurement (tends to sensor-self-heating??) */
void measurePeriodic(Interval ival) {
cfg.mode = MODE_NORMAL;
cfg.interval = ival;
commitConfig();
}
/** measure only once, takes some time before NEW results are present (seems more stable in terms of temperature) */
void measureOnce() {
cfg.mode = MODE_FORCED;
commitConfig();
}
/** get the most recent readings */
Result getAll() {
Result res;
res.temp = getTemperature();
res.humi = getHumidity();
res.pres = getPressure();
return res;
}
/** get most recent pressure reading (hPa) */
float getPressure() {
uint8_t res[3];
i2c.readReg(ADDR7, REG_PRESSURE, 3, res);
//os_printf("res: %d - %d - %d \n", res[0], res[1], res[2]);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const uint32_t pres = BME280_compensate_P_int64(tmp);
const float presF = pres / 256.0f / 100.0f; // convert from Q24.8 to float and from Pa to hPa
//const uint32_t p0 = pres / 256;
//const uint32_t p1 = (uint32_t) presF;
//const uint32_t p2 = (presF - p1) * 100000;
//Log::addInfo((NAME, "[pres] ADC: %d -> %d Pa | %d.%d hPa", tmp, p0, p1,p2);
return presF;
}
/** get most recent temperature reading */
float getTemperature() {
uint8_t res[3];
i2c.readReg(ADDR7, REG_TEMPERATURE, 3, res);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const int32_t temp = BME280_compensate_T_int32(tmp);
const float tempF = temp / 100.0f;
return tempF;
}
/** get the most recent humidity reading */
float getHumidity() {
uint8_t res[2];
i2c.readReg(ADDR7, REG_HUMIDITY, 2, res);
//os_printf("res: %d - %d \n", res[0], res[1]);
const uint32_t tmp = (res[0] << 8) | (res[1] << 0);
const int32_t humi = bme280_compensate_H_int32(tmp);
const float humiF = humi / 1024.0f;
//const uint16_t h0 = humi / 1024;
//const uint16_t h1 = (uint16_t) humiF;
//const uint16_t h2 = (humiF - humi) * 10000;
//Log::addInfo((NAME, "[humi] ADC: %d -> %d -> %d.%d %%", tmp, h0, h1,h2);
return humiF;
}
private: private:
void readCalib() { void readCalib() {
debugMod(NAME, "readCalib()"); Log::addInfo(NAME, "readCalib()");
// read all 24 calibration bytes for temperature and pressure // read all 24 calibration bytes for temperature and pressure
uint8_t b1[24]; uint8_t b1[24];
@@ -93,137 +221,33 @@ private:
i2c.readReg(ADDR7, 0xA1, 1, &cal.dig_H1); i2c.readReg(ADDR7, 0xA1, 1, &cal.dig_H1);
i2c.readReg(ADDR7, 0xE1, 7, b1); i2c.readReg(ADDR7, 0xE1, 7, b1);
cal.dig_H2 = (b1[1] << 8) | b1[0]; cal.dig_H2 = (b1[1] << 8) | b1[0];
cal.dig_H3 = b1[3]; cal.dig_H3 = b1[2];
cal.dig_H4 = (b1[3] << 4) | (b1[4] & 0b000001111); cal.dig_H4 = (b1[3] << 4) | (b1[4] & 0b00001111);
cal.dig_H5 = (b1[5] << 4) | ((b1[4] & 0b111100000) >> 4); cal.dig_H5 = (b1[5] << 4) | ((b1[4] & 0b11110000) >> 4);
cal.dig_H6 = (b1[6]); cal.dig_H6 = (b1[6]);
//os_printf("calib temp: %d %d %d\n", cal.dig_T1, cal.dig_T2, cal.dig_T3); //os_printf("calib temp: %d %d %d\n", cal.dig_T1, cal.dig_T2, cal.dig_T3);
//os_printf("calib pres: %d %d %d %d %d %d %d %d %d\n", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9); //os_printf("calib pres: %d %d %d %d %d %d %d %d %d\n", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9);
//os_printf("calib humi: %d %d %d %d %d %d\n", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6); //os_printf("calib humi: %d %d %d %d %d %d\n", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6);
//debugMod3(NAME, "calTemp: %d %d %d", cal.dig_T1, cal.dig_T2, cal.dig_T3); Log::addInfo(NAME, "calTemp: %d %d %d", cal.dig_T1, cal.dig_T2, cal.dig_T3);
//debugMod9(NAME, "calPres: %d %d %d %d %d %d %d %d %d", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9); Log::addInfo(NAME, "calPres: %d %d %d %d %d %d %d %d %d", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9);
//debugMod6(NAME, "calHumi: %d %d %d %d %d %d", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6); Log::addInfo(NAME, "calHumi: %d %d %d %d %d %d", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6);
} }
void start() { void commitConfig() {
debugMod(NAME, "start()");
const uint8_t cfgHumi = 0b101; // 16x oversampling
const uint8_t cfgPres = 0b101; // 16x oversampling
const uint8_t cfgTemp = 0b101; // 16x oversampling
const uint8_t cfgMode = 0b11;
const uint8_t cfg1 = (cfgHumi << 1);
const uint8_t cfg2 = (cfgTemp << 5) | (cfgPres << 2) | (cfgMode << 0);
i2c.writeReg(ADDR7, REG_CTRL1, 1, &cfg1);
i2c.writeReg(ADDR7, REG_CTRL2, 1, &cfg2);
}
const uint8_t ctrl1 = (uint8_t(cfg.humi) << 0);
const uint8_t ctrl2 = (uint8_t(cfg.temp) << 5) | (uint8_t(cfg.pres) << 2) | (uint8_t(cfg.mode) << 0);
const uint8_t conf = (uint8_t(cfg.interval) << 5) | (cfg.fir << 2);
i2c.writeReg8(ADDR7, REG_CTRL1, MODE_SLEEP);
public: i2c.writeReg8(ADDR7, REG_CTRL1, ctrl1);
i2c.writeReg8(ADDR7, REG_CTRL2, ctrl2);
void startOnce() { i2c.writeReg8(ADDR7, REG_CONFIG, conf);
if (started) {return;}
debugMod(NAME, "startOnce()");
readCalib();
start();
started = true;
}
uint8_t getStatus() {
uint8_t res[1];
i2c.readReg(ADDR7, REG_STATUS, 1, res);
//os_printf("Status: %d \n", res[0]);
return 0;
}
/** get current pressure in hPa */
float getPressure() {
uint8_t res[3];
i2c.readReg(ADDR7, REG_PRESSURE, 3, res);
//os_printf("res: %d - %d - %d \n", res[0], res[1], res[2]);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const uint32_t pres = BME280_compensate_P_int64(tmp);
const float presF = pres / 256.0f / 100.0f; // convert from Q24.8 to float and from Pa to hPa
//const uint32_t p0 = pres / 256;
//const uint32_t p1 = (uint32_t) presF;
//const uint32_t p2 = (presF - p1) * 100000;
//debugMod4(NAME, "[pres] ADC: %d -> %d Pa | %d.%d hPa", tmp, p0, p1,p2);
return presF;
}
float getTemperature() {
uint8_t res[3];
i2c.readReg(ADDR7, REG_TEMPERATURE, 3, res);
//os_printf("res: %d - %d - %d \n", res[0], res[1], res[2]);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const int32_t temp = BME280_compensate_T_int32(tmp);
const float tempF = temp / 100.0f;
//debugMod2(NAME, "[temp] ADC: %d -> %d", tmp, temp);
return tempF;
}
float getHumidity() {
uint8_t res[2];
i2c.readReg(ADDR7, REG_HUMIDITY, 2, res);
//os_printf("res: %d - %d \n", res[0], res[1]);
const uint32_t tmp = (res[0] << 8) | (res[1] << 0);
const int32_t humi = bme280_compensate_H_int32(tmp);
const float humiF = humi / 1024.0f;
//const uint16_t h0 = humi / 1024;
//const uint16_t h1 = (uint16_t) humiF;
//const uint16_t h2 = (humiF - humi) * 10000;
//debugMod4(NAME, "[humi] ADC: %d -> %d -> %d.%d %%", tmp, h0, h1,h2);
return humiF;
}
/*
bool readRegister(const uint8_t addr, uint8_t* dst, const uint8_t len) {
bool ok;
// address the slave in write mode and select the first register to read
ok = i2c.startWrite(ADDR7);
if (!ok) {printf("failed start write\n"); return false;}
ok = i2c.writeByteAndCheck(addr);
if (!ok) {printf("failed to select register %d\n", addr); return false;}
//i2c::stop();
// address the slave in read mode and read [len] registers
ok = i2c.startRead(ADDR7);
if (!ok) {printf("failed start read\n"); return 0;}
i2c.readBytes(dst, len);
// done
i2c.stop();
return true;
} }
bool writeRegister(const uint8_t addr, const uint8_t* src, const uint8_t len) {
bool ok;
// address the slave in write mode and select the first register to read
ok = i2c.startWrite(ADDR7);
if (!ok) {printf("failed start write\n"); return false;}
ok = i2c.writeByteAndCheck(addr);
if (!ok) {printf("failed to select register %d\n", addr); return false;}
ok = i2c.writeBytesAndCheck(src, len);
if (!ok) {printf("failed to write register contents \n"); return false;}
// done
i2c.stop();
return true;
}
*/
private:
/** conversions from ADC values to real-world values. from Bosch BMP280 manual! */ /** conversions from ADC values to real-world values. from Bosch BMP280 manual! */
using BME280_S32_t = int32_t; using BME280_S32_t = int32_t;
@@ -251,7 +275,7 @@ private:
var2 = var2 + ((var1*(BME280_S64_t)cal.dig_P5)<<17); var2 = var2 + ((var1*(BME280_S64_t)cal.dig_P5)<<17);
var2 = var2 + (((BME280_S64_t)cal.dig_P4)<<35); var2 = var2 + (((BME280_S64_t)cal.dig_P4)<<35);
var1 = ((var1 * var1 * (BME280_S64_t)cal.dig_P3)>>8) + ((var1 * (BME280_S64_t)cal.dig_P2)<<12); var1 = ((var1 * var1 * (BME280_S64_t)cal.dig_P3)>>8) + ((var1 * (BME280_S64_t)cal.dig_P2)<<12);
var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)cal.dig_P1)>>33; var1 = (((((BME280_S64_t)1l)<<47)+var1))*((BME280_S64_t)cal.dig_P1)>>33;
if (var1 == 0) {return 0;} // avoid exception caused by division by zero if (var1 == 0) {return 0;} // avoid exception caused by division by zero
p = 1048576-adc_P; p = 1048576-adc_P;
p = (((p<<31)-var2)*3125)/var1; p = (((p<<31)-var2)*3125)/var1;

74
ext/sens/CMPS10.h Normal file
View File

@@ -0,0 +1,74 @@
#pragma once
#include "../../Platforms.h"
#include "../../Debug.h"
/**
* CMPS10 3-axis magnetometer/accelerometer module
* https://www.robot-electronics.co.uk/htm/cmps10i2c.htm
*/
template <typename I2C> class CMPS10 {
I2C& i2c;
static constexpr const char* NAME = "CMPS10";
static constexpr uint8_t ADDR7 = 0xC0>>1;
static constexpr uint8_t REG_MAG_X = 10; //10+11;
static constexpr uint8_t REG_MAG_Y = 12; //12+13;
static constexpr uint8_t REG_MAG_Z = 14; //14+15;
static constexpr uint8_t REG_ACC_X = 16; //16+17;
static constexpr uint8_t REG_ACC_Y = 18; //18+19;
static constexpr uint8_t REG_ACC_Z = 20; //20+21;
public:
struct Magnetometer {
int16_t x;
int16_t y;
int16_t z;
};
struct Acceleromter {
int16_t x;
int16_t y;
int16_t z;
};
public:
CMPS10(I2C& i2c, uint8_t addrOffset = 0) : i2c(i2c){
}
bool isPresent() {
return i2c.query(ADDR7);
}
Magnetometer getMagnetometer() {
uint8_t res[6];
i2c.readReg(ADDR7, REG_MAG_X, 6, res);
Magnetometer mag;
mag.x = ((res[0] << 8) | (res[1] << 0));
mag.y = ((res[2] << 8) | (res[3] << 0));
mag.z = ((res[4] << 8) | (res[5] << 0));
return mag;
}
Acceleromter getAcceleromter() {
uint8_t res[6];
i2c.readReg(ADDR7, REG_ACC_X, 6, res);
Acceleromter acc;
acc.x = ((res[0] << 8) | (res[1] << 0));
acc.y = ((res[2] << 8) | (res[3] << 0));
acc.z = ((res[4] << 8) | (res[5] << 0));
return acc;
}
};

146
ext/sens/ENS160.h Normal file
View File

@@ -0,0 +1,146 @@
#pragma once
/**
* a digital multi-gas sensor for indoor air quality monitoring
* https://www.sciosense.com/wp-content/uploads/documents/SC-001224-DS-7-ENS160-Datasheet.pdf
*/
template <typename I2C> class ENS160 {
private:
I2C& i2c;
static constexpr const uint8_t ADDR1 = 0x52;
static constexpr const uint8_t ADDR2 = 0x53;
uint8_t ADDR;
static constexpr const char* NAME = "ENS160";
static constexpr const uint8_t REG_PART_ID = 0x00;
static constexpr const uint8_t REG_OPMODE = 0x10;
static constexpr const uint8_t REG_TEMP_IN = 0x13;
static constexpr const uint8_t REG_RH_IN = 0x15;
static constexpr const uint8_t REG_DEVICE_STATUS = 0x20;
static constexpr const uint8_t REG_DATA_AQI = 0x21;
static constexpr const uint8_t REG_DATA_TVOC = 0x22;
static constexpr const uint8_t REG_DATA_ECO2 = 0x24;
public:
enum class Mode : uint8_t {
DEEP_SLEEP = 0x00,
IDLE = 0x01,
STANDARD = 0x02,
RESET = 0xF0,
};
union Status {
uint8_t raw;
struct {
uint8_t newgpr : 1;
uint8_t newdat : 1;
uint8_t valid : 2;
uint8_t dummy : 2;
uint8_t stater : 1;
uint8_t statas : 1;
} __attribute__((__packed__));
bool isNormal() const {return valid == 0;}
bool isWarmUp() const {return valid == 1;}
bool isStartUp() const {return valid == 2;}
bool isInvalid() const {return valid == 3;}
} __attribute__((__packed__));
union Result {
uint8_t raw[6];
struct {
Status status;
uint8_t aqi;
uint16_t tvoc;
uint16_t eco2;
} __attribute__((__packed__));
} __attribute__((__packed__));
public:
ENS160(I2C& i2c, uint8_t addr = ADDR1) : i2c(i2c), ADDR(addr) {
}
/** always 0x01 0x60 */
uint16_t getID() {
uint16_t res = 0;
i2c.readReg(ADDR, 0x00, 2, (uint8_t*)&res);
return res;
}
/** switch the mode of operation */
void setMode(Mode m) {
i2c.writeReg8(ADDR, REG_OPMODE, (uint8_t)m);
DELAY_MS(250); // not mentioned in the data-sheet but important?
}
/** set the current ambient temperature - for compensation */
void setTemp(float celsius) {
float kelvin = celsius + 273.15;
uint16_t tmp = (uint16_t) (kelvin * 64);
i2c.writeReg(ADDR, REG_TEMP_IN, 2, (uint8_t*)&tmp);
}
/** set the current ambient humidity (in %) - for compensation */
void setHumi(uint8_t humi) {
uint16_t tmp = humi * 512;
i2c.writeReg(ADDR, REG_RH_IN, 2, (uint8_t*)&tmp);
}
/** status + aqi + tvoc + eco2 */
Result getAll() {
Result res;
memset(res.raw, 0, 6);
i2c.readReg(ADDR, REG_DEVICE_STATUS, 6, res.raw);
res.status = getStatus();
//res.aqi = getAQI();
//res.tvoc = getTVOC();
//res.eco2 = getECO2();
return res;
}
Status getStatus() {
Status res;
res.raw = i2c.readReg8(ADDR, REG_DEVICE_STATUS);
return res;
}
uint8_t getAQI() {
uint8_t tmp = 0;
i2c.readReg(ADDR, REG_DATA_AQI, 1, &tmp);
return tmp & 0b111;
}
uint16_t getTVOC() {
uint16_t tmp = 0;
i2c.readReg(ADDR, REG_DATA_TVOC, 2, (uint8_t*)&tmp);
return tmp;
}
uint16_t getECO2() {
uint16_t tmp = 0;
i2c.readReg(ADDR, REG_DATA_ECO2, 2, (uint8_t*)&tmp);
return tmp;
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
};

101
ext/sens/HTU2x.h Normal file
View File

@@ -0,0 +1,101 @@
#pragma once
/**
* humidity and temperature sensor
* https://www.ttieurope.com/content/dam/tti-europe/manufacturers/te-connectivity/resources/ENG_DS_HPC199_6_A6.pdf
*
* this sensor seems to be a bit stubborn.. requiring active polling until it is finished
* just waiting some time does not seem to work
*
*/
template <typename I2C> class HTU2x {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0x40;
static constexpr const char* NAME = "HTU2x";
static constexpr const uint8_t CMD_QUERY_TEMP = 0xF3;
static constexpr const uint8_t CMD_QUERY_HUMI = 0xF5;
static constexpr const uint8_t CMD_READ_USER_REG = 0xE7;
static constexpr const uint8_t CMD_SOFT_RESET = 0xFE;
public:
HTU2x(I2C& i2c) : i2c(i2c) {
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
struct Result {
float temp;
float humi;
float humiComp;
};
/** trigger a single measurement */
Result singleMeasure() {
uint8_t tmp[3]; // 2 bytes + checksum
Result res;
sendCMD(CMD_QUERY_TEMP);
if (waitForStart()) {
i2c.readBytes(tmp, 3);
i2c.stop();
uint16_t t = ((tmp[0]<<8)|(tmp[1]<<0)) & 0xFFFC;
//printf("a: %d\n", t);
res.temp = -46.85f + 175.72 * t / float(1<<16);
}
sendCMD(CMD_QUERY_HUMI);
if (waitForStart()) {
i2c.readBytes(tmp, 3);
i2c.stop();
uint16_t h = ((tmp[0]<<8)|(tmp[1]<<0)) & 0xFFFC;
//printf("b: %d\n", h);
res.humi = -6 + 125 * h / float(1<<16);
res.humiComp = res.humi + (-0.15 * (25 - res.temp));
}
return res;
}
private:
bool waitForStart() {
for (int i = 0; i < 1024; ++i) {
if (i2c.startRead(ADDR)) {return true;}
}
return false;
}
void sendCMD(uint8_t cmd) {
i2c.writeRaw(ADDR, 1, &cmd);
}
void readUserRegister() {
i2c.writeRaw(ADDR, 1, &CMD_SOFT_RESET);
vTaskDelay(100 / portTICK_PERIOD_MS);
uint8_t val = 0xaa;
i2c.readReg(ADDR, CMD_READ_USER_REG, 1, &val);
printf("user: %d\n", val);
}
};

123
ext/sens/LIS3MDL.h Normal file
View File

@@ -0,0 +1,123 @@
#pragma once
#include "../../Platforms.h"
#include "../../Debug.h"
/**
* LIS3MDL 3-axis magnetometer module
* https://www.st.com/resource/en/datasheet/lis3mdl.pdf
*/
template <typename I2C> class LIS3MDL {
I2C& i2c;
static constexpr const char* NAME = "LIS3MDL";
static constexpr uint8_t ADDR7 = 0b0011100;
static constexpr uint8_t CTRL_REG1 = 0x20;
static constexpr uint8_t CTRL_REG2 = 0x21;
static constexpr uint8_t CTRL_REG3 = 0x22;
static constexpr uint8_t CTRL_REG4 = 0x23;
static constexpr uint8_t CTRL_REG5 = 0x24;
static constexpr uint8_t REG_X = 0x28; //0x28(L= + 0x29(H)
static constexpr uint8_t REG_Y = 0x2A; //0x2A(L) + 0x2B(H)
static constexpr uint8_t REG_Z = 0x2C; //0x2C(L) + 0x2D(H)
public:
struct Magnetometer {
int16_t x;
int16_t y;
int16_t z;
};
struct Acceleromter {
int16_t x;
int16_t y;
int16_t z;
};
enum class Resolution : uint8_t {
GAUSS_4 = 0b00,
GAUSS_8 = 0b01,
GAUSS_12 = 0b10,
GAUSS_16 = 0b11,
};
enum class AxisMode : uint8_t {
LOW_POWER = 0b00,
MEDIUM_PERFORMANCE = 0b01,
HIGH_PERFORMANCE = 0b10,
ULTRA_HIGH_PERFORMANCE = 0b11,
};
enum class SamplingRate : uint8_t {
HZ_0_625,
HZ_1_25,
HZ_2_5,
HZ_5,
HZ_10,
HZ_20,
HZ_40,
HZ_80,
};
enum class OperationMode : uint8_t {
CONTINUOUS = 0b00,
SINGLE = 0b01,
OFF = 0b11,
};
public:
LIS3MDL(I2C& i2c, uint8_t addrOffset = 0) : i2c(i2c){
}
bool isPresent() {
return i2c.query(ADDR7);
}
void setResolution(Resolution res) {
getAndSet(CTRL_REG2, 0b01100000, (uint8_t)res << 5);
}
void setAxisMode(AxisMode mode) {
getAndSet(CTRL_REG1, 0b01100000, (uint8_t)mode << 5); // x and y
getAndSet(CTRL_REG4, 0b00001100, (uint8_t)mode << 2); // z
}
void setSamplingRate(SamplingRate rate) {
getAndSet(CTRL_REG1, 0b00011100, (uint8_t)rate << 2);
}
void setOperationMode(OperationMode mode) {
getAndSet(CTRL_REG3, 0b00000011, (uint8_t)mode << 0);
}
Magnetometer getMagnetometer() {
uint8_t res[6];
i2c.readReg(ADDR7, REG_X, 6, res);
Magnetometer mag;
mag.x = ((res[0] << 0) | (res[1] << 8));
mag.y = ((res[2] << 0) | (res[3] << 8));
mag.z = ((res[4] << 0) | (res[5] << 8));
return mag;
}
void getAndSet(uint8_t reg, uint8_t setMask, uint8_t setVal) {
uint8_t tmp = i2c.readReg8(ADDR7, reg);
tmp = (tmp & ~setMask) | setVal;
i2c.writeReg8(ADDR7, reg, tmp);
}
};

109
ext/sens/SGP30.h Normal file
View File

@@ -0,0 +1,109 @@
#pragma once
/**
* air quality sensor
* https://sensirion.com/media/documents/984E0DD5/61644B8B/Sensirion_Gas_Sensors_Datasheet_SGP30.pdf
*/
template <typename I2C> class SGP30 {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0x58;
static constexpr const char* NAME = "SGP30";
static constexpr const uint16_t CMD_IAQ_INIT = 0x2003;
static constexpr const uint16_t CMD_IAQ_MEASURE = 0x2008;
static constexpr const uint16_t CMD_GET_SERIAL = 0x3682;
public:
SGP30(I2C& i2c) : i2c(i2c) {
}
void init() {
sendCommand(CMD_IAQ_INIT);
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
struct Result {
uint16_t co2e;
uint16_t tvoc;
};
/** should be called ~ every second */
Result measure() {
sendCommand(CMD_IAQ_MEASURE);
vTaskDelay(100 / portTICK_PERIOD_MS);
uint8_t tmp[6];
i2c.readRaw(ADDR, 6, tmp);
Result res;
res.co2e = (tmp[0]<<8) | (tmp[1]<<0);
res.tvoc = (tmp[3]<<8) | (tmp[4]<<0);
return res;
}
void getSerial() {
struct Serial {
uint8_t v1[2];
uint8_t crc1;
uint8_t v2[2];
uint8_t crc2;
uint8_t v3[2];
uint8_t crc3;
} serial;
sendCommand(CMD_GET_SERIAL);
uint8_t tmp[9];
i2c.readRaw(ADDR, 9, &serial);
/*
uint8_t a = calcCRC(tmp+0, 2);
uint8_t b = calcCRC(tmp+3, 2);
uint8_t c = calcCRC(tmp+6, 2);
printf("%d %d %d %d\n", tmp[0], tmp[1], tmp[2], a);
printf("%d %d %d %d\n", tmp[3], tmp[4], tmp[5], b);
printf("%d %d %d %d\n", tmp[6], tmp[7], tmp[8], c);
*/
}
private:
void sendCommand(uint16_t cmd) {
uint8_t tmp[2];
tmp[0] = cmd >> 8;
tmp[1] = cmd >> 0;
i2c.writeRaw(ADDR, 2, tmp);
}
static uint8_t calcCRC(const uint8_t* data, uint8_t len) {
uint8_t crc = 0xff;
for (uint8_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if ((crc & 0x80) != 0) {
crc = (uint8_t)((crc << 1) ^ 0x31);
} else {
crc <<= 1;
}
}
}
return crc;
}
};

93
ext/sens/SHT3x.h Normal file
View File

@@ -0,0 +1,93 @@
#pragma once
/**
* humidity and temperature sensor
* https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf
*
* sensor seems to be really good! and very easy to use!
*
*/
template <typename I2C> class SHT3x {
private:
I2C& i2c;
static constexpr const uint8_t ADDR = 0x44;
static constexpr const char* NAME = "SHT3x";
public:
SHT3x(I2C& i2c) : i2c(i2c) {
}
/** is the device present on the bus? */
bool isPresent() {
return i2c.query(ADDR);
}
struct Result {
float temp;
float humi;
};
/** trigger a single measurement */
Result singleMeasure() {
uint16_t cmd = 0x2400; // high quality, no clock stretching
sendCommand(cmd);
vTaskDelay(100 / portTICK_PERIOD_MS);
return readResult();
}
void startPeriodicMeasure() {
uint16_t cmd = 0x2130; // high quality, 1 measurement per second
sendCommand(cmd);
}
Result getLastResult() {
return readResult();
}
private:
Result readResult() {
uint8_t tmp[6];
i2c.readRaw(ADDR, 6, (uint8_t*)&tmp);
Result res;
res.temp = -45 + 175 * ((tmp[0]<<8) | (tmp[1]<<0)) / float((1<<16)-1);
res.humi = 100 * ((tmp[3]<<8) | (tmp[4]<<0)) / float((1<<16)-1);
return res;
}
void sendCommand(uint16_t cmd) {
uint8_t tmp[2];
tmp[0] = cmd >> 8;
tmp[1] = cmd >> 0;
i2c.writeRaw(ADDR, 2, tmp);
}
static uint8_t calcCRC(const uint8_t* data, uint8_t len) {
uint8_t crc = 0xff;
for (uint8_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if ((crc & 0x80) != 0) {
crc = (uint8_t)((crc << 1) ^ 0x31);
} else {
crc <<= 1;
}
}
}
return crc;
}
};

View File

@@ -100,6 +100,7 @@
#include "driver/gpio.h" #include "driver/gpio.h"
#include "esp8266/gpio_struct.h" #include "esp8266/gpio_struct.h"
struct MyGPIO { struct MyGPIO {
static inline bool get(const uint8_t num) { static inline bool get(const uint8_t num) {
@@ -166,6 +167,11 @@
ESP_ERROR_CHECK(gpio_config(&io_conf)); ESP_ERROR_CHECK(gpio_config(&io_conf));
} }
static void setBuiltInLED(bool on) {
setOutput(GPIO_NUM_2);
if (on) {clear(GPIO_NUM_2);} else {set(GPIO_NUM_2);}
}
static void toggleBuiltInLED() { static void toggleBuiltInLED() {
static bool level = false; static bool level = false;
setOutput(GPIO_NUM_2); setOutput(GPIO_NUM_2);
@@ -179,6 +185,7 @@
#elif IS_ESP32 #elif IS_ESP32
#include "driver/gpio.h" #include "driver/gpio.h"
#include "soc/gpio_reg.h"
// NOTE from the manual // NOTE from the manual
// GPIO 6-11 are usually used for SPI flash. // GPIO 6-11 are usually used for SPI flash.

View File

@@ -157,7 +157,7 @@ public:
Log::addInfo(NAME, "found %d", i); Log::addInfo(NAME, "found %d", i);
} }
waitLong(); waitLong();
if (i%16 == 0) {delay(10);} //if (i%16 == 0) {DELAY_MS(10);}
} }
} }
@@ -219,6 +219,44 @@ public:
public:
/** similar to readReg() but without actually selecting a register */
bool readRaw(const uint8_t addr, const uint8_t len, uint8_t* dst) {
bool ok;
ok = startWrite(addr);
if (!ok) {Log::addInfo(NAME, "failed start read(1)"); return false;}
stop();
ok = startRead(addr);
if (!ok) {Log::addInfo(NAME, "failed start read(2)"); return false;}
readBytes(dst, len);
stop();
return true;
}
/** similar to writeReg() but without actually selecting a register */
bool writeRaw(const uint8_t addr, const uint8_t len, const uint8_t* src) {
bool ok;
// address the slave in write mode and select the first register to read
ok = startWrite(addr);
if (!ok) {Log::addInfo(NAME, "failed start write"); return false;}
ok = writeBytesAndCheck(src, len);
if (!ok) {Log::addInfo(NAME, "failed to write register contents"); return false;}
stop();
return true;
}

View File

@@ -18,6 +18,8 @@
struct FontBuilder { struct FontBuilder {
uint8_t spaceBetween = 1;
/** resulting font */ /** resulting font */
struct Result { struct Result {
@@ -33,6 +35,8 @@ struct FontBuilder {
void dump(const char* name) const { void dump(const char* name) const {
std::cout << "#include <ESP8266lib/ext/lcd/Draw.h>" << std::endl;
std::cout << "static const uint8_t " << name << "_data[] = {"; std::cout << "static const uint8_t " << name << "_data[] = {";
for (uint8_t i : data) { for (uint8_t i : data) {
std::cout << (int) i << ","; std::cout << (int) i << ",";
@@ -76,6 +80,10 @@ struct FontBuilder {
} }
void setSpaceBetween(uint8_t space) {
this->spaceBetween = space;
}
void addDummy() { void addDummy() {
// update // update
res.offsets.push_back(curX); res.offsets.push_back(curX);
@@ -202,7 +210,7 @@ struct FontBuilder {
std::cout << " " << c << " : " << rect.width() << " cur: " << curX << std::endl; std::cout << " " << c << " : " << rect.width() << " cur: " << curX << std::endl;
p.drawText(curX+drawOffsetX, atHeight, str); p.drawText(curX+drawOffsetX, atHeight, str);
curX += std::ceil(rect.width()) + 1; // 1 pixel space between chars curX += std::ceil(rect.width()) + spaceBetween; // 1 pixel space between chars
} }
p.end(); p.end();

View File

@@ -4,7 +4,7 @@
#include <QImage> #include <QImage>
#include <QFontDatabase> #include <QFontDatabase>
#include <ESP8266lib/ext/lcd/Draw.h> #include "../../ext/lcd/Draw.h"
#include <iostream> #include <iostream>
#include <FontBuilder.h> #include <FontBuilder.h>
@@ -26,13 +26,13 @@ MainWindow::~MainWindow() {
void MainWindow::paintEvent(QPaintEvent* e) { void MainWindow::paintEvent(QPaintEvent* e) {
QString fontPath="/apps/ESP8266lib/tools/PixelFontGen/fonts/"; QString fontPath="/storage/vm/workspace/house/ESP8266lib/tools/PixelFontGen/fonts/";
//FontBuilder::Result res = fb.build("/apps/esp/test/04B_03__.TTF"); //FontBuilder::Result res = fb.build("/apps/esp/test/04B_03__.TTF");
//FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/PixelOperator.ttf", 16, 9, 32, 126); //FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/PixelOperator.ttf", 16, 9, 32, 126);
//FontBuilder fb(8); fb.addChars("/apps/esp/PixelFont/04B_03__.TTF", 8, 6, 32, 126); // OK //FontBuilder fb(8); fb.addChars("/apps/esp/PixelFont/04B_03__.TTF", 8, 6, 32, 126); // OK
//FontBuilder fb(8); fb.addChars("/apps/esp/PixelFont/Minecraft.ttf", 7.5, 6, 32, 126); // ugly //FontBuilder fb(8); fb.addChars("/apps/esp/PixelFont/Minecraft.ttf", 7.5, 6, 32, 126); // ugly
//FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/EnterCommand.ttf", 15, 8, 32, 126); //FontBuilder fb(10); fb.addChars(fontPath+"/EnterCommand.ttf", 15, 8, 32, 126);
//FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/PIXELADE.TTF", 13, 8, 32, 126); //FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/PIXELADE.TTF", 13, 8, 32, 126);
//FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/C&C Red Alert [LAN].ttf", 110, 8, 32, 126); // ugly //FontBuilder fb(10); fb.addChars("/apps/esp/PixelFont/C&C Red Alert [LAN].ttf", 110, 8, 32, 126); // ugly
//FontBuilder fb(11); fb.addChars("/apps/esp/PixelFont/LeviWindows.ttf", 21, 9, 32, 126); //FontBuilder fb(11); fb.addChars("/apps/esp/PixelFont/LeviWindows.ttf", 21, 9, 32, 126);
@@ -51,8 +51,24 @@ void MainWindow::paintEvent(QPaintEvent* e) {
//FontBuilder fb(7); fb.addChars(fontPath+"/RNTG Larger.ttf", 7, 7, 32, 126, [](char c, QRect& r) {if(c=='1'){r.setX(0); r.setWidth(5);}}); //FontBuilder fb(7); fb.addChars(fontPath+"/RNTG Larger.ttf", 7, 7, 32, 126, [](char c, QRect& r) {if(c=='1'){r.setX(0); r.setWidth(5);}});
//FontBuilder fb(8); fb.addChars(fontPath+"/Bonni-Africa.ttf", 8, 7, 32, 126); //FontBuilder fb(8); fb.addChars(fontPath+"/Bonni-Africa.ttf", 8, 7, 32, 126);
//FontBuilder fb(14); fb.addChars(fontPath+"/rainyhearts.ttf", 16, 11, 32, 126);
//FontBuilder fb(16); fb.addChars(fontPath+"/Pixellari.ttf", 16, 7, 32, 126);
//FontBuilder fb(13); fb.addChars(fontPath+"/PixelOperator.ttf", 16, 10, 32, 126);
//FontBuilder fb(16); fb.setSpaceBetween(2); fb.addChars(fontPath+"/gameovercre1.ttf", 16, 12, 32, 126);
FontBuilder fb(13); fb.setSpaceBetween(2); fb.addChars(fontPath+"/monaco.ttf", 16, 11, 32, 126);
//FontBuilder fb(16); fb.addChars(fontPath+"/VCR_OSD_MONO_1.001.ttf", 21, 17, 32, 126);
//FontBuilder fb(8); fb.addCharsMonoFromImage("/apps/esp/PixelFont/res/fnt1.png", 3, 32, 126); //FontBuilder fb(8); fb.addCharsMonoFromImage("/apps/esp/PixelFont/res/fnt1.png", 3, 32, 126);
/*
// test for icons // test for icons
FontBuilder fb(9); FontBuilder fb(9);
// for (int i = 0; i < 10; ++i) { // for (int i = 0; i < 10; ++i) {
@@ -62,10 +78,11 @@ void MainWindow::paintEvent(QPaintEvent* e) {
fb.addIcon("/apps/esp32/BoatRemote/icon/boat.svg", 12, 9, 0); fb.addIcon("/apps/esp32/BoatRemote/icon/boat.svg", 12, 9, 0);
fb.addDummy(); fb.addDummy();
// } // }
*/
const FontBuilder::Result& res = fb.get(); const FontBuilder::Result& res = fb.get();
//res.dump("f1"); //res.dump("f1");
res.dump("fIcon"); res.dump("f1");

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.1, 2020-07-08T21:18:06. --> <!-- Written by QtCreator 6.0.0, 2022-07-27T20:40:33. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
<value type="QByteArray">{662356ad-536e-4e17-8869-ff649e71cb1a}</value> <value type="QByteArray">{09bd03a1-b3d4-445c-b477-faca8ef547ef}</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.ActiveTarget</variable> <variable>ProjectExplorer.Project.ActiveTarget</variable>
@@ -37,6 +37,7 @@
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value> <value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
@@ -45,20 +46,38 @@
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value> <value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> <value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
</valuemap> </valuemap>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.PluginSettings</variable> <variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value>
<valuemap type="QVariantMap" key="ClangTools"> <valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">4</value> <value type="int" key="ClangTools.ParallelJobs">12</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
@@ -69,33 +88,27 @@
<data> <data>
<variable>ProjectExplorer.Project.Target.0</variable> <variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fe56f1ef-f99a-4240-b10b-b3bde6dd50d2}</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{d62f8679-f200-4a85-9392-dac2dc9931cd}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="bool">true</value>
<value type="int" key="EnableQmlDebugging">0</value> <value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
@@ -106,11 +119,7 @@
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
@@ -119,34 +128,26 @@
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="int" key="QtQuickCompiler">2</value>
<value type="int" key="SeparateDebugInfo">2</value>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="bool">true</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Release</value>
<value type="int" key="EnableQmlDebugging">2</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
@@ -157,11 +158,7 @@
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
@@ -170,34 +167,28 @@
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="int" key="QtQuickCompiler">0</value> <value type="int" key="QtQuickCompiler">0</value>
<value type="int" key="SeparateDebugInfo">2</value>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="bool">true</value>
<value type="int" key="EnableQmlDebugging">0</value> <value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Profile</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Profile</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
@@ -208,11 +199,7 @@
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
@@ -221,6 +208,8 @@
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
@@ -242,80 +231,19 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
<value type="QString">-e</value>
<value type="QString">cpu-cycles</value>
<value type="QString">--call-graph</value>
<value type="QString">dwarf,4096</value>
<value type="QString">-F</value>
<value type="QString">250</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> <valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value> <value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/apps/ESP8266lib/tools/PixelFontGen/PixelFontGen.pro</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/storage/vm/workspace/house/ESP8266lib/tools/PixelFontGen/PixelFontGen.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/apps/ESP8266lib/tools/PixelFontGen/PixelFontGen.pro</value> <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/storage/vm/workspace/house/ESP8266lib/tools/PixelFontGen/PixelFontGen.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value> <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value> <value type="QString" key="RunConfiguration.WorkingDirectory.default">/storage/vm/workspace/house/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/apps/ESP8266lib/tools/build-PixelFontGen-Desktop-Debug</value>
</valuemap> </valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap> </valuemap>

View File

@@ -1,8 +1,6 @@
#include "MainWindow.h" #include "MainWindow.h"
#include <QApplication> #include <QApplication>
#include <ESP8266lib/ext/lcd/Draw.h>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication a(argc, argv); QApplication a(argc, argv);