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

Bus is in Slave Mode with Arduino core for the ESP32 release v2.0.1 #360

Open
whogarden opened this issue Nov 12, 2021 · 17 comments
Open

Bus is in Slave Mode with Arduino core for the ESP32 release v2.0.1 #360

whogarden opened this issue Nov 12, 2021 · 17 comments

Comments

@whogarden
Copy link

Describe the bug
Nothing is displayed on an oled sh1106 with
ESP32 dev board
SSD1306SimpleDemo.ino (it's your example code)

To Reproduce
I use
ESP32 dev board
An SH1106
Wire sda to gpio21, scl to gpio22
Flash SSD1306SimpleDemo.ino with Arduino core for the ESP32 release v2.0.1
an nothing is displayed on the oled screen.
If I go back to Arduino core for the ESP32 release v2.0.0, it's working

Sample code
Provide a MCVE below.

/**
   The MIT License (MIT)

   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
   Copyright (c) 2018 by Fabrice Weinberg

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in all
   copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   SOFTWARE.

   ThingPulse invests considerable time and money to develop these open source libraries.
   Please support us by buying our products (and not the clones) from
   https://thingpulse.com

*/

// Include the correct display library

// For a connection via I2C using the Arduino Wire include:
//#include <Wire.h>               // Only needed for Arduino 1.6.5 and earlier
//#include "SSD1306Wire.h"        // legacy: #include "SSD1306.h"
#include "SH1106Wire.h"   // legacy: #include "SH1106.h"

// For a connection via I2C using brzo_i2c (must be installed) include:
// #include <brzo_i2c.h>        // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// OR #include "SH1106Brzo.h"

// For a connection via SPI include:
// #include <SPI.h>             // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// OR #include "SH1106SPi.h"


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


// Initialize the OLED display using Arduino Wire:
//SSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
// SSD1306Wire display(0x3c, D3, D5);  // ADDRESS, SDA, SCL  -  If not, they can be specified manually.
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32);  // ADDRESS, SDA, SCL, OLEDDISPLAY_GEOMETRY  -  Extra param required for 128x32 displays.
 SH1106Wire display(0x3c, 21, 22);     // ADDRESS, SDA, SCL

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

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


#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,
                             "The pain itself\n pain is important, it has been resolved over the years." );
}

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, i * 3);
    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.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_RIGHT);
  display.drawString(128, 54, String(millis()));
  // write the buffer to the display
  display.display();

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

Expected behavior
Debug level "Debug"
[ 10][I][esp32-hal-i2c-slave.c:234] i2cSlaveInit(): Initialising I2C Slave: sda=22 scl=22 freq=100000, addr=0x15
[ 11][D][esp32-hal-i2c-slave.c:494] i2c_slave_set_frequency(): Fifo thresholds: rx_fifo_full = 28, tx_fifo_empty = 4
[ 28][E][Wire.cpp:283] setClock(): Bus is in Slave Mode
[ 33][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 39][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 45][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 51][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 57][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 63][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 68][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 74][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 80][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode

Additional context
Compile wire used :
Wire version 2.0.0 dans le dossier: C:\Users\me\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.1\libraries\Wire

@speedlao
Copy link

Hi whogarden, I'm having the same issue now, has yours resolved yet?

@whogarden
Copy link
Author

whogarden commented Mar 25, 2022

Hi speedlao,
I can't remember how it was solved.
I just try it now and it's working with :
ESP32 arduino core 2.0.2
ESP8266 and ESP32 OLED driver for SSD1306 displays version=4.2.1
Wire version 2.0.0( coming with the esp32 arduino core 2.0.2)

@speedlao
Copy link

Hi speedlao, I can't remember how it was solved. I just try it now and it's working with : ESP32 arduino core 2.0.2 ESP8266 and ESP32 OLED driver for SSD1306 displays version=4.2.1 Wire version 2.0.0( coming with the esp32 arduino core 2.0.2)

Thanks for the reply. my problem solved just now. In my case is using u8g2 lib for SSD1306 OLED.
The problem is when constructing u8g2 instance with hardwre I2C pin configuration, it won't work.
A pre-called Wire.setPins saved my day.

So, have a nice day, cheers!

@Logos7
Copy link

Logos7 commented Jun 20, 2022

I have the same problem on Heltec LoRa32 v2.

[ 28][E][Wire.cpp:283] setClock(): Bus is in Slave Mode
[ 33][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 39][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 45][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 51][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 57][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 63][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 68][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode

@whogarden
Copy link
Author

Hi Logos7
Did you solved the pb?
If not can you post
your code
And the first 2 lines before [ 28][E][Wire.cpp:283] setClock(): Bus is in Slave Mode

@Logos7
Copy link

Logos7 commented Jun 21, 2022

I used u8g2 lib for SSD1306 OLED.

I used the following type:

U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(SCL_OLED, SDA_OLED, RST_OLED);

@Logos7
Copy link

Logos7 commented Jun 21, 2022

setClock() looked like:

bool TwoWire::setClock(uint32_t frequency)
{
    esp_err_t err = ESP_OK;
#if !CONFIG_DISABLE_HAL_LOCKS
    //acquire lock
    if(lock == NULL || xSemaphoreTake(lock, portMAX_DELAY) != pdTRUE){
        log_e("could not acquire lock");
        return false;
    }
#endif
    if(is_slave){
        log_e("Bus is in Slave Mode");
        err = ESP_FAIL;
    } else {
        err = i2cSetClock(num, frequency);
    }
#if !CONFIG_DISABLE_HAL_LOCKS
    //release lock
    xSemaphoreGive(lock);
#endif
    return (err == ESP_OK);
}

@Logos7
Copy link

Logos7 commented Jun 21, 2022

Sorry, something went wrong with line endings...

@whogarden
Copy link
Author

In your Heltec LoRa32 v2, I can see that
oled sda is hard wired to gpio 4
And oled scl is hard wired to gpio 15
can you insure that your code correctly define that pins?

@Logos7
Copy link

Logos7 commented Jun 21, 2022

Yes.
I have the same pins.

@whogarden
Copy link
Author

And did you set the correct level on gpio16 (oled rst)?

@Logos7
Copy link

Logos7 commented Jun 21, 2022

Yes.

Even reset it manually...

@whogarden
Copy link
Author

without your code, I am unable to help you further...

@bato3
Copy link

bato3 commented Jul 14, 2022

see Wire.begin() overload issue: espressif/arduino-esp32#6616 (comment)

@Tinyu-Zhao
Copy link

Tinyu-Zhao commented Jul 21, 2022

see Wire.begin() overload issue: espressif/arduino-esp32#6616 (comment)

Thank you he played a role for me.

@ramonjunquera
Copy link

A variant for the begin method has been included in the ESP32 Wire library.
Now we have the following syntax:

Wire.begin(int sda=-1,int scl=-1,uint32_t frequency=0U);
Wire.begin(uint8_t slaveAddr,int sda=-1,int scl=-1,uint32_t frequency=0U);

If we try to make the following call:

byte pinSDA=4;
byte pinSCL=15;
Wire.begin(pinSDA,pinSCL);

The compiler will find that the call to the begin method will detect that its first parameter is of type byte (uint8_t), therefore it will consider that the variant to call is the second...ERROR.
To solve the problem, it is enough to force the type of the first parameter to int:

byte pinSDA=4;
byte pinSCL=15;
Wire.begin((int)pinSDA,pinSCL);

Cheers

@sama-re
Copy link

sama-re commented Sep 3, 2022

Bonjour et merci pour l'astuce.
Le fait d'insérer (int) a débloqué ma situation en erreur.
J'utilise un ESP32 DevKitC v4. Sous l'IDE Arduino, avec un PC, cela fonctionnait.
Je viens de passer sous VScode + PlatformIO, sur Mac OS X, qui m'avait affiché cette erreur.
Merci à vous tous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants