luc-github / ESP3D

FW for ESP8266/ESP8285/ESP32 used with 3D printer
GNU General Public License v3.0
1.78k stars 466 forks source link

Lolin ESP32 OLED #200

Closed shaddow501 closed 6 years ago

shaddow501 commented 6 years ago

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 demos[demoMode]();

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 commented 6 years ago

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 commented 6 years ago

Dear Luc

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

luc-github commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

https://github.com/luc-github/ESP3D/blob/13ee5e19e834fbfebd8652d5ee08e73d3b06eefd/esp3d/wificonf.cpp#L408-L409 for first one in command.cpp for [ESP111] command.

shaddow501 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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_SERIALOUT.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 commented 6 years ago

Dear Luc

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

https://github.com/espressif/arduino-esp32/issues/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 commented 6 years ago

@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 commented 6 years ago

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 commented 6 years ago

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_SERIALOUT.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_SERIALOUT.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 commented 6 years ago

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 // 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 commented 6 years ago

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

luc-github commented 6 years ago

I think issue can be closed now

mvturnho commented 6 years ago

the code is on github

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

github-actions[bot] commented 4 years ago

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.