Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lolin ESP32 OLED #200

Closed
shaddow501 opened this issue Jan 14, 2018 · 18 comments
Closed

Lolin ESP32 OLED #200

shaddow501 opened this issue Jan 14, 2018 · 18 comments

Comments

@shaddow501
Copy link

Dear Luc

I am trying to add OLED support to the ESP3D and it just doesnt work.

I use an example file:

#include "images.h"

// Initialize the OLED display using SPI
// D5 -> CLK
// D7 -> MOSI (DOUT)
// D0 -> RES
// D2 -> DC
// D8 -> CS
// SSD1306Spi display(D0, D2, D8);
// or
// SH1106Spi display(D0, D2);

// Initialize the OLED display using brzo_i2c
// D3 -> SDA
// D5 -> SCL
// SSD1306Brzo display(0x3c, D3, D5);
// or
// SH1106Brzo display(0x3c, D3, D5);

// Initialize the OLED display using Wire library
SSD1306 display(0x3c, 5, 4);
// SH1106 display(0x3c, D3, D5);

#define DEMO_DURATION 3000
typedef void (*Demo)(void);

int demoMode = 0;
int counter = 1;

void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();

// Initialising the UI will init the display too.
display.init();

display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);

}

void drawFontFaceDemo() {
// Font Demo1
// create more fonts at http://oleddisplay.squix.ch/
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Hello world");
display.setFont(ArialMT_Plain_16);
display.drawString(0, 10, "Hello world");
display.setFont(ArialMT_Plain_24);
display.drawString(0, 26, "Hello world");
}

void drawTextFlowDemo() {
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawStringMaxWidth(0, 0, 128,
"Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." );
}

void drawTextAlignmentDemo() {
// Text alignment demo
display.setFont(ArialMT_Plain_10);

// The coordinates define the left starting point of the text
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 10, "Left aligned (0,10)");

// The coordinates define the center of the text
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 22, "Center aligned (64,22)");

// The coordinates define the right end of the text
display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.drawString(128, 33, "Right aligned (128,33)");
}

void drawRectDemo() {
// Draw a pixel at given position
for (int i = 0; i < 10; i++) {
display.setPixel(i, i);
display.setPixel(10 - i, i);
}
display.drawRect(12, 12, 20, 20);

// Fill the rectangle
display.fillRect(14, 14, 17, 17);

// Draw a line horizontally
display.drawHorizontalLine(0, 40, 20);

// Draw a line horizontally
display.drawVerticalLine(40, 0, 20);

}

void drawCircleDemo() {
for (int i=1; i < 8; i++) {
display.setColor(WHITE);
display.drawCircle(32, 32, i3);
if (i % 2 == 0) {
display.setColor(BLACK);
}
display.fillCircle(96, 32, 32 - i
3);
}
}

void drawProgressBarDemo() {
int progress = (counter / 5) % 100;
// draw the progress bar
display.drawProgressBar(0, 32, 120, 10, progress);

// draw the percentage as String
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 15, String(progress) + "%");
}

void drawImageDemo() {
// see http://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html
// on how to create xbm files
display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
}

Demo demos[] = {drawFontFaceDemo, drawTextFlowDemo, drawTextAlignmentDemo, drawRectDemo, drawCircleDemo, drawProgressBarDemo, drawImageDemo};
int demoLength = (sizeof(demos) / sizeof(Demo));
long timeSinceLastModeSwitch = 0;

void loop() {
// clear the display
display.clear();
// draw the current demo method
demosdemoMode;

display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.drawString(10, 128, String(millis()));
// write the buffer to the display
display.display();

if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) {
demoMode = (demoMode + 1) % demoLength;
timeSinceLastModeSwitch = millis();
}
counter++;
delay(10);
}

And with the example file the OLED on the lolin works.

I add those lines in the ESP3D.ino file:

#include "SSD1306.h"
#include "Wire.h"
SSD1306 display(0x3c, 5, 4);

And in void setup: (just to test if it works I add those lines)

display.init();
display.clear();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Hello world");

the code compile successfully but there is nothing shown in the display.

Is there anywhere in your code that you are using pins 4 & 5? is there anything in your code that can affect the OLED function?

by the way I have added those lines also in the void loop:
but still the OLED display doesnt show anything.

I am lost...

@luc-github
Copy link
Owner

Not using 5,4 pins in this github so it should not be the root cause
I just played with sample code using 2 differents display but did not integrated in ESP3D code yet - will start next week in theory
Did you tried to run a sample code just using functions you mentioned you added to see if it is working out of the official sample ?

@shaddow501
Copy link
Author

Dear Luc

With the sample code it works, When I try to integrate with your code the display stay off.

@luc-github
Copy link
Owner

I read sample works
My question was :
Do

#include "SSD1306.h"
#include "Wire.h"
SSD1306 display(0x3c, 5, 4);

void setup() {

display.init();
display.clear();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Hello world");
}

void loop() {
}

works alone ?

@shaddow501
Copy link
Author

shaddow501 commented Jan 14, 2018

Dear Luc

I have found the problem, I had to add this function "display.display();"

display.init();
display.clear();

display.flipScreenVertically();
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Hello world");
display.display();

This works.

@shaddow501
Copy link
Author

Can you tell me where is the functions that print IP to the serial exist? so I can add this to print also on the display?

@luc-github
Copy link
Owner

ESP3D/esp3d/wificonf.cpp

Lines 408 to 409 in 13ee5e1

ESP_SERIAL_OUT.print(FPSTR(M117_));
ESP_SERIAL_OUT.println(currentIP);

for first one
in command.cpp for [ESP111] command.

@shaddow501
Copy link
Author

Dear Luc

I have added the:
#include "SSD1306.h"
and:
SSD1306 display(0x3c, 5, 4);

in the ESP3D.ino file.

In the void setup I added the:
display.init();
display.clear();

display.flipScreenVertically();
display.setFont(ArialMT_Plain_16);

If I set something to print(OLED) on the loop or setup it works.
But when I add the command in wificonf.cpp
display.drawString(0, 10, ... (doesnt important)

it says that "display" is not defined in this scope.
How? I did define all in the main ESP3D.ino, so whats wrong??

@luc-github
Copy link
Owner

Each cpp is compiled individualy and so need to have all global variable information before linker do its job.
To succeed, you must add oled header or forward declaration of the SSD1306 class , and declare display variable as extern.

This is basic programming thing - you can find lot of information on google : https://www.google.fr/search?q=share+variable+in+several+file+arduino

@shaddow501
Copy link
Author

Dear Luc

  1. In the esped.ino I have added "oled.h" file
    in the oled.h file I added 2 lines:
    #include "SSD1306.h"
    SSD1306 display(0x3c, 5, 4);

  2. In the wificonf.cpp I have added:
    #include "SSD1306.h"
    extern SSD1306 display;

  3.  //Get IP
    

    if (WiFi.getMode()==WIFI_STA) {
    currentIP=WiFi.localIP();
    currentIP_string=WiFi.localIP().toString();
    } else {
    currentIP=WiFi.softAPIP();
    currentIP_string=WiFi.softAPIP().toString();
    }
    ESP_SERIAL_OUT.print(FPSTR(M117_));
    ESP_SERIAL_OUT.println(currentIP);
    display.clear();
    display.flipScreenVertically();
    display.setFont(ArialMT_Plain_16);
    display.drawString(0, 3, "ESP3D IP:");
    display.drawString(0, 20, String (currentIP_string));
    display.setTextAlignment(TEXT_ALIGN_RIGHT);
    // write the buffer to the display
    display.display();

After that I get the IP address correctly on the OLED display.

Where can I find the place that it show the wifi signal?

@shaddow501
Copy link
Author

Dear Luc

I have encounter with resets on ESP32 I have found a solution in here:

espressif/arduino-esp32#863

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
void setup(){
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

it seems to solve the problem.

@luc-github
Copy link
Owner

@shaddow501
You can find location in the code - but I do not think it would be a good approach as information are displayed at start or on request which make no sense for screen that need to be permanently updated

I have studied the oled API and prepared some test sketch for rendering, screen refresh, etc.. if you want to have a look :
testoled.zip

The functions I use and wrote do not use delay / yield as oled must be compatible with async webserver, I plan to add an update screen function which will be in main loop and update screen every 1 sec as minimum trigger to not overload esp

It should cover all needs for the ESP - may be need to define a boot splash screen - and may be add a clock when SPIFFS will support time

About reset : I never had such issue, which confirm it is an HW issue as mentioned in thread you shared, it could be added using flag, but it should not be enabled by default IMHO

@shaddow501
Copy link
Author

Dear Luc

At the moment the module is stable and running good.

The screen show my printer name , SSID and IP.

I don’t think that there is anymore room to add anything else in the screen.

By the way I don’t think that it is important to update the screen every second, I think that the display should be updated with new info only if IP or SSID changes.

20180117_180134

@shaddow501
Copy link
Author

I did modify those sections:

//this is AP mode
if (bmode==AP_MODE) {
LOG("Set AP mode\r\n")
if(!CONFIG::read_string(EP_AP_SSID, sbuf, MAX_SSID_LENGTH)) {
return false;
}
if(!CONFIG::read_string(EP_AP_PASSWORD, pwd, MAX_PASSWORD_LENGTH)) {
return false;
}
ESP_SERIAL_OUT.print(FPSTR(M117_));
ESP_SERIAL_OUT.print(F("SSID "));
ESP_SERIAL_OUT.println(sbuf);
display.clear();
display.setFont(ArialMT_Plain_16);
display.setColor(WHITE);
display.drawString(0, 0, "AnyCubic 3D");
display.drawString(0, 22, "SSID: " + String(sbuf));
display.display();

} else {
LOG("Set STA mode\r\n")
if(!CONFIG::read_string(EP_STA_SSID, sbuf, MAX_SSID_LENGTH)) {
return false;
}
if(!CONFIG::read_string(EP_STA_PASSWORD, pwd, MAX_PASSWORD_LENGTH)) {
return false;
}
ESP_SERIAL_OUT.print(FPSTR(M117_));
ESP_SERIAL_OUT.print(F("SSID "));
ESP_SERIAL_OUT.println(sbuf);
display.clear();
display.setFont(ArialMT_Plain_16);
display.setColor(WHITE);
display.drawString(0, 0, "AnyCubic 3D");
display.drawString(0, 22, "SSID: " + String(sbuf));
display.display();
LOG("SSID ")
LOG(sbuf)
LOG("\r\n")
if (!CONFIG::read_byte(EP_STA_IP_MODE, &bflag )) {
return false;
}

//Get IP
if (WiFi.getMode()==WIFI_STA) {
    currentIP=WiFi.localIP();
    currentIP_string=WiFi.localIP().toString();
} else {
    currentIP=WiFi.softAPIP();
    currentIP_string=WiFi.softAPIP().toString();
}
ESP_SERIAL_OUT.print(FPSTR(M117_));
ESP_SERIAL_OUT.println(currentIP);
 display.setFont(ArialMT_Plain_16);
 display.setColor(BLACK);
 display.drawString(0, 45, "IP:" + String (currentIP_string_old));
 display.display();
 display.setColor(WHITE);
display.drawString(0, 45, "IP:" + String (currentIP_string));
display.display();
currentIP_string = currentIP_string_old; 


ESP_SERIAL_OUT.flush();
return true;

}

@mvturnho
Copy link

mvturnho commented Feb 2, 2018

I added OLed and 5 way tactile button support for ESP32 and use the second core to run the display task. This way the animations are fluently and you can leave the brownout (watchdog) active.

in esp3d.ino in setup I add

initOled(); xTaskCreatePinnedToCore(esp3dTask, "loop1", 4096, (void *) 1, 1, NULL, 1); xTaskCreatePinnedToCore(oledTask, "loop1", 4096, (void *) 1, 1, NULL, 0);

I moved the complete loop to a task:

`
void esp3dTask(void *pvParameters) {
int taskno = (int) pvParameters;
int sleeptime;

while (1) {
	//be sure wifi is on to proceed wifi function
	if (WiFi.getMode() != WIFI_OFF) {

#ifdef CAPTIVE_PORTAL_FEATURE
if (WiFi.getMode() != WIFI_STA) {
dnsServer.processNextRequest();
}
#endif
//web requests
web_interface->web_server.handleClient();
#ifdef TCP_IP_DATA_FEATURE
BRIDGE::processFromTCP2Serial();
#endif
}
BRIDGE::processFromSerial2TCP();
//in case of restart requested
if (web_interface->restartmodule) {
CONFIG::esp_restart();
}
vTaskDelay(1);
}
}
`

and left the loop with only:

//main loop void loop() { //do nothing here vTaskDelay(portMAX_DELAY); // wait as much as posible ... }

in Oled.cpp I have the implementation:

`
#include "oled.h"
#include "config.h"
#include "wificonf.h"

// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for #include "SSD1306Wire.h"

// Include the UI lib
#include "OLEDDisplayUi.h"

// Include custom images
#include "images.h"

//Hardware pin assignment
#define SDA 4
#define SCL 15

#define PIN_UP 12
#define PIN_DOWN 13
#define PIN_LEFT 14
#define PIN_RIGHT 26
#define PIN_CENTER 27

#define TARGET_FPS 30
#define FRAMECOUNT 2

//--- 4way(U,D,L,R) Switch Read ---
#define KEY_ID_UP 1
#define KEY_ID_DOWN 2
#define KEY_ID_LEFT 3
#define KEY_ID_RIGHT 4
#define KEY_ID_MUN 5

#define MODE_MENU 1
#define MODE_SELECT 2
#define MODE_MOVE 3

// Initialize the OLED display using Wire library
SSD1306 display(0x3c, SDA, SCL);

OLEDDisplayUi ui ( &display );

int oldButtonState = HIGH;

int key_code = 0;
int prev_key_code = 0;
int long_press = 0;
int ui_mode = MODE_MENU;

void oledTask(void *pvParameters) {
int taskno = (int)pvParameters;
int sleeptime;

while (1) {
sleeptime = (int)(esp_random() & 0x0F);
//Serial.println(String("Task ")+String(taskno)+String(" ")+String(sleeptime));
int remainingTimeBudget = oLedUpdate();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
vTaskDelay(remainingTimeBudget);
}
}
}

void msOverlay(OLEDDisplay display, OLEDDisplayUiState state) {
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->setFont(ArialMT_Plain_10);
display->drawString(128, 0, String(millis()));
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0,0,WiFi.localIP().toString().c_str());
}

void drawFrame1(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->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
}

void drawFrame2(OLEDDisplay display, OLEDDisplayUiState state, int16_t x, int16_t y) {
// Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
// Besides the default fonts there will be a program to convert TrueType fonts into this format
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_16);
display->drawString(0 + x, 10 + y, WiFi.getHostname());

display->setFont(ArialMT_Plain_10);
display->drawString(0 + x, 26 + y, WiFi.SSID().c_str());
display->drawString(0 + x, 36 + y, String(wifi_config.getSignal(WiFi.RSSI())).c_str());
}

// This array keeps function pointers to all frames
// frames are the single views that slide in
FrameCallback frames[] = { drawFrame1, drawFrame2 };
//int frameCount = FRAMECOUNT;

// Overlays are statically drawn on top of a frame eg. a clock
OverlayCallback overlays[] = { msOverlay };
int overlaysCount = 1;

void initOled(void) {
Serial.println("start");
pinMode(16,OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high

//init the keypad
//pinMode(0, INPUT);
pinMode(PIN_UP, INPUT_PULLDOWN);
pinMode(PIN_DOWN, INPUT_PULLDOWN);
pinMode(PIN_LEFT, INPUT_PULLDOWN);
pinMode(PIN_RIGHT, INPUT_PULLDOWN);
pinMode(PIN_CENTER, INPUT_PULLDOWN);

// The ESP is capable of rendering 60fps in 80Mhz mode
// but that won't give you much time for anything else
// run it in 160Mhz mode or just set it to 30 fps
ui.setTargetFPS(TARGET_FPS);
ui.disableAutoTransition();
// Customize the active and inactive symbol
ui.setActiveSymbol(activeSymbol);
ui.setInactiveSymbol(inactiveSymbol);

// 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);

// Initialising the UI will init the display too.
ui.init();

display.flipScreenVertically();

display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_24);
display.drawString(20, 0, "ESP3D");
display.drawString(0, 35, "Connecting");

display.display();
}

//-------------------------------------------
// key Control
//-------------------------------------------
void KeyPolling(void) {
prev_key_code = key_code;
if (digitalRead(PIN_UP) == HIGH) {
key_code = KEY_ID_UP;
} else if (digitalRead(PIN_DOWN) == HIGH) {
key_code = KEY_ID_DOWN;
} else if (digitalRead(PIN_LEFT) == HIGH) {
key_code = KEY_ID_LEFT;
} else if (digitalRead(PIN_RIGHT) == HIGH) {
key_code = KEY_ID_RIGHT;
} else
key_code = 0;

if (prev_key_code == key_code)
	long_press++;
else
	long_press = 0;

return;

}

int oLedUpdate(void) {
int buttonState = digitalRead(0); //GPIO 0
// check if the pushbutton is pressed.
// if it is, the buttonState is LOW:
if (buttonState == LOW && oldButtonState != buttonState) {
//Serial.println("Button Pushed");
ui.nextFrame();
oldButtonState = buttonState;
}
if(buttonState == HIGH && oldButtonState != buttonState){
oldButtonState = buttonState;
}

KeyPolling();

if (key_code == KEY_ID_LEFT) {
ui.previousFrame();
} else if(key_code == KEY_ID_RIGHT) {
ui.nextFrame();
} else if(key_code == KEY_ID_UP) {
ui.enableAutoTransition();
} else if(key_code == KEY_ID_DOWN) {
ui.disableAutoTransition();
} else if(key_code == KEY_ID_MUN) {
ui_mode = ui.getUiState()->currentFrame;
}

return ui.update();
}
`

@shaddow501
Copy link
Author

Hi, Where can I download the complete code to test?

@luc-github
Copy link
Owner

I think issue can be closed now

@mvturnho
Copy link

the code is on github

https://github.com/mvturnho/ESP3D.git

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants