olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5.01k stars 1.04k forks source link

u8g2.begin(); (SPI) breaks I2C devices #838

Closed wilhelmzeuschner closed 5 years ago

wilhelmzeuschner commented 5 years ago

Hardware:

I want to use an LCD display and have successfully tested it. Here's the constructor for my display: U8G2_ST7565_ERC12864_ALT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ SS, /* dc=*/ D3, /* reset=*/ D2); // contrast improved version for ERC12864 Additionally I have two I2C devices connected (HTU21D and DS3231). Both work fine when tested separately. As soon as I call u8g2.begin(); the sensors are "broken" and don't return data. If I read the sensor(s) beforeu8g2.begin(); it works fine!

I'm quite puzzled since I can't really explain that behavior... Is the u8g2 library somehow interfering with the I2C bus when initializing it?

Here's my complete sketch:

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

#include <Arduino.h>
#include <U8g2lib.h>
#include <SparkFunHTU21D.h>
#include <RtcDS3231.h>

#define CONTRAST 75

//Pins
const byte backlight_pin = D4;

//Variables
float humd = 0, temp = 0;

String time_comb;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

U8G2_ST7565_ERC12864_ALT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ SS, /* dc=*/ D3, /* reset=*/ D2);  // contrast improved version for ERC12864
HTU21D myHumidity;
RtcDS3231<TwoWire> Rtc(Wire);

void setup() {
  pinMode(backlight_pin, OUTPUT);
  analogWrite(backlight_pin, 128);

  Serial.begin(115200);
  Serial.println("Bike Computer started");

  Rtc.Begin();
  myHumidity.begin();
  //Reading data now (still) works
  float temp = myHumidity.readTemperature();

  Serial.print(" Temperature:");
  Serial.print(temp, 1);
  Serial.print("C");

  u8g2.begin();
  u8g2.setContrast(CONTRAST);
  //Now reading data doesn't work anymore
}

void loop() {
  update_display();
  read_sensors();
  rtc_time();

  delay(1000);
}

void update_display() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(0, 20, "Hello World!");
  u8g2.sendBuffer();
}

void read_sensors() {
  humd = myHumidity.readHumidity();
  temp = myHumidity.readTemperature();

  Serial.print("Time:");
  Serial.print(millis());
  Serial.print(" Temperature:");
  Serial.print(temp, 1);
  Serial.print("C");
  Serial.print(" Humidity:");
  Serial.print(humd, 1);
  Serial.println("%");
}

void rtc_time() {
  //RTC Measurement

  RtcDateTime now = Rtc.GetDateTime();

  String day_padding = zero_padder(String(now.Day()));  //Add Padding to Days
  /*Serial.print(day_padding);
  Serial.print('.');*/
  String month_padding = zero_padder(String(now.Month()));  //Add Padding to Months
  /*Serial.print(month_padding);
  Serial.print('.');
  Serial.print(now.year(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");*/

  String hour_padding = zero_padder(String(now.Hour()));  //Add Padding to Hours
  Serial.print(hour_padding);
  Serial.print(':');

  String min_padding = zero_padder(String(now.Minute())); //Add Padding to Minutes
  Serial.print(min_padding);
  Serial.print(':');

  String sec_padding = zero_padder(String(now.Second())); //Add Padding to Seconds
  Serial.print(sec_padding);
  Serial.println();
  time_comb = String(hour_padding) + ":" + String(min_padding) + ":" + String(sec_padding);
}

//Zero Padding function
String zero_padder(String z_p) {
  String zero_padded = z_p;   //Variable to hold result
  float current = z_p.toFloat();  //Integer for comparison
  if (current < 10) {
    zero_padded = "0" + z_p;
  }
  return zero_padded;
}
olikraus commented 5 years ago

Basically it should work. Maybe the activated display disturbs the other two sensors.

You could change "cs" pin and check whether the data from the sensor is correct (of course the display will not work). If this is the case, then there is a hardware problem, not a software problem.

wilhelmzeuschner commented 5 years ago

@olikraus I found my mistake, it had absolutely nothing to do with your code: U8G2_ST7565_ERC12864_ALT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ SS, /* dc=*/ D3, /* reset=*/ D2); D2 is SDA, so it makes perfect sense that I2C didn't work. Unfortunately I was testing out which pins I didn't need to connect to the display and one of them is the CS / SS pin which can be tied to GND directly if no other SPI device is on the bus. That's why I didn't find it earlier... Sorry for bothering you!

olikraus commented 5 years ago

:-)