Uso de doble comunicacion por I2C con pantalla LCD con modulo I2C y sensor BH1750

#include <Wire.h>
#include <BH1750.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>

BH1750 sensor;
Servo servoMotor;
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address may vary, use 0x27 or check your LCD documentation

const int LUX_THRESHOLD = 200;
const int SERVO_MIN_ANGLE = 80;
const int SERVO_MAX_ANGLE = 100;
const int SERVO_DURATION = 5000; // 5 seconds

const int BUTTON1_PIN = 2; // Button 1 connected to pin 2
const int BUTTON2_PIN = 3; // Button 2 connected to pin 3

bool button1Pressed = false;
bool button2Pressed = false;
unsigned long button1PressTime = 0;
unsigned long button2PressTime = 0;

void setup() {
  Serial.begin(9600);
  sensor.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);//Sensor mode
  servoMotor.attach(9);
  lcd.init(); //Start LCD
  lcd.backlight();
  lcd.begin(16, 2);
  pinMode(BUTTON1_PIN, INPUT_PULLUP);
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
}

void loop() {
  // Check if button 1 is pressed
  if (digitalRead(BUTTON1_PIN) == LOW) {
    if (!button1Pressed) {
      button1Pressed = true;
      button1PressTime = millis();
    }
  } else {
    if (button1Pressed && (millis() - button1PressTime) >= SERVO_DURATION) {
      button1Pressed = false;
    }
  }

  // Check if button 2 is pressed
  if (digitalRead(BUTTON2_PIN) == LOW) {
    if (!button2Pressed) {
      button2Pressed = true;
      button2PressTime = millis();
    }
  } else {
    if (button2Pressed && (millis() - button2PressTime) >= SERVO_DURATION) {
      button2Pressed = false;
    }
  }

  // Read the lux value from the sensor
  unsigned int lux = sensor.readLightLevel();
  Serial.print("Lux: ");
  Serial.println(lux);
  
  // Display the lux value on the LCD
  lcd.setCursor(7, 0);
  lcd.print(lux);
  delay(2000);
  lcd.setCursor(0, 0);
  lcd.print("Luxes");
  //lcd.setCursor(0, 0);
  //lcd.print("                ");
  
  // Adjust the servomotor position based on lux value and button status
  if (button1Pressed) {
    servoMotor.write(SERVO_MAX_ANGLE);
    Serial.println("Button 1 pressed. Servo at 100 degrees");
  } else if (button2Pressed) {
    servoMotor.write(SERVO_MIN_ANGLE);
    Serial.println("Button 2 pressed. Servo at 80 degrees");
  } else {
    if (lux >= LUX_THRESHOLD) {
      servoMotor.write(SERVO_MIN_ANGLE);
      Serial.println("Sensor detected lux >= 200. Servo at 80 degrees");
    } else {
      servoMotor.write(SERVO_MAX_ANGLE);
      Serial.println("Sensor detected lux < 200. Servo at 100 degrees");
    }
  }

  delay(100);
}

He estado usando este código para medir la cantidad luxes en una habitacion y a partir de ello mover un servomotor y que a su vez esta lectura la escriba en la pantalla LCD, a su vez he hecho el monitoreo en monitor serie para comprobar las lecturas; pero al momento que pongo a funcionar el codigo con ambas cosas a la vez en el monitor serie arroja error en el sensor y la pantalla no imprime nada, hasta que desconecto la pantalla y lo reinicio y despues la vuelvo a conectar no se si sea un error por usar ambas cosas a la vez y si exista una manera para solucionarlo

He trasladado su tema de una categoría de idioma inglés del foro a la categoría International > Español @joza101420.

En adelante por favor usar la categoría apropiada a la lengua en que queráis publicar. Esto es importante para el uso responsable del foro, y esta explicado aquí la guía "How to get the best out of this forum".
Este guía contiene mucha información útil. Por favor leer.

De antemano, muchas gracias por cooperar.

Si pruebas el BH1750 solo, te da error?

Moderador:
Bueno, ten cuidado donde publicas porque lo has hecho en el foro en inglés usando idioma español.

Si, por si solo si funciona, crea confusion al momento de conectar la pantalla LCD
De hecho, la parte del funcionamiento "manual" (con los botones) no esta funcionando solo efectua la parte "automatica" con el sensor

Si, no me habia percado de ese error ya no sucedera

Tenés un adaptador de niveles?
Si lo tenés, hacé la prueba de ponerlo entre los pines SCL y SDA del sensor solamente.
El problema podría venir por ese lado porque el BH1750 trabaja a 3.3V (por eso tiene regulador) y las resistencias pull-up están conectadas a 3.3V.
En cambio, la pantalla trabaja con 5V y sus resistencias pull-up están conectadas a 5V.
Ojo, es una teoría, no sé si estoy acertado.

Lamento que tengo ambas cosas y podría probarlo pero en casa tenemos un corte de energía desde hace ya 7 días :face_with_symbols_over_mouth:).
Parece que es más difícil encontrar una falla en un cable eléctrico que una falla en un arduino. :rage:

Agrego: Como no vas a poder tomar los 3V3 de la placa del BH, tomalos del arduino, poné una R de 330 o 220 en serie por las dudas.

no cuento con un adaptador de niveles, se me ocurria no se si se pueda, como estoy usando arduino uno, hacer la conexion del sensor directamente al pin de 3.3 V de arduino
No vi la actualizacion jeje, lo intentare asi

Lamento lo de su electricidad :sweat_smile:

No, si no tenés el adaptador no hagas nada.
El BH1750 trae el regulador de 3V entonces hay que alimentarlo con 5V.

Dos diodos tipo 1N4147 o similar tenés?
Podés probar poniendo uno en el pin SCL del BH con el cátodo (la rayita) hacia el lado del arduino y en el pin SDA el otro pero invertido, o sea con el cátodo hacia el BH.
De nuevo, puede no dar resultado...

image
sigue igual, es este anuncio el que me aparece en el monitor serial, por otro lado la pantalla imprime "Luxes:" y su tope que es 65534

Eso es con los diodos?

Asi es, sigue funcionando bien solo desconectando la pantalla LCD y despues que sensa bien, la conecto de nuevo y funciona bien

Probá, solo por probar, mover

lcd.init();

antes de

sensor.begin(...

image
o si se te complica
image

wow ya funciona esa parte
Ahora la parte de los botones no la esta respetando :melting_face:

Ya me di cuenta por que no funciona tu código tal y como está.
Si miras los ejemplos de la librería BH1750 en todos primero inicializan Wire

O sea,

Wire.begin();
sensor.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);

Como LiquidCrystal_I2C inicializa Wire, no hace falta hacerlo explícitamente, pero BH1750 no lo hace.
Al cambiar el orden ya Wire está iniciada por LiquidCrystal_I2C.
Si quieres dejar el código como lo tenías agrega

Wire.begin();

al principio de setup() antes de iniciar el BH.

1 Like

Si, ya funcionan ambos, gracias

Solo que la pate de los botones ya no funciona, eso solo es para activar el servomotor manualmente cuando se requiera

Y qué tal si sacas el delay de 2 segundos?

Ya con las modificaciones el codigo va de la siguiente manera:

#include <Wire.h>
#include <BH1750.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>

BH1750 sensor;
Servo servoMotor;
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address may vary, use 0x27

const int LUX_THRESHOLD = 200;
const int SERVO_MIN_ANGLE = 80;
const int SERVO_MAX_ANGLE = 100;
const int SERVO_DURATION = 5000; // 5 seconds

const int BUTTON1_PIN = 2; // Button 1 connected to pin 2
const int BUTTON2_PIN = 3; // Button 2 connected to pin 3

bool button1Pressed = false;
bool button2Pressed = false;
unsigned long button1PressTime = 0;
unsigned long button2PressTime = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  sensor.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);//Sensor mode
  servoMotor.attach(9);
  lcd.init(); //Start LCD
  lcd.backlight();
  lcd.begin(16, 2);
  pinMode(BUTTON1_PIN, INPUT_PULLUP);
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
}

void loop() {
  // Check if button 1 is pressed
  if (digitalRead(BUTTON1_PIN) == LOW) {
    if (!button1Pressed) {
      button1Pressed = true;
      button1PressTime = millis();
    }
  } else {
    if (button1Pressed && (millis() - button1PressTime) >= SERVO_DURATION) {
      button1Pressed = false;
    }
  }

  // Check if button 2 is pressed
  if (digitalRead(BUTTON2_PIN) == LOW) {
    if (!button2Pressed) {
      button2Pressed = true;
      button2PressTime = millis();
    }
  } else {
    if (button2Pressed && (millis() - button2PressTime) >= SERVO_DURATION) {
      button2Pressed = false;
    }
  }

  // Read the lux value from the sensor
  unsigned int lux = sensor.readLightLevel();
  Serial.print("Lux: ");
  Serial.println(lux);
  
  // Display the lux value on the LCD
  lcd.setCursor(7, 0);
  lcd.print(lux);
  //delay(2000);
  lcd.setCursor(0, 0);
  lcd.print("Luxes");
  //lcd.setCursor(0, 0);
  //lcd.print("                ");
  
  // Adjust the servomotor position based on lux value and button status
  if (button1Pressed) {
    servoMotor.write(SERVO_MAX_ANGLE);
    Serial.println("Button 1 pressed. Servo at 100 degrees");
  } else if (button2Pressed) {
    servoMotor.write(SERVO_MIN_ANGLE);
    Serial.println("Button 2 pressed. Servo at 80 degrees");
  } else {
    if (lux >= LUX_THRESHOLD) {
      servoMotor.write(SERVO_MIN_ANGLE);
      Serial.println("Sensor detected lux >= 200. Servo at 80 degrees");
    } else {
      servoMotor.write(SERVO_MAX_ANGLE);
      Serial.println("Sensor detected lux < 200. Servo at 100 degrees");
    }
  }

  delay(100);
}

Y es donde sigue sin respetar las acciones que le platico, porque de hecho para este modo "manual" estoy poniendo el tiempo de cambio en caso de pulsar boton de 5 segundos para prueba ya que final el tiempo debe de ser de 25 minutos y despues regresar al modo "automatico"

Aclara qué es lo que no hace porque no queda claro.
¿No detecta la pulsacion?
¿No respeta el tiempo?

Igual le platico desde el principio, es un sistema que cuando el sensor detecta arriba de 200 lx mueve el servomotor a una posicion de lo contrario se queda en una posicion inicial
Eso engloba el funcionamiento automatico
Para el manual, estan los botones, hay uno para que cuando el sensor no detecta mas de 200 lx se haga de manera manual y se quede en esa posicion durante 25 minutos (5 segundos para la prueba), caso contrario si el sensor detecta arriba de 200 lx y se quiere regresar a la posicion inicial esta el otro boton

Ahora lo que no hace el programa es que no detecta la pulsacion, el modo "manual" esta obsoleto

Aunque suene obvio: ¿Conectaste los pulsadores a masa?
Pon una impresión luego de cada

if(digitalRead(...

a ver si es que nunca detecta las pulsaciones.

El código parece estar bien, no veo nada raro.