How to connect everything together properly?

Hello,

I am trying to assemble simple barometer with logging and LCD display but looks like using the same pins for some tasks not allowed or at least in some extend. I am using NodeMCUv3 with ESP8266 onboard, bmp280 sensor for retrieving data, ds3231 clock to be able constantly use clock with no interrupts SD card module to write data and time to the file and LCD 16x2 display to show current time and sensor data, additionally I am using telegram bot to be able access current sensor data which takes some interrupts. image of the scheme

I did test all modules separate with the standard code which provides along with Arduino IDE and everything is working fine until I combine many sketches in one. After many attempts to do this I have reached the point when every module works in sketch except the SD card module and looks like it is conflicting with LCD. Unfortunately I did not find the information how I can resolve the issue and there is no free pins left which I can use to avoid overlapping. The strange thing that the same overlapping pins which connected to BMP280 and DS3231 are not conflicting to each other and work ok together. On other hand LCD and SD card no. Any ideas how to fix it? Thanks.

If the "SD" part of code uncomment LCD display is starting display garbage

Code:
https://codeshare.io/OdKw9g

#include <LiquidCrystal.h>
#include <BMP280_DEV.h>                           // Include the BMP280_DEV.h library        The .cpp file was modified by changing altitude measuring value
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <math.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
#include <BME280I2C.h>
#include <Wire.h>


// SD
File myFile;
// SD


// LCD
LiquidCrystal lcd(D6, D5, D0, D7, D3, D4);
// LCD


// BME280
float temperature, pressure, altitude;            // Create the temperature, pressure and altitude variables
BMP280_DEV bmp280;     // Instantiate (create) a BMP280_DEV object and set-up for I2C operation

BME280I2C bme;

// BME280

/*

// DS3231
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// DS3231

*/

unsigned long previousmillis = 0;
const long interval = 1000;


float temp(NAN), hum(NAN), pres(NAN);



//TELEGRAM
// Wifi network station credentials
#define WIFI_SSID "Untitled"
#define WIFI_PASSWORD "Untitled"
// Telegram BOT Token (Get from Botfather)
#define BOT_TOKEN "1804515083:AAE_pQS0Hf911B_VG5Tty4STfuBOG8z2fsc"

const unsigned long BOT_MTBS = 1000; // mean time between scan messages

X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);
unsigned long bot_lasttime; // last time messages' scan has been done


void handleNewMessages(int numNewMessages)
{
  Serial.print("handleNewMessages ");
  Serial.println(numNewMessages);

  for (int i = 0; i < numNewMessages; i++)
  {
    String chat_id = bot.messages[i].chat_id;
    String text = bot.messages[i].text;

    String from_name = bot.messages[i].from_name;
    if (from_name == "")
      from_name = "Guest";

    if (text)
    {
      String PresText;
      String TempText;
      String Temp2Text;
      char pressureBuffer[32];
      char temperatureBuffer[32];
      char temperature2Buffer[32];
      //float rtcTemp = rtc.getTemperature();
      
      PresText += " hPa";
      dtostrf(pres / 100, 16, 2, pressureBuffer);
      bot.sendMessage(chat_id, pressureBuffer + PresText, "");
      delay(200);
      
      TempText = " *C";
      dtostrf(temp, 16, 2, temperatureBuffer);
      bot.sendMessage(chat_id, temperatureBuffer + TempText, "");

      //Temp2Text = " *C";
      //dtostrf(rtcTemp, 16, 2, temperature2Buffer);
      //bot.sendMessage(chat_id, temperature2Buffer + Temp2Text, "");
    }

   
    if (text == "/start")
    {
      String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n";
      welcome += "This is Flash Led Bot example.\n\n";
      welcome += "/ledon : to switch the Led ON\n";
      welcome += "/ledoff : to switch the Led OFF\n";
      welcome += "/status : Returns current status of LED\n";
      bot.sendMessage(chat_id, welcome, "Markdown");
    }
  }
}
// TELEGRAM


void printBME280Data
(
   Stream* client
)
{


   BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
   BME280::PresUnit presUnit(BME280::PresUnit_Pa);

   bme.read(pres, temp, hum, tempUnit, presUnit);

   client->print("Temp: ");
   client->print(temp);
   client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
   client->print("\t\tHumidity: ");
   client->print(hum);
   client->print("% RH");
   client->print("\t\tPressure: ");
   client->print(pres);
   client->println("Pa");

    lcd.clear();
    lcd.setCursor(0,1); 
    lcd.print (pres / 100);
    lcd.print (F("hPa "));
    lcd.print(temp);

   delay(1000);

}



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

// LCD
    lcd.begin(16, 2);
// LCD

Wire.begin();

  while(!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!");
    delay(1000);
  }

  switch(bme.chipModel())
  {
     case BME280::ChipModel_BME280:
       Serial.println("Found BME280 sensor! Success.");
       break;
     case BME280::ChipModel_BMP280:
       Serial.println("Found BMP280 sensor! No Humidity available.");
       break;
     default:
       Serial.println("Found UNKNOWN sensor! Error!");
  }


/*
// BME280
  if(bmp280.begin(BMP280_I2C_ALT_ADDR)) {            // Default initialisation with alternative I2C address (0x76), place the BMP280 into SLEEP_MODE 
  Serial.println("bmp280.began");
  
  //bmp280.setPresOversampling(OVERSAMPLING_X4);    // Set the pressure oversampling to X4
  //bmp280.setTempOversampling(OVERSAMPLING_X1);    // Set the temperature oversampling to X1
  //bmp280.setIIRFilter(IIR_FILTER_4);              // Set the IIR filter to setting 4
  bmp280.setTimeStandby(TIME_STANDBY_2000MS);     // Set the standby time to 2 seconds
  Serial.println("enter standby mode");
  bmp280.startNormalConversion();                 // Start BMP280 continuous conversion in NORMAL_MODE
  Serial.println("enter normal mode");
  }
// BME280
*/
/*

  // SD
  Serial.print("Initializing SD card...");

  if (!SD.begin(D8)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");


    // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    String Comma = ",";
    Comma = ", ";
    Serial.print("Writing to test.txt...");
    myFile.println(Comma + press + Comma + temp);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

// SD

*/


// TELEGRAM
  Serial.println();

  // attempt to connect to Wifi network:
  Serial.print("Connecting to Wifi SSID ");
  Serial.print(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  secured_client.setTrustAnchors(&cert); // Add root certificate for api.telegram.org
  
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(400);
  }
  Serial.print("\nWiFi connected. IP address: ");
  Serial.println(WiFi.localIP());

  Serial.print("Retrieving time: ");
  configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(200);
    now = time(nullptr);
  }
Serial.println(now);

// TELEGRAM



/*

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }


  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2021, 6, 19, 17, 19, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2021, 7, 31, 16, 12, 0));
// DS3231


*/
}

void loop(){

Serial.println("enter loop");

/*

BME280I2C bme;

   Stream* client
   float temp(NAN), hum(NAN), pres(NAN);

   BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
   BME280::PresUnit presUnit(BME280::PresUnit_Pa);

   bme.read(pres, temp, hum, tempUnit, presUnit);
// LCD

    //DateTime now = rtc.now();
    lcd.clear();

    //lcd.print(now.day(), DEC);
    //lcd.print('/');
    //lcd.print(now.month(), DEC);
    //lcd.print("    ");
    //lcd.print(now.hour(), DEC);
    //lcd.print(':');
    //lcd.print(now.minute(), DEC);
    //lcd.print(':');
    //lcd.print(now.second(), DEC);


//    lcd.print(rtc.getTemperature());
//    lcd.print(F("*C"));

        // go to row 1 column 0, note that this is indexed at 0
    lcd.setCursor(0,1); 
    client->lcd.print (pres);
    lcd.print (F("hPa "));
    lcd.print(temp);
//    lcd.print(F("*C "));
*/

   printBME280Data(&Serial);
   delay(500);

/*
   String Comma = ", ";
   Comma = ", ";
   char pressureBuffer[32];
   char temperatureBuffer[32];
   char temperature2Buffer[32];
   //float rtcTemp = rtc.getTemperature();
   //uint8_t ifBuffer = now.minute();
   //uint8_t ifBuffer2 = now.second();

   if (ifBuffer == 0 && ifBuffer2 == 0) {
    for (int i = 0; i = 1; i++) {
    myFile = SD.open("DATA.txt", FILE_WRITE);

    // if the file opened okay, write to it:
   if (myFile) {
    myFile.println(now.day() + Comma + now.month() + Comma + now.year() + Comma + now.hour() + Comma + now.minute() + Comma + now.second() + Comma + pressure + Comma + temperature + Comma + rtc.getTemperature() + Comma + altitude);
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening DATA.txt");
  }}}

*/
// LCD


// TELEGRAM
if (millis() - bot_lasttime > BOT_MTBS)
  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

    while (numNewMessages)
    {
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }

    bot_lasttime = millis();
  }
// TELEGRAM
Serial.println("exit loop");
}

Your post was MOVED to its current location as it is more suitable.

I'm surprised you're not having more problems. Seems like you're using pins of the microcontroller for several devices at the same time. In most cases, this does not work, and can in fact damage the devices.
You might want to look into I2C, or migrate to another mlm microcontroller (eg esp32) that has more GPIO's.

I'm also surprised you don't have bigger problems. BMP280 and DS3231 use I2C bus and since they have different addresses there is no problem - that's why this bus was created. If only the LCD display is a problem, you can try to connect it to the same I2C bus of BMP280 and DS3231. There are such ready-made displays and their price is not high.

Thanks for your reply. I have esp32 but i didn't try to assemble all things with that but I have already bought baseboard for esp8266 to avoid soldering (it always went mess for me) so for this project I will use only esp8266.

Thanks for your reply. Just purchased I2C bus to make things easier. The delivery will take some time then I'll update my progress :slightly_smiling_face:

What exactly have you bought ?

Yes, a really good question from @UKHeliBob. I'm also curious, what did you order? I hope you mean PCF8574 or something similar for connection to the LCD display. Or I2C OLED display, maybe SSD1306.

This one Free Shipping IIC/I2C / Interface LCD1602 2004 LCD Adapter Plate for Arduino|interface lcd|interface i2cplate adapter - AliExpress
But looks like it has to be resolder because the LCD soldered with the same type of pins but I will handle it :grinning: I guess.

Excellent, that module will do the job.
I'd get a new 1602 lcd as well, they're cheap and desoldering the pins from one is usually frustrating work (can be done fine btw).

After a while the device arrived and I did broken it during desoldering headers on it((( Even after, it is really difficult to solder the adapter on LCD headers because I don't have special equipment just regular soldering iron and it is almost impossible to "put on" adapter on pins because holes on it covered by metal. Is anyone knows some soldering technique?