|
|
|
|
@@ -1,49 +1,137 @@
|
|
|
|
|
#include "display.h"
|
|
|
|
|
|
|
|
|
|
c_onScreenButton ma20("20m", (uint8_t)mA20, LocBottom);
|
|
|
|
|
c_onScreenButton ma200("200m", (uint8_t)mA200, LocBottom);
|
|
|
|
|
c_onScreenButton ma1000("1A", (uint8_t)mA1000, LocBottom);
|
|
|
|
|
c_onScreenButton mauto("Auto", (uint8_t)mAuto, LocBottom);
|
|
|
|
|
c_onScreenButton bsetup("Conf", 5, LocBottom);
|
|
|
|
|
c_onScreenButton errorState("ER", 6, LocRight, &getErrorState);
|
|
|
|
|
c_onScreenButton okState("OK", 7, LocRight, &getOkState);
|
|
|
|
|
c_onScreenButton openState("Open", 8, LocRight, &getOpenState);
|
|
|
|
|
c_onScreenButton wifiState("Wifi", 9, LocRight, &getWifiState);
|
|
|
|
|
|
|
|
|
|
#ifdef HAS_SSD1306
|
|
|
|
|
SSD1306Wire display(0x3c, SDA_OLED, SCL_OLED, RST_OLED, GEOMETRY_128_64);
|
|
|
|
|
std::vector<c_onScreenButton> MainScreen;
|
|
|
|
|
|
|
|
|
|
OLEDDisplayUi ui(&display);
|
|
|
|
|
displayState displaystate = mainscreen;
|
|
|
|
|
bool stateMutex = true;
|
|
|
|
|
#ifdef HAS_SSD1322
|
|
|
|
|
|
|
|
|
|
String measureModes[4] = {"20mA", "200mA", "1000mA", "Auto"};
|
|
|
|
|
uint8_t measureModePos[4] = {2, 34, 66, 98};
|
|
|
|
|
uint8_t measureModeCenter[4] = {16, 48, 80, 112};
|
|
|
|
|
#define FONT8 u8g2_font_helvR08_tf
|
|
|
|
|
#define FONT16 u8g2_font_7x14_tf
|
|
|
|
|
#define FONT24 u8g2_font_freedoomr25_tn //u8g2_font_logisoso24_tf
|
|
|
|
|
|
|
|
|
|
void drawWifiSymbol(OLEDDisplay *display, OLEDDisplayUiState *state)
|
|
|
|
|
U8G2_SSD1322_NHD_256X64_2_4W_HW_SPI display(U8G2_R0, OLED_CS, OLED_DC, OLED_RST);
|
|
|
|
|
|
|
|
|
|
void initMainScreenButtons(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
Serial.print("Init GUI: ");
|
|
|
|
|
display.setFont(FONT8);
|
|
|
|
|
uint16_t screenwidth = display.getWidth() - 1;
|
|
|
|
|
uint16_t buttonwidth = ((screenwidth / mLast) - CONTROLLOFFSET * 2) - 1;
|
|
|
|
|
uint16_t currentWidth = 0;
|
|
|
|
|
uint16_t ypos = display.getHeight() - 1 - CONTROLSLINE_H + 2;
|
|
|
|
|
|
|
|
|
|
c_displayMeasureMode ma20(mA20, 16, 32, "20m");
|
|
|
|
|
c_displayMeasureMode ma200(mA200, 48, 32, "200m");
|
|
|
|
|
c_displayMeasureMode ma1000(mA1000, 80, 32, "1A");
|
|
|
|
|
c_displayMeasureMode mauto(mAuto, 112, 32, "Auto");
|
|
|
|
|
//setup bottom buttons
|
|
|
|
|
ma20.begin(currentWidth, ypos, buttonwidth, CONTROLSLINE_H + 6, CONTROLRADIUS);
|
|
|
|
|
ma200.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
|
|
|
|
|
ma1000.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
|
|
|
|
|
mauto.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
|
|
|
|
|
bsetup.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
|
|
|
|
|
|
|
|
|
|
std::vector<c_displayMeasureMode> modes;
|
|
|
|
|
//setup right side indicators
|
|
|
|
|
uint16_t currentYpos = 0;
|
|
|
|
|
uint16_t IndicatorXpos = screenwidth - INDICATORWIDTH - (INDICATORWIDTH / 2);
|
|
|
|
|
|
|
|
|
|
void initModes(void)
|
|
|
|
|
{
|
|
|
|
|
modes.push_back(ma20);
|
|
|
|
|
modes.push_back(ma200);
|
|
|
|
|
modes.push_back(ma1000);
|
|
|
|
|
modes.push_back(mauto);
|
|
|
|
|
}
|
|
|
|
|
errorState.begin(IndicatorXpos, currentYpos, INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
|
|
|
|
|
okState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
|
|
|
|
|
openState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
|
|
|
|
|
wifiState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
|
|
|
|
|
|
|
|
|
|
void c_displayMeasureMode::drawMeasureMode(OLEDDisplay *display, measureMode mode, int16_t x, int16_t y)
|
|
|
|
|
{
|
|
|
|
|
display->setFont(ArialMT_Plain_10);
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
|
|
|
display->drawString(x + _xpos, y + CONTROLSTRIP_YPOS, _name);
|
|
|
|
|
if (mode == _mode)
|
|
|
|
|
//fill vector
|
|
|
|
|
Serial.print("Store");
|
|
|
|
|
MainScreen.push_back(ma20);
|
|
|
|
|
MainScreen.push_back(ma200);
|
|
|
|
|
MainScreen.push_back(ma1000);
|
|
|
|
|
MainScreen.push_back(mauto);
|
|
|
|
|
MainScreen.push_back(bsetup);
|
|
|
|
|
|
|
|
|
|
MainScreen.push_back(errorState);
|
|
|
|
|
MainScreen.push_back(okState);
|
|
|
|
|
MainScreen.push_back(openState);
|
|
|
|
|
MainScreen.push_back(wifiState);
|
|
|
|
|
|
|
|
|
|
for (auto &&button : MainScreen)
|
|
|
|
|
{
|
|
|
|
|
display->drawRect(x + (_xpos - (_width / 2)), y + CONTROLSLINE_YPOS, CONTROLSLINE_W, CONTROLSLINE_H);
|
|
|
|
|
button.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
Serial.println("OK");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void c_onScreenButton::begin(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint16_t radius)
|
|
|
|
|
{
|
|
|
|
|
Serial.printf("%s", _name.c_str());
|
|
|
|
|
_xpos = xpos;
|
|
|
|
|
_width = width;
|
|
|
|
|
_ypos = ypos;
|
|
|
|
|
_radius = radius;
|
|
|
|
|
_height = height;
|
|
|
|
|
|
|
|
|
|
if (_location == LocBottom)
|
|
|
|
|
{
|
|
|
|
|
Serial.print(":Calc_yTpos");
|
|
|
|
|
_yTpos = display.getHeight() - 1 - (CONTROLSLINE_H / 2) + (display.getMaxCharHeight() / 2);
|
|
|
|
|
Serial.print(":Calc_xTpos");
|
|
|
|
|
_xTpos = _xpos + (_width / 2) - (display.getStrWidth(_name.c_str()) / 2);
|
|
|
|
|
}
|
|
|
|
|
if (_location == LocRight)
|
|
|
|
|
{
|
|
|
|
|
Serial.print(":Calc_yTpos");
|
|
|
|
|
_yTpos = _ypos + display.getMaxCharHeight() - 2;
|
|
|
|
|
Serial.print(":Calc_xTpos");
|
|
|
|
|
_xTpos = _xpos + (_width / 2) - (display.getStrWidth(_name.c_str()) / 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Serial.print(":OK | ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawDashedHLine(uint16_t x, uint16_t y, uint16_t len)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < len; i+=2)
|
|
|
|
|
{
|
|
|
|
|
display.drawPixel(x+i, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawDashedVLine(uint16_t x, uint16_t y, uint16_t len)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < len; i+=2)
|
|
|
|
|
{
|
|
|
|
|
display.drawPixel(x, y+i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void c_onScreenButton::drawButton()
|
|
|
|
|
{
|
|
|
|
|
display.setFont(FONT8);
|
|
|
|
|
//Serial.printf("drawbutton:%s(x=%u, y=%u, w=%u, h=%u)\n", _name.c_str(), _xpos, _ypos, _width, _height);
|
|
|
|
|
if (!_visible)
|
|
|
|
|
{
|
|
|
|
|
//hide button
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (getState())
|
|
|
|
|
{
|
|
|
|
|
display.drawRBox(_xpos, _ypos, _width, _height, _radius);
|
|
|
|
|
display.setDrawColor(0);
|
|
|
|
|
display.drawStr(_xTpos, _yTpos, _name.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
display->fillRect(x + (_xpos - (_width / 2)), y + CONTROLSLINE_YPOS, CONTROLSLINE_W, CONTROLSLINE_H);
|
|
|
|
|
display.setDrawColor(1);
|
|
|
|
|
display.drawRFrame(_xpos, _ypos, _width, _height, _radius);
|
|
|
|
|
display.drawStr(_xTpos, _yTpos, _name.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
display.setDrawColor(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String showValue(String designator, double value, String unit)
|
|
|
|
|
@@ -59,508 +147,78 @@ String showValue(String designator, double value, String unit)
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawMeasurementValues(OLEDDisplay *display, int16_t x, int16_t y)
|
|
|
|
|
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress)
|
|
|
|
|
{
|
|
|
|
|
display->setFont(ArialMT_Plain_10);
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
|
|
|
display->drawString(x + 0, y + 0, showValue("m:", getMin(), ""));
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
|
|
|
display->drawString(x + 64, y + 0, showValue("r:", getRms(), ""));
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
|
|
|
|
display->drawString(x + 128, y + 0, showValue("m:", getMax(), ""));
|
|
|
|
|
uint16_t radius = height / 2;
|
|
|
|
|
uint16_t doubleRadius = radius << 1;
|
|
|
|
|
|
|
|
|
|
display->setFont(ArialMT_Plain_24);
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
|
|
|
display.setColorIndex(1);
|
|
|
|
|
display.drawRFrame(x, y, width, height, radius);
|
|
|
|
|
|
|
|
|
|
display->drawString(x + 64, y + 12, showValue("", getValue(), "mE"));
|
|
|
|
|
display->drawProgressBar(x + 0, y + 40, 127, 5, getBar());
|
|
|
|
|
uint16_t maxProgressWidth = (width - doubleRadius + 1) * progress / 100;
|
|
|
|
|
|
|
|
|
|
display.drawRBox(x + 1, y + 2, maxProgressWidth, height - 3, radius);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawButtons(OLEDDisplay *display, int16_t x, int16_t y)
|
|
|
|
|
void drawMeasurementValues()
|
|
|
|
|
{
|
|
|
|
|
// display.setFont(FONT16);
|
|
|
|
|
// display.drawStr(0, 12, showValue("m:", getMin(), "").c_str());
|
|
|
|
|
// display.drawStr(80, 12, showValue("r:", getRms(), "").c_str());
|
|
|
|
|
// display.drawStr(160, 12, showValue("m:", getMax(), "").c_str());
|
|
|
|
|
|
|
|
|
|
drawDashedHLine(0,12,220);
|
|
|
|
|
drawDashedVLine(40,12,33);
|
|
|
|
|
display.setFont(FONT8);
|
|
|
|
|
display.drawStr(5,8,"Fs:100Hz LP");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
display.setFont(FONT24);
|
|
|
|
|
|
|
|
|
|
display.drawStr(60, 45, showValue("", getValue(), "").c_str());
|
|
|
|
|
uint16_t stringwidth = display.getStrWidth(showValue("", getValue(), "").c_str());
|
|
|
|
|
display.setFont(u8g2_font_8x13_t_symbols);
|
|
|
|
|
display.drawUTF8(60+stringwidth+3 , 43, "mΩ");
|
|
|
|
|
//drawProgressBar(0, 40, 127, 5, getBar());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawMainSceenButtons()
|
|
|
|
|
{
|
|
|
|
|
//draw controlstrip indicators
|
|
|
|
|
measureMode currentMode = getMeasureMode();
|
|
|
|
|
|
|
|
|
|
for (auto &&thismode : modes)
|
|
|
|
|
for (auto &&thismode : MainScreen)
|
|
|
|
|
{
|
|
|
|
|
thismode.drawMeasureMode(display, currentMode, x, y);
|
|
|
|
|
thismode.setState((thismode.getIndex() == (uint8_t)getMeasureMode()));
|
|
|
|
|
thismode.drawButton();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int screenW = 128;
|
|
|
|
|
int screenH = 64;
|
|
|
|
|
int clockCenterX = screenW / 2;
|
|
|
|
|
int clockCenterY = ((screenH - 16) / 2) + 16; // top yellow part is 16 px height
|
|
|
|
|
int clockRadius = 23;
|
|
|
|
|
|
|
|
|
|
void drawMeasurementDail(OLEDDisplay *display, int16_t x, int16_t y)
|
|
|
|
|
void drawMainScreen()
|
|
|
|
|
{
|
|
|
|
|
//fit half a circle on screen
|
|
|
|
|
display->drawCircleQuads(DAILCENTERX, DAILCENTERY, DAILRADIUS + 1, 0b0011);
|
|
|
|
|
display->drawCircleQuads(DAILCENTERX, DAILCENTERY, DAILRADIUS, 0b0011);
|
|
|
|
|
drawMainSceenButtons();
|
|
|
|
|
drawMeasurementValues();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//draw outer ticks
|
|
|
|
|
for (int z = -90; z < 91; z = z + 30)
|
|
|
|
|
uint64_t lastDisplayTime = 0;
|
|
|
|
|
|
|
|
|
|
void initDisplay()
|
|
|
|
|
{
|
|
|
|
|
initMainScreenButtons();
|
|
|
|
|
display.begin();
|
|
|
|
|
display.clearBuffer();
|
|
|
|
|
lastDisplayTime = millis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleDisplay()
|
|
|
|
|
{
|
|
|
|
|
uint64_t currentmillis = millis();
|
|
|
|
|
if (currentmillis - lastDisplayTime > SCREENREFRESH)
|
|
|
|
|
{
|
|
|
|
|
//Begin at 0° and stop at 360°
|
|
|
|
|
float angle = z;
|
|
|
|
|
angle = (angle / 57.29577951); //Convert degrees to radians
|
|
|
|
|
int x2 = (DAILCENTERX + (sin(angle) * DAILRADIUS));
|
|
|
|
|
int y2 = (DAILCENTERY - (cos(angle) * DAILRADIUS));
|
|
|
|
|
int x3 = (DAILCENTERX + (sin(angle) * (DAILRADIUS - 8)));
|
|
|
|
|
int y3 = (DAILCENTERY - (cos(angle) * (DAILRADIUS - 8)));
|
|
|
|
|
display->drawLine(x2 + x, y2 + y, x3 + x, y3 + y);
|
|
|
|
|
}
|
|
|
|
|
//draw inner Ticks
|
|
|
|
|
for (int z = -75; z < 76; z = z + 30)
|
|
|
|
|
{
|
|
|
|
|
//Begin at 0° and stop at 360°
|
|
|
|
|
float angle = z;
|
|
|
|
|
angle = (angle / 57.29577951); //Convert degrees to radians
|
|
|
|
|
int x2 = (DAILCENTERX + (sin(angle) * DAILRADIUS));
|
|
|
|
|
int y2 = (DAILCENTERY - (cos(angle) * DAILRADIUS));
|
|
|
|
|
int x3 = (DAILCENTERX + (sin(angle) * (DAILRADIUS - 4)));
|
|
|
|
|
int y3 = (DAILCENTERY - (cos(angle) * (DAILRADIUS - 4)));
|
|
|
|
|
display->drawLine(x2 + x, y2 + y, x3 + x, y3 + y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// draw value
|
|
|
|
|
float angle = map(getValue(), 270, 90, 0, 100);
|
|
|
|
|
angle = (angle / 57.29577951); //Convert degrees to radians
|
|
|
|
|
int x3 = (DAILCENTERX + (sin(angle) * (DAILRADIUS - (DAILRADIUS / 5))));
|
|
|
|
|
int y3 = (DAILCENTERY - (cos(angle) * (DAILRADIUS - (DAILRADIUS / 5))));
|
|
|
|
|
display->drawLine(DAILCENTERX + x, DAILCENTERY + y, x3 + x, y3 + y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawMainScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if ((displaystate != mainscreen) && (x == 0))
|
|
|
|
|
{
|
|
|
|
|
Serial.printf("[%lu] display: DrawMainScreen\n", millis());
|
|
|
|
|
displaystate = mainscreen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drawButtons(display, x, y);
|
|
|
|
|
//drawMeasurementValues(display, x, y);
|
|
|
|
|
drawMeasurementDail(display, x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawSetupScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
|
|
|
{
|
|
|
|
|
// draw an xbm image.
|
|
|
|
|
// Please note that everything that should be transitioned
|
|
|
|
|
// needs to be drawn relative to x and y
|
|
|
|
|
display->setFont(ArialMT_Plain_16);
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
|
|
|
display->drawString(x + 64, y + 0, "Setup screen");
|
|
|
|
|
if ((displaystate != setupscreen) && (x == 0))
|
|
|
|
|
{
|
|
|
|
|
Serial.printf("[%lu] display: DrawSetupScreen\n", millis());
|
|
|
|
|
displaystate = setupscreen;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
drawMainScreen();
|
|
|
|
|
} while (display.nextPage());
|
|
|
|
|
lastDisplayTime = millis();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrameCallback frames[] = {drawMainScreen}; //, drawSetupScreen};
|
|
|
|
|
int frameCount = 1;
|
|
|
|
|
OverlayCallback overlays[] = {drawWifiSymbol};
|
|
|
|
|
int overlaysCount = 1;
|
|
|
|
|
bool displayInitDone = false;
|
|
|
|
|
|
|
|
|
|
void initDisplay(void)
|
|
|
|
|
{
|
|
|
|
|
Serial.print("Init Display: ");
|
|
|
|
|
|
|
|
|
|
initModes();
|
|
|
|
|
|
|
|
|
|
displayInitDone = true;
|
|
|
|
|
|
|
|
|
|
ui.setTargetFPS(30);
|
|
|
|
|
|
|
|
|
|
// You can change this to
|
|
|
|
|
// TOP, LEFT, BOTTOM, RIGHT
|
|
|
|
|
ui.setIndicatorPosition(BOTTOM);
|
|
|
|
|
|
|
|
|
|
// Defines where the first frame is located in the bar.
|
|
|
|
|
ui.setIndicatorDirection(LEFT_RIGHT);
|
|
|
|
|
|
|
|
|
|
// You can change the transition that is used
|
|
|
|
|
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
|
|
|
|
|
ui.setFrameAnimation(SLIDE_LEFT);
|
|
|
|
|
|
|
|
|
|
// Add frames
|
|
|
|
|
ui.setFrames(frames, frameCount);
|
|
|
|
|
|
|
|
|
|
// Add overlays
|
|
|
|
|
ui.setOverlays(overlays, overlaysCount);
|
|
|
|
|
|
|
|
|
|
ui.disableAllIndicators();
|
|
|
|
|
ui.disableAutoTransition();
|
|
|
|
|
|
|
|
|
|
// Initialising the UI will init the display too.
|
|
|
|
|
ui.init();
|
|
|
|
|
Serial.println(" OK");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleDisplay(void)
|
|
|
|
|
{
|
|
|
|
|
if (!displayInitDone)
|
|
|
|
|
return;
|
|
|
|
|
int remainingTimeBudget = ui.update();
|
|
|
|
|
|
|
|
|
|
Serial.printf("DT=%u;", remainingTimeBudget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAS_SSD1322
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ATMega32u4 pins
|
|
|
|
|
//#define OLED_DC 8 // D8 - B4
|
|
|
|
|
//#define OLED_CS 17 // D17 - B0
|
|
|
|
|
//#define OLED_RESET 9 // D9 - B5
|
|
|
|
|
|
|
|
|
|
//hardware SPI - only way to go. Can get 110 FPS
|
|
|
|
|
ESP8266_SSD1322 display(1,MOSI,OLED_DC,0, OLED_CS);
|
|
|
|
|
//int8_t SID, int8_t SDA, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS
|
|
|
|
|
|
|
|
|
|
#define NUMFLAKES 10
|
|
|
|
|
#define XPOS 0
|
|
|
|
|
#define YPOS 1
|
|
|
|
|
#define DELTAY 2
|
|
|
|
|
|
|
|
|
|
#define LOGO16_GLCD_HEIGHT 16
|
|
|
|
|
#define LOGO16_GLCD_WIDTH 16
|
|
|
|
|
static const unsigned char PROGMEM logo16_glcd_bmp[] =
|
|
|
|
|
{ B00000000, B11000000,
|
|
|
|
|
B00000001, B11000000,
|
|
|
|
|
B00000001, B11000000,
|
|
|
|
|
B00000011, B11100000,
|
|
|
|
|
B11110011, B11100000,
|
|
|
|
|
B11111110, B11111000,
|
|
|
|
|
B01111110, B11111111,
|
|
|
|
|
B00110011, B10011111,
|
|
|
|
|
B00011111, B11111100,
|
|
|
|
|
B00001101, B01110000,
|
|
|
|
|
B00011011, B10100000,
|
|
|
|
|
B00111111, B11100000,
|
|
|
|
|
B00111111, B11110000,
|
|
|
|
|
B01111100, B11110000,
|
|
|
|
|
B01110000, B01110000,
|
|
|
|
|
B00000000, B00110000 };
|
|
|
|
|
|
|
|
|
|
#if (SSD1322_LCDHEIGHT != 64)
|
|
|
|
|
#error("Height incorrect, please fix ESP8266_SSD1322.h!");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// void c_displayMeasureMode::drawMeasureMode(OLEDDisplay *display, measureMode mode, int16_t x, int16_t y)
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
|
|
|
|
|
uint8_t icons[NUMFLAKES][3];
|
|
|
|
|
|
|
|
|
|
// initialize
|
|
|
|
|
for (uint8_t f=0; f< NUMFLAKES; f++) {
|
|
|
|
|
icons[f][XPOS] = random(display.width());
|
|
|
|
|
icons[f][YPOS] = 0;
|
|
|
|
|
icons[f][DELTAY] = random(5) + 1;
|
|
|
|
|
|
|
|
|
|
Serial.print("x: ");
|
|
|
|
|
Serial.print(icons[f][XPOS], DEC);
|
|
|
|
|
Serial.print(" y: ");
|
|
|
|
|
Serial.print(icons[f][YPOS], DEC);
|
|
|
|
|
Serial.print(" dy: ");
|
|
|
|
|
Serial.println(icons[f][DELTAY], DEC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
// draw each icon
|
|
|
|
|
for (uint8_t f=0; f< NUMFLAKES; f++) {
|
|
|
|
|
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE);
|
|
|
|
|
}
|
|
|
|
|
display.display();
|
|
|
|
|
delay(200);
|
|
|
|
|
|
|
|
|
|
// then erase it + move it
|
|
|
|
|
for (uint8_t f=0; f< NUMFLAKES; f++) {
|
|
|
|
|
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK);
|
|
|
|
|
// move it
|
|
|
|
|
icons[f][YPOS] += icons[f][DELTAY];
|
|
|
|
|
// if its gone, reinit
|
|
|
|
|
if (icons[f][YPOS] > display.height()) {
|
|
|
|
|
icons[f][XPOS] = random(display.width());
|
|
|
|
|
icons[f][YPOS] = 0;
|
|
|
|
|
icons[f][DELTAY] = random(5) + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void testdrawchar(void) {
|
|
|
|
|
display.setTextSize(1);
|
|
|
|
|
display.setTextColor(WHITE);
|
|
|
|
|
display.setCursor(0,0);
|
|
|
|
|
|
|
|
|
|
for (uint8_t i=0; i < 168; i++) {
|
|
|
|
|
if (i == '\n') continue;
|
|
|
|
|
display.write(i);
|
|
|
|
|
if ((i > 0) && (i % 21 == 0))
|
|
|
|
|
display.println();
|
|
|
|
|
}
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testdrawcircle(void) {
|
|
|
|
|
for (int16_t i=0; i<display.height(); i+=2) {
|
|
|
|
|
display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testfillrect(void) {
|
|
|
|
|
uint8_t color = 1;
|
|
|
|
|
for (int16_t i=0; i<display.height()/2; i+=3) {
|
|
|
|
|
// alternate colors
|
|
|
|
|
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
|
|
|
|
|
display.display();
|
|
|
|
|
color++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testdrawtriangle(void) {
|
|
|
|
|
for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
|
|
|
|
|
display.drawTriangle(display.width()/2, display.height()/2-i,
|
|
|
|
|
display.width()/2-i, display.height()/2+i,
|
|
|
|
|
display.width()/2+i, display.height()/2+i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testfilltriangle(void) {
|
|
|
|
|
uint8_t color = WHITE;
|
|
|
|
|
for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
|
|
|
|
|
display.fillTriangle(display.width()/2, display.height()/2-i,
|
|
|
|
|
display.width()/2-i, display.height()/2+i,
|
|
|
|
|
display.width()/2+i, display.height()/2+i, WHITE);
|
|
|
|
|
if (color == WHITE) color = BLACK;
|
|
|
|
|
else color = WHITE;
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testdrawroundrect(void) {
|
|
|
|
|
for (int16_t i=0; i<display.height()/2-2; i+=2) {
|
|
|
|
|
display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testfillroundrect(void) {
|
|
|
|
|
uint8_t color = WHITE;
|
|
|
|
|
for (int16_t i=0; i<display.height()/2-2; i+=2) {
|
|
|
|
|
display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
|
|
|
|
|
if (color == WHITE) color = BLACK;
|
|
|
|
|
else color = WHITE;
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testdrawrect(void) {
|
|
|
|
|
for (int16_t i=0; i<display.height()/2; i+=2) {
|
|
|
|
|
display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testdrawline() {
|
|
|
|
|
for (int16_t i=0; i<display.width(); i+=4) {
|
|
|
|
|
display.drawLine(0, 0, i, display.height()-1, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
for (int16_t i=0; i<display.height(); i+=4) {
|
|
|
|
|
display.drawLine(0, 0, display.width()-1, i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
delay(250);
|
|
|
|
|
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
for (int16_t i=0; i<display.width(); i+=4) {
|
|
|
|
|
display.drawLine(0, display.height()-1, i, 0, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
for (int16_t i=display.height()-1; i>=0; i-=4) {
|
|
|
|
|
display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
delay(250);
|
|
|
|
|
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
for (int16_t i=display.width()-1; i>=0; i-=4) {
|
|
|
|
|
display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
for (int16_t i=display.height()-1; i>=0; i-=4) {
|
|
|
|
|
display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
delay(250);
|
|
|
|
|
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
for (int16_t i=0; i<display.height(); i+=4) {
|
|
|
|
|
display.drawLine(display.width()-1, 0, 0, i, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
for (int16_t i=0; i<display.width(); i+=4) {
|
|
|
|
|
display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
}
|
|
|
|
|
delay(250);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void testscrolltext(void) {
|
|
|
|
|
display.setTextSize(2);
|
|
|
|
|
display.setTextColor(WHITE);
|
|
|
|
|
display.setCursor(10,0);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
display.println("scroll");
|
|
|
|
|
display.display();
|
|
|
|
|
|
|
|
|
|
display.startscrollright(0x00, 0x0F);
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.stopscroll();
|
|
|
|
|
delay(1000);
|
|
|
|
|
display.startscrollleft(0x00, 0x0F);
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.stopscroll();
|
|
|
|
|
delay(1000);
|
|
|
|
|
display.startscrolldiagright(0x00, 0x07);
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.startscrolldiagleft(0x00, 0x07);
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.stopscroll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initDisplay() {
|
|
|
|
|
Serial.begin(9600);
|
|
|
|
|
|
|
|
|
|
// Initialize and perform reset
|
|
|
|
|
display.begin(true);
|
|
|
|
|
// init done
|
|
|
|
|
|
|
|
|
|
// Show image buffer on the display hardware.
|
|
|
|
|
// Since the buffer is intialized with an Adafruit splashscreen
|
|
|
|
|
// internally, this will display the splashscreen.
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
|
|
|
|
|
// Clear the buffer.
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw a single pixel
|
|
|
|
|
display.drawPixel(10, 10, WHITE);
|
|
|
|
|
// Show the display buffer on the hardware.
|
|
|
|
|
// NOTE: You _must_ call display after making any drawing commands
|
|
|
|
|
// to make them visible on the display hardware!
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw many lines
|
|
|
|
|
testdrawline();
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw rectangles
|
|
|
|
|
testdrawrect();
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw multiple rectangles
|
|
|
|
|
testfillrect();
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw mulitple circles
|
|
|
|
|
testdrawcircle();
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw a white circle, 10 pixel radius
|
|
|
|
|
display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
testdrawroundrect();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
testfillroundrect();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
testdrawtriangle();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
testfilltriangle();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw the first ~12 characters in the font
|
|
|
|
|
testdrawchar();
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// draw scrolling text
|
|
|
|
|
testscrolltext();
|
|
|
|
|
delay(2000);
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
|
|
|
|
|
// text display tests
|
|
|
|
|
display.setTextSize(1);
|
|
|
|
|
display.setTextColor(WHITE);
|
|
|
|
|
display.setCursor(0,0);
|
|
|
|
|
display.println("Hello, world!");
|
|
|
|
|
display.setTextColor(BLACK, WHITE); // 'inverted' text
|
|
|
|
|
display.println(3.141592);
|
|
|
|
|
display.setTextSize(2);
|
|
|
|
|
display.setTextColor(WHITE);
|
|
|
|
|
display.print("0x"); display.println(0xDEADBEEF, HEX);
|
|
|
|
|
display.display();
|
|
|
|
|
delay(2000);
|
|
|
|
|
|
|
|
|
|
// miniature bitmap display
|
|
|
|
|
display.clearDisplay();
|
|
|
|
|
display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
|
|
|
|
|
display.display();
|
|
|
|
|
|
|
|
|
|
// invert the display
|
|
|
|
|
display.invertDisplay(true);
|
|
|
|
|
delay(1000);
|
|
|
|
|
display.invertDisplay(false);
|
|
|
|
|
delay(1000);
|
|
|
|
|
|
|
|
|
|
// draw a bitmap icon and 'animate' movement
|
|
|
|
|
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void handleDisplay() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|