Arduino hangs

Hi guys I have this system running to control a grow room with high humdity problem I am having is the arduino basically freezes after a random amount of time, it varies and the display comes up with random letters and numbers on it and the sensor is unresponsive, is there something wrong in my code causing this

   #include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "BlueDot_BME280_TSL2591.h"
BlueDot_BME280_TSL2591 bme280;
LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);
#define HUMIDIFIER 4
#define SETPOINT 90.0
#define DEADBAND 2.0
#define ON false
#define OFF true
void setup() {
  Serial.begin(9600);
  pinMode(HUMIDIFIER, OUTPUT);
  lcd.begin(16, 2);                     // for 16x2 LCD module
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Temp");
  lcd.setCursor(0, 1);
  lcd.print("Humidity");
  bme280.parameter.I2CAddress = 0x77;
  bme280.parameter.sensorMode = 0b11;
  bme280.parameter.IIRfilter = 0b100;
  bme280.parameter.humidOversampling = 0b101;
  bme280.parameter.tempOversampling = 0b101;
  bme280.parameter.tempOutsideCelsius = 15;
  if (bme280.init_BME280() != 0x60)
  {
    Serial.println(F("Ops! BME280 could not be found!"));
  }
  else
  {
    Serial.println(F("BME280 detected!"));
  }
  Serial.println();
  Serial.println();
}
void loop()
{ delay(1000);
  lcd.setCursor(11, 0);
  lcd.print(bme280.readTempC(), 2);
  //Move the cursor to the end of the word Humidity: and print the reading to 2 decimal places
  lcd.setCursor(11, 1);
  lcd.print(bme280.readHumidity(), 2);


  Serial.print(F("Temperature in Celsius:\t\t"));
  Serial.println(bme280.readTempC());

  Serial.print(F("Humidity in %:\t\t\t"));
  Serial.println(bme280.readHumidity());

  if (digitalRead(HUMIDIFIER) == OFF)
  {
    if (bme280.readHumidity() > SETPOINT + DEADBAND)
    {
      digitalWrite(HUMIDIFIER, ON);
    }
  }
  else
  {
    if (bme280.readHumidity() < SETPOINT - DEADBAND)
      digitalWrite(HUMIDIFIER, OFF);
  }
}

Try here

I have an outdoor wheather station based on a BME280 sensor and I am using a transistor to switch the GND of the sensor on and off in order to save power. I have never experienced any problems with the sensor and it has been running for almost two years now. If the softreset method does not work, maybe you can try that as well.

//Pseudocode
digitalWrite(TRANSISTOR, HIGH); //Switch on the sensor
initialize_BME280();
get_BME280_reading();
digitalWrite(TRANSISTOR, LOW); //Switch off the sensor

I am busy writing that into my code, however it's not only the sensor that stops working the display also stops working and gets completely jumbled up, would that be caused by the sensor as well

Mushroom_man:
I am busy writing that into my code, however it's not only the sensor that stops working the display also stops working and gets completely jumbled up, would that be caused by the sensor as well

Probably not, it may be caused by a brown out or some interference - HUMIDIFIER suggests some sort of relay, right? If so, that may be the cause.. If possible, you should post a schematic (drawing or good photo) of your wiring..

I did suspect the relay so I took that out of the system completely and it's still hanging I will post a picture of my wiring as soon as I get home, what is a brown out??

Which LiquidCrystal_I2C are you using that has a method for:

LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);

The ones I've seen typicall have (address, columns, rows).

Not sure what the identifiers are after the address 0x27 but, assuming they're pin numbers (as might be the case with a non-I2C parallel LCD) pins 0 and 1 are used; note that 0 and 1 are also the pins used by Serial.

Mushroom_man:
what is a brown out??

It’s not quite as bad as a blackout.

Blackfin:
Which LiquidCrystal_I2C are you using that has a method for:

LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);

The ones I've seen typicall have (address, columns, rows).

Not sure what the identifiers are after the address 0x27 but, assuming they're pin numbers (as might be the case with a non-I2C parallel LCD) pins 0 and 1 are used; note that 0 and 1 are also the pins used by Serial.

sorry it is a i2c display, that was the example I saw and did not think anything of it as it functioned do you thin it could be confusing things

Blackfin:
Which LiquidCrystal_I2C are you using that has a method for:

LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);

The ones I've seen typicall have (address, columns, rows).

Not sure what the identifiers are after the address 0x27 but, assuming they're pin numbers (as might be the case with a non-I2C parallel LCD) pins 0 and 1 are used; note that 0 and 1 are also the pins used by Serial.

sorry it is a i2c display, that was the example I saw and did not think anything of it as it functioned do you thin it could be confusing things

So if you're using the I2C IO expander board, they're probably okay as those appear to be the expander IO pins, not the Arduino pins (at least according to the "New-LiquidCrystal") library here:

assuming that's the one you're using.

You read the sensor 3 times. Once for the screen, once for Serial and once for the actual program logic. Those could give 3 different values. Best-practice is to take a reading at the top of loop() and use that same value everywhere.

digitalRead()ing an output pin is a valid technique on processors with extremely limited RAM. (Like, some have no general-purpose RAM at all.) The tiniest Arduino has enough RAM for your program to remember what state it is in without reading a pin.

Putting code on a line after a { makes it more difficult to read.

Writing an if() statement on 2 or more lines without using { and } is asking for trouble. Make it one single line or use the braces.

2 or more blank lines between functions helps break up the code visually and makes it easier to debug.

How long are the I2C wires?

My i2c wires for the screen are short, probably 10cm, however the wires to the sensor is 5 meter long, I am using 2×10kohm pullup resistors on the sensor cable, and I am using cat 5 communication cable

MorganS:
You read the sensor 3 times. Once for the screen, once for Serial and once for the actual program logic. Those could give 3 different values. Best-practice is to take a reading at the top of loop() and use that same value everywhere.

digitalRead()ing an output pin is a valid technique on processors with extremely limited RAM. (Like, some have no general-purpose RAM at all.) The tiniest Arduino has enough RAM for your program to remember what state it is in without reading a pin.

Putting code on a line after a { makes it more difficult to read.

Writing an if() statement on 2 or more lines without using { and } is asking for trouble. Make it one single line or use the braces.

2 or more blank lines between functions helps break up the code visually and makes it easier to debug.

How long are the I2C wires?

not sure how I would incorporate the reading of the sensor once for all 3 functions???

Can you try commenting out one of the BME280 reads – temperature or humidity – to see if either of them is causing the problem.

The math in the lib for the humidity reading in particular is pretty intensive:

.
.
. int32_t var1;
 var1 = (t_fine - ((int32_t)76800));
 var1 = (((((adc_H << 14) - (((int32_t)bme280_coefficients.dig_H4) << 20) - (((int32_t)bme280_coefficients.dig_H5) * var1)) +
 ((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)bme280_coefficients.dig_H6)) >> 10) * (((var1 * ((int32_t)bme280_coefficients.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
 ((int32_t)bme280_coefficients.dig_H2) + 8192) >> 14));
 var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)bme280_coefficients.dig_H1)) >> 4));
 var1 = (var1 < 0 ? 0 : var1);
 var1 = (var1 > 419430400 ? 419430400 : var1);
 float H = (var1>>12);
.
.
.

By commenting out certain calls you might be able to narrow down the section of code that’s causing the problem.

Accidental reply. See #16

Mushroom_man:
not sure how I would incorporate the reading of the sensor once for all 3 functions???

int humidity = bme280.readHumidity();

lcd.print(humidity, 2);

Serial.println(humidity);

if (humidity < SETPOINT - DEADBAND)

5m of CAT5 is probably too much for reliable I2C. It may be improved by careful choice of pairs for each function.

Stronger pullups, like 2.2k may also help with long wires.

MorganS:
5m of CAT5 is probably too much for reliable I2C. It may be improved by careful choice of pairs for each function.

Stronger pullups, like 2.2k may also help with long wires.

thanks for all the advice I have some adjustments to make to make sure this does not happen, please explain why you mean by careful choice of pairs

Basically: don't use the pairs. Use each pair as if it was a single wire, turning your 8-wire Cat6 cable into a 4-wire cable.