Oled 1.3" I2C SSH1106 with ESP32 no display

Hi all Arduino geniuses!

I am using the code from original designer "Projects of Red" for the wire stripper.
The sketch was successful uploaded but I can't see display on OLED. However, it works with example code from Adafruit.

Please advise

#include <Stepper.h>
#include <Encoder.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

#define motorInterfaceType 1
#define i2c_Address 0x3c //OLED 1.3 Inch 128X64 IIC I2C SPI SSH1106 SSD1306

const int LINMOT_STEPPERS_STEP_PIN = 19;  // LINMOT: Linear motion
const int LINMOT_STEPPERS_DIR_PIN = 18;

const int EXTRUDER_STEPPER_STEP_PIN = 16;  // The stepper that moves the wire in the extruder.
const int EXTRUDER_STEPPER_DIR_PIN = 17;

const int ENCODER_DT_PIN = 0;
const int ENCODER_CLK_PIN = 23;
const int ENCODER_BTN_PIN = 4;

// For calibration only. The two buttons are used to move the top blade up and down manually.
// Once calibrated, you can remove the buttons from the circuit.
const int BTN1_PIN = 27;
const int BTN2_PIN = 26;

const int LINMOT_STEPPERS_STEPS = 1;  // Steppers step(s) movement at a time.
const int EXTRUDER_STEPPER_STEPS = 1;

const int LINMOT_STEPPERS_SPEED = 2000;
const int EXTRUDER_STEPPER_SPEED = 2000;


const int SCREEN_WIDTH = 128;  // OLED display width, in pixels
const int SCREEN_HEIGHT = 64;  // OLED display height, in pixels
const int TEXT_SIZE = 2;
const int TEXT_OFFSET = 3;

// Values for drawing the wire at the top of the OLED screen.
const int WIRE_STRAND_LENGTH = 30;
const int WIRE_STRAND_Y_POS = 7;
const int WIRE_INSULATION_WIDTH = SCREEN_WIDTH - (WIRE_STRAND_LENGTH * 2);
const int WIRE_INSULATION_HEIGHT = 14;

// These are just references to the corresponding component index in the comps array;
const int STRIPPING_LENGTH1_INDEX = 0;
const int WIRE_LENGTH_INDEX = 1;
const int STRIPPING_LENGTH2_INDEX = 2;
const int QUANTITY_INDEX = 3;
const int STRIPPING_DEPTH_INDEX = 4;
const int START_BTN_INDEX = 5;

const int CUTTING_STEPS = 17750;  // Steps to move blade to fully cut the wire.
const int STRIPPING_MULTIPLIER = 300;  // The chosen stripping depth value on the screen is multiplied by this value.
const int WIRE_MOVEMENT_MULTI = 414;  // How much to move wire per unit on OLED, turn on CALIBRATION_MODE to find this value.
const int DELAY_BETWEEN_CUTS = 100;  // Delay in ms between each cut in the quantity.

// To calibrate the wire movement distance. Use the first cell to enter the distance in mm to move the wire.
// Then adjust WIRE_MOVEMENT_MULTI to get the correct wire length.
const boolean CALIBRATION_MODE = true;


Stepper linMotSteppers(200, LINMOT_STEPPERS_DIR_PIN, LINMOT_STEPPERS_STEP_PIN);
Stepper extruderStepper(200, EXTRUDER_STEPPER_DIR_PIN, EXTRUDER_STEPPER_STEP_PIN);

Encoder encoder(ENCODER_DT_PIN, ENCODER_CLK_PIN);

Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


int linMotSteppersCurrStep = 0;  // Current position/step of the stepper motor.

// A component is a cell with a value on the OLED display.
struct Component {
    int x, y;  // Position
    int w, h;  // Size
    int value;  // Current value of the cell.
    boolean highlighted;  // Whether the cell is the currently highlighted cell.
    boolean selected;  // Whether the cell is currently the selected one, where its value will be controlled by the encoder.
    boolean btn;  // If it is a button or not.
};


Component comps[] = {{0, 20, 40, 20, 0, 0, 0, 0},
                     {44, 20, 40, 20, 0, 0, 0, 0},
                     {88, 20, 40, 20, 0, 0, 0, 0},
                     {0, 44, 40, 20, 0, 0, 0, 0},
                     {44, 44, 40, 20, 0, 0, 0, 0},
                     {88, 44, 40, 20, 0, 0, 0, 1}};

int numOfComps = sizeof(comps) / sizeof(comps[0]);


int encoderPos;  // Current position/value of the encoder.
int encoderLastPos;  // For OLED drawing.
int encoderLastPosMain;  // For main loop.

boolean encBtnState = false;
boolean encBtnPrevState = false;  // For OLED drawing.
boolean encBtnPrevStateMain = false;  // For main loop.



void setup() {
    linMotSteppers.setSpeed(LINMOT_STEPPERS_SPEED);
    extruderStepper.setSpeed(EXTRUDER_STEPPER_SPEED);

    pinMode(ENCODER_BTN_PIN, INPUT_PULLUP);

    pinMode(BTN1_PIN, INPUT_PULLUP);
    pinMode(BTN2_PIN, INPUT_PULLUP);

    display.begin(i2c_Address, true);
}


void loop() {
    int encPos = getEncoderPos();
    boolean encBtnState = digitalRead(ENCODER_BTN_PIN);

    // Only update OLED screen if encoder is moved or pressed.
    if((encPos != encoderLastPosMain) || (encBtnState != encBtnPrevStateMain)) {
        handleOLEDDisplay();
    }
    
    if(comps[START_BTN_INDEX].selected) {
        runAutoCuttingStripping();
    }

    encoderLastPosMain = encPos;
    encBtnPrevStateMain = encBtnState;


    if(!digitalRead(BTN1_PIN)) {
        moveBlade(1);
    }
    if(!digitalRead(BTN2_PIN)) {
        moveBlade(-1);
    }    
}


void handleOLEDDisplay() {
    display.clearDisplay();

    drawWire();

    boolean btnState = digitalRead(ENCODER_BTN_PIN);

    // Handling whether encoder is changing cell or value of the cell.
    if(!btnState && (btnState != encBtnPrevState)) {
        encBtnState = !encBtnState;

        if(encBtnState) {
            encoderLastPos = encoderPos;
        } else {
            encoder.write(encoderLastPos * 4);
        }
    }
    
    encBtnPrevState = btnState;

    if (!encBtnState) {
        encoderPos = getEncoderPos();
    }

    handleAllComponents();
    
    display.display();
}


void drawWire() {
    display.drawLine(0, WIRE_STRAND_Y_POS, WIRE_STRAND_LENGTH, WIRE_STRAND_Y_POS, SH110X_WHITE);
    display.fillRect(WIRE_STRAND_LENGTH, 0, WIRE_INSULATION_WIDTH, WIRE_INSULATION_HEIGHT, SH110X_WHITE);
    display.drawLine(WIRE_STRAND_LENGTH+WIRE_INSULATION_WIDTH, WIRE_STRAND_Y_POS, SCREEN_WIDTH, WIRE_STRAND_Y_POS, SH110X_WHITE);
}


void handleAllComponents() {
    for(int i = 0; i < numOfComps; i++) {
        Component &comp = comps[i];
        
        if(encoderPos == i) {
            comp.highlighted = true;
            
            if(encBtnState) {
                if(!comp.selected && !comp.btn) {
                    encoder.write(comp.value * 4);
                }
                
                comp.selected = true;
                
                int newEncPos = getEncoderPos();
                comp.value = newEncPos;
                
            } else {
                comp.selected = false;
            }
            
        } else {
            comp.highlighted = false;
            comp.selected = false;
        }
        
        drawComponent(comp);
    }
}


void drawComponent(Component comp) {
    if(comp.highlighted) {
        display.setTextColor(SH110X_BLACK, SH110X_WHITE);
        display.fillRect(comp.x, comp.y, comp.w, comp.h, SH110X_WHITE);
        
        if (comp.selected) {
            display.drawRect(comp.x-1, comp.y-1, comp.w+2, comp.h+2, SH110X_WHITE);
        }
        
    } else {
        display.setTextColor(SH110X_WHITE, SH110X_BLACK);
        display.drawRect(comp.x, comp.y, comp.w, comp.h, SH110X_WHITE);
    }

    if(comp.btn) {
        display.setTextSize(1);
        drawText("Start", comp.x + TEXT_OFFSET, comp.y + TEXT_OFFSET);
    } else {
        display.setTextSize(TEXT_SIZE);
        drawText(String(comp.value), comp.x + TEXT_OFFSET, comp.y + TEXT_OFFSET);
    }
}


void drawText(String text, int x, int y) {
    display.setCursor(x, y);
    display.println(text);
}


void runAutoCuttingStripping() {
    if(CALIBRATION_MODE) {
        moveWire(comps[STRIPPING_LENGTH1_INDEX].value);
        cut();
    } else {
        cut();
        delay(DELAY_BETWEEN_CUTS);

        for(int i = 0; i < comps[QUANTITY_INDEX].value; i++) {
            moveWire(comps[STRIPPING_LENGTH1_INDEX].value);
            strip();
            moveWire(comps[WIRE_LENGTH_INDEX].value);
            strip();
            moveWire(comps[STRIPPING_LENGTH2_INDEX].value);
            cut();
            delay(DELAY_BETWEEN_CUTS);
        }   
    }

    comps[START_BTN_INDEX].selected = false;
    encBtnState = false;
}


void cut() {
    moveBlade(-CUTTING_STEPS);
    moveBlade(CUTTING_STEPS);
}


void strip() {
    moveBlade(-(comps[STRIPPING_DEPTH_INDEX].value * STRIPPING_MULTIPLIER));
    moveBlade(comps[STRIPPING_DEPTH_INDEX].value * STRIPPING_MULTIPLIER);
}


void moveBlade(int steps) {
    linMotSteppers.step(steps);
    linMotSteppersCurrStep += steps;
}


void moveWire(int steps) {
    extruderStepper.step(steps * WIRE_MOVEMENT_MULTI);
}


int getEncoderPos() {
    int encPos = encoder.read() / 4;
    return encPos;
}

Check for conflicts with I/O pin usage.

The best approach is to start with the working display example, and add your other code in, section by section, testing as you go.

from the example code, I tried to combine both sketch but don't know where to start.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>


/* Uncomment the initialize the I2C address , uncomment only one, If you get a totally blank screen try the other*/
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
//#define i2c_Address 0x3d //initialize with the I2C addr 0x3D Typically Adafruit OLED's

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1   //   QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


#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
};


void setup()   {

  Serial.begin(9600);

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.

  delay(250); // wait for the OLED to power up
  display.begin(i2c_Address, true); // Address 0x3C default
 //display.setContrast (0); // dim display
 
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, SH110X_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 SH110X_WHITE circle, 10 pixel radius
  display.fillCircle(display.width() / 2, display.height() / 2, 10, SH110X_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();



  // text display tests
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);
  display.println("Failure is always an option");
  display.setTextColor(SH110X_BLACK, SH110X_WHITE); // 'inverted' text
  display.println(3.141592);
  display.setTextSize(2);
  display.setTextColor(SH110X_WHITE);
  display.print("0x"); display.println(0xDEADBEEF, HEX);
  display.display();
  delay(2000);
  display.clearDisplay();

  // miniature bitmap display
  display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
  display.display();
  delay(1);

  // invert the display
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);
  display.clearDisplay();

  // draw a bitmap icon and 'animate' movement
  testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}


void loop() {

}


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], bitmap, w, h, SH110X_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], bitmap, w, h, SH110X_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(SH110X_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();
  delay(1);
}

void testdrawcircle(void) {
  for (int16_t i = 0; i < display.height(); i += 2) {
    display.drawCircle(display.width() / 2, display.height() / 2, i, SH110X_WHITE);
    display.display();
    delay(1);
  }
}

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();
    delay(1);
    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, SH110X_WHITE);
    display.display();
    delay(1);
  }
}

void testfilltriangle(void) {
  uint8_t color = SH110X_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, SH110X_WHITE);
    if (color == SH110X_WHITE) color = SH110X_BLACK;
    else color = SH110X_WHITE;
    display.display();
    delay(1);
  }
}

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, SH110X_WHITE);
    display.display();
    delay(1);
  }
}

void testfillroundrect(void) {
  uint8_t color = SH110X_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 == SH110X_WHITE) color = SH110X_BLACK;
    else color = SH110X_WHITE;
    display.display();
    delay(1);
  }
}

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, SH110X_WHITE);
    display.display();
    delay(1);
  }
}

void testdrawline() {
  for (int16_t i = 0; i < display.width(); i += 4) {
    display.drawLine(0, 0, i, display.height() - 1, SH110X_WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i = 0; i < display.height(); i += 4) {
    display.drawLine(0, 0, display.width() - 1, i, SH110X_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i = 0; i < display.width(); i += 4) {
    display.drawLine(0, display.height() - 1, i, 0, SH110X_WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i = display.height() - 1; i >= 0; i -= 4) {
    display.drawLine(0, display.height() - 1, display.width() - 1, i, SH110X_WHITE);
    display.display();
    delay(1);
  }
  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, SH110X_WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i = display.height() - 1; i >= 0; i -= 4) {
    display.drawLine(display.width() - 1, display.height() - 1, 0, i, SH110X_WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i = 0; i < display.height(); i += 4) {
    display.drawLine(display.width() - 1, 0, 0, i, SH110X_WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i = 0; i < display.width(); i += 4) {
    display.drawLine(display.width() - 1, 0, i, display.height() - 1, SH110X_WHITE);
    display.display();
    delay(1);
  }
  delay(250);
}

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project.

@sterretje Thank you

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.