#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.
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 ).
Parece que es más difícil encontrar una falla en un cable eléctrico que una falla en un arduino.
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
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...
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
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"
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