Objetivo y caso de uso
Qué construirás: Construirás un controlador automático de luz nocturna solar que activa un arreglo de LED de alta potencia al anochecer. Utiliza un LDR para la detección de luz ambiental y un divisor de voltaje con resistencias para monitorear activamente y proteger una batería de 12V contra descargas profundas.
Por qué es importante / Casos de uso
- Protección de la batería: Monitorea activamente el estado de la batería y corta la carga cuando el voltaje cae por debajo de los umbrales seguros (p. ej., < 10.5V), previniendo daños permanentes a las celdas de plomo-ácido o de iones de litio.
- Eficiencia energética: Utiliza un LDR con histéresis por software para asegurar que la iluminación se active solo cuando sea realmente necesario, evitando el parpadeo rápido y el desperdicio de energía durante las horas del crepúsculo.
- Automatización fuera de la red (Off-Grid): Forma la lógica autónoma central para la iluminación remota de paradas de autobús, cobertizos de jardín o luces de seguridad para senderos que operan de manera totalmente independiente de la red eléctrica.
- Control de potencia escalable: Utiliza un MOSFET de canal N de nivel lógico para demostrar cómo un microcontrolador de bajo consumo de 5V puede conmutar de manera segura grandes cargas de CC (hasta 5A/60W).
Resultado esperado
- Lectura precisa de voltaje: El Arduino escalará y medirá correctamente el voltaje de la batería de 12V a través del circuito divisor con un margen de error < 0.1V.
- Actuación confiable: Conmuta de forma fluida la carga del LED de alta potencia con una latencia < 10ms una vez que el LDR detecta el umbral de oscuridad objetivo.
- Preservación de la batería: Desconecta con éxito el arreglo de LED automáticamente cuando la capacidad de la batería cae al límite crítico de seguridad de 10.5V.
Audiencia: Desarrolladores de IoT, creadores de hardware y entusiastas de los sistemas fuera de la red; Nivel: Intermedio
Arquitectura/flujo: LDR & Divisor de voltaje (Sensores) → ADC de Arduino (Lógica/Procesamiento) → MOSFET de canal N (Interruptor) → Arreglo de LED de 12V (Salida)
Nota educativa de validación
Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. El validador comprobó los bloques de código, la estructura del artículo, los comandos copiables y la coherencia con el catálogo de dispositivos soportados.
Evidencia de validación publicada
- Resultado automático: PASS.
- Estructura parseada: 3 apartados, 2 tablas y 2 bloques de código detectados antes de publicar.
- Código comprobado: 1 Python/py_compile, 1 Arduino/arduino-cli compile.
- Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
- Hallazgos del informe: sin hallazgos bloqueantes.
Esta validación confirma compatibilidad sintáctica y de herramientas para el material publicado, pero no sustituye la prueba física sobre tu hardware, cableado y entorno exactos.
Nota educativa de seguridad
Este proyecto es un prototipo educativo de bajo voltaje, no un producto certificado. Antes de encender la configuración, verifique el cableado de su Arduino UNO R3, evite cortocircuitar 5 V, GND o los pines digitales, desconecte la alimentación antes de cambiar las conexiones y use módulos de interfaz adecuados para relés, motores o cargas externas.
Diagrama de bloques conceptual
Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema.
Arquitectura funcional
Flujo conceptual de señales y responsabilidades entre bloques del dispositivo.
Ruta de validación
Resumen conceptual de las herramientas usadas para comprobar el material publicado.
Requisitos previos
Para completar con éxito este tutorial, debe tener una comprensión básica de la Ley de Ohm (específicamente los cálculos del divisor de voltaje), programación fundamental en C++ para Arduino (variables, declaraciones if/else, millis() para la temporización) y familiaridad con el funcionamiento de una interfaz de línea de comandos. Debe tener instalado y configurado Arduino CLI en su computadora host.
Materiales
Necesitará los siguientes componentes exactos para construir este prototipo:
- Microcontrolador: Arduino UNO R3 (ATmega328P)
- Sensor de luz: 1x LDR estándar (Fotorresistencia)
- MOSFET: 1x IRLZ44N (MOSFET de potencia de canal N de nivel lógico)
- Resistencias (1/4 de vatio):
- 1x 30kΩ (Divisor de batería R1)
- 2x 10kΩ (Divisor de batería R2, LDR pull-down)
- 1x 10kΩ (Compuerta del MOSFET pull-down)
- 1x 220Ω (Limitador de corriente de la compuerta del MOSFET)
- Carga: 1x Arreglo de LED de 12V o tira de LED de 12V (Máximo 2 Amperios para pruebas en protoboard)
- Fuente de alimentación: 1x Batería de 12V (p. ej., paquete de iones de litio 3S o batería de plomo-ácido sellada de 12V)
- Prototipado: 1x Protoboard, cables puente macho a macho variados
Configuración/Conexión
Debido a que el Arduino UNO R3 funciona a 5V, no puede medir directamente una batería de 12V ni accionar una carga de 12V. Debemos utilizar circuitos de interfaz específicos.
1. El divisor de voltaje de la batería
El ADC de Arduino solo puede medir hasta 5V. Para medir una batería de 12V (que puede alcanzar hasta 14.4V durante la carga), usamos un divisor de voltaje. Conecte la resistencia de 30kΩ (R1) al terminal positivo de la batería (BAT+). Conecte el otro extremo de la resistencia de 30kΩ al pin A0 de Arduino. Conecte la resistencia de 10kΩ (R2) desde el pin A0 de Arduino a Tierra (GND).
Fórmula: Vout = Vin * (R2 / (R1 + R2)). A una entrada de 20V, A0 ve exactamente 5V. El factor de escala en el código será 4.0.
2. El divisor del LDR
Conecte una pata del LDR al pin de 5V de Arduino. Conecte la otra pata del LDR al pin A1 de Arduino. Conecte una resistencia de 10kΩ desde el pin A1 de Arduino a Tierra (GND).
Comportamiento: En luz brillante, la resistencia del LDR disminuye, acercando A1 a 5V. En la oscuridad, la resistencia del LDR aumenta y la resistencia de 10kΩ acerca A1 a 0V.
3. El controlador LED MOSFET
Sostenga el MOSFET IRLZ44N de modo que la pestaña de metal quede en la parte posterior y el texto lo mire a usted. Los pines de izquierda a derecha son Compuerta (Gate) (1), Drenador (Drain) (2) y Surtidor (Source) (3).
* Conecte el Pin 9 de Arduino a una resistencia de 220Ω, luego a la Compuerta del MOSFET.
* Conecte una resistencia de 10kΩ desde la Compuerta del MOSFET directamente a Tierra (esto evita que el LED parpadee mientras el Arduino arranca).
* Conecte el Surtidor del MOSFET a Tierra.
* Conecte el Drenador del MOSFET al cable negativo (Cátodo) de su arreglo de LED de 12V.
* Conecte el cable positivo (Ánodo) de su arreglo de LED de 12V directamente al terminal positivo de la batería (BAT+).
4. Tierra común
Asegúrese de que el GND del Arduino, el terminal negativo de la batería, el Surtidor del MOSFET y todas las conexiones a tierra del divisor estén unidas en el riel negativo de la protoboard.
Tabla de asignación de pines
| Pin de Arduino UNO R3 | Conexión del componente | Función |
|---|---|---|
| A0 | Unión de resistencias de 30kΩ y 10kΩ | Detección de voltaje de la batería |
| A1 | Unión del LDR y resistencia de 10kΩ | Detección de luz ambiental |
| Pin 9 (PWM) | Resistencia de 220Ω → Compuerta del MOSFET | Brillo / Conmutación del LED |
| 5V | Pata superior del LDR | Voltaje de referencia para el LDR |
| GND | Riel de tierra común | Retorno del sistema / Referencia |
| VIN | No conectado en esta prueba | Alimentar Arduino vía USB para pruebas |
Código validado
La siguiente sección contiene dos archivos. El primero es el firmware en C++ para el Arduino UNO R3. El segundo es un script de Python opcional que se ejecuta en su computadora para registrar los datos en serie del Arduino en un archivo CSV, lo cual es muy útil para validar la curva de descarga de la batería y los puntos de conmutación.
Firmware de Arduino: solar_night_light.ino
Cree una carpeta llamada solar_night_light y coloque este código dentro de un archivo llamado solar_night_light.ino.
Vista pública parcial del archivo validado. El código completo se muestra a miembros y en PDF/Print.
/*
* Solar Night Light Controller
* Target: Arduino UNO R3 (ATmega328P)
* Purpose: Controls a 12V LED via MOSFET based on LDR light levels,
* incorporating Low Voltage Disconnect (LVD) for battery protection.
*/
// --- Hardware Pins ---
const int PIN_BATTERY_SENSE = A0;
const int PIN_LIGHT_SENSE = A1;
const int PIN_LED_DRIVE = 9;
// --- Calibration & Thresholds ---
// Voltage Divider: R1 = 30k, R2 = 10k. Ratio = (30+10)/10 = 4.0
const float VOLTAGE_DIVIDER_RATIO = 4.0;
const float ADC_REFERENCE_VOLTAGE = 5.0;
const float ADC_MAX_VALUE = 1023.0;
// Battery Thresholds (12V Lead-Acid / 3S Li-ion example)
const float BATT_LVD_DISCONNECT = 10.5; // Turn off below 10.5V
const float BATT_LVD_RECONNECT = 11.5; // Require 11.5V to turn back on
// Light Thresholds (0-1023). Higher value = brighter ambient light.
const int LIGHT_THRESHOLD_DARK = 300; // Below this is considered night
const int LIGHT_THRESHOLD_LIGHT = 450; // Above this is considered day
// --- System State ---
enum SystemState {
STATE_DAYTIME,
STATE_NIGHT_ON,
STATE_LOW_BATTERY
};
SystemState currentState = STATE_DAYTIME;
// --- Timing ---
unsigned long lastLogTime = 0;
const unsigned long LOG_INTERVAL_MS = 1000;
void setup() {
Serial.begin(115200);
pinMode(PIN_BATTERY_SENSE, INPUT);
pinMode(PIN_LIGHT_SENSE, INPUT);
// Initialize MOSFET drive pin
pinMode(PIN_LED_DRIVE, OUTPUT);
analogWrite(PIN_LED_DRIVE, 0); // Ensure LED is OFF at boot
Serial.println("Solar Night Light Controller Initialized.");
Serial.println("Timestamp_ms,Battery_V,Light_ADC,State,PWM_Out");
}
void loop() {
// 1. Read Sensors
int rawBatteryADC = analogRead(PIN_BATTERY_SENSE);
int rawLightADC = analogRead(PIN_LIGHT_SENSE);
// 2. Calculate Real Voltage
float pinVoltage = (rawBatteryADC / ADC_MAX_VALUE) * ADC_REFERENCE_VOLTAGE;
float batteryVoltage = pinVoltage * VOLTAGE_DIVIDER_RATIO;
// 3. State Machine Logic
switch (currentState) {
case STATE_DAYTIME:
// Transition to NIGHT if it gets dark AND battery is healthy
if (rawLightADC < LIGHT_THRESHOLD_DARK) {
if (batteryVoltage > BATT_LVD_RECONNECT) {
currentState = STATE_NIGHT_ON;
} else {
currentState = STATE_LOW_BATTERY; // Too dark, but battery is dead
}
// .../*
* Solar Night Light Controller
* Target: Arduino UNO R3 (ATmega328P)
* Purpose: Controls a 12V LED via MOSFET based on LDR light levels,
* incorporating Low Voltage Disconnect (LVD) for battery protection.
*/
// --- Hardware Pins ---
const int PIN_BATTERY_SENSE = A0;
const int PIN_LIGHT_SENSE = A1;
const int PIN_LED_DRIVE = 9;
// --- Calibration & Thresholds ---
// Voltage Divider: R1 = 30k, R2 = 10k. Ratio = (30+10)/10 = 4.0
const float VOLTAGE_DIVIDER_RATIO = 4.0;
const float ADC_REFERENCE_VOLTAGE = 5.0;
const float ADC_MAX_VALUE = 1023.0;
// Battery Thresholds (12V Lead-Acid / 3S Li-ion example)
const float BATT_LVD_DISCONNECT = 10.5; // Turn off below 10.5V
const float BATT_LVD_RECONNECT = 11.5; // Require 11.5V to turn back on
// Light Thresholds (0-1023). Higher value = brighter ambient light.
const int LIGHT_THRESHOLD_DARK = 300; // Below this is considered night
const int LIGHT_THRESHOLD_LIGHT = 450; // Above this is considered day
// --- System State ---
enum SystemState {
STATE_DAYTIME,
STATE_NIGHT_ON,
STATE_LOW_BATTERY
};
SystemState currentState = STATE_DAYTIME;
// --- Timing ---
unsigned long lastLogTime = 0;
const unsigned long LOG_INTERVAL_MS = 1000;
void setup() {
Serial.begin(115200);
pinMode(PIN_BATTERY_SENSE, INPUT);
pinMode(PIN_LIGHT_SENSE, INPUT);
// Initialize MOSFET drive pin
pinMode(PIN_LED_DRIVE, OUTPUT);
analogWrite(PIN_LED_DRIVE, 0); // Ensure LED is OFF at boot
Serial.println("Solar Night Light Controller Initialized.");
Serial.println("Timestamp_ms,Battery_V,Light_ADC,State,PWM_Out");
}
void loop() {
// 1. Read Sensors
int rawBatteryADC = analogRead(PIN_BATTERY_SENSE);
int rawLightADC = analogRead(PIN_LIGHT_SENSE);
// 2. Calculate Real Voltage
float pinVoltage = (rawBatteryADC / ADC_MAX_VALUE) * ADC_REFERENCE_VOLTAGE;
float batteryVoltage = pinVoltage * VOLTAGE_DIVIDER_RATIO;
// 3. State Machine Logic
switch (currentState) {
case STATE_DAYTIME:
// Transition to NIGHT if it gets dark AND battery is healthy
if (rawLightADC < LIGHT_THRESHOLD_DARK) {
if (batteryVoltage > BATT_LVD_RECONNECT) {
currentState = STATE_NIGHT_ON;
} else {
currentState = STATE_LOW_BATTERY; // Too dark, but battery is dead
}
}
// Transition to LOW_BATTERY if voltage drops even during day
if (batteryVoltage < BATT_LVD_DISCONNECT) {
currentState = STATE_LOW_BATTERY;
}
break;
case STATE_NIGHT_ON:
// Transition back to DAYTIME if light returns
if (rawLightADC > LIGHT_THRESHOLD_LIGHT) {
currentState = STATE_DAYTIME;
}
// Transition to LOW_BATTERY if voltage drops below safe limit
if (batteryVoltage < BATT_LVD_DISCONNECT) {
currentState = STATE_LOW_BATTERY;
}
break;
case STATE_LOW_BATTERY:
// Only recover from Low Battery if voltage rises above reconnect threshold
if (batteryVoltage > BATT_LVD_RECONNECT) {
if (rawLightADC > LIGHT_THRESHOLD_LIGHT) {
currentState = STATE_DAYTIME;
} else {
currentState = STATE_NIGHT_ON;
}
}
break;
}
// 4. Actuate Outputs
int pwmValue = 0;
if (currentState == STATE_NIGHT_ON) {
pwmValue = 255; // 100% duty cycle (Full brightness)
}
analogWrite(PIN_LED_DRIVE, pwmValue);
// 5. Telemetry Logging (Non-blocking)
unsigned long currentMillis = millis();
if (currentMillis - lastLogTime >= LOG_INTERVAL_MS) {
lastLogTime = currentMillis;
Serial.print(currentMillis);
Serial.print(",");
Serial.print(batteryVoltage, 2);
Serial.print(",");
Serial.print(rawLightADC);
Serial.print(",");
if (currentState == STATE_DAYTIME) Serial.print("DAYTIME");
else if (currentState == STATE_NIGHT_ON) Serial.print("NIGHT_ON");
else if (currentState == STATE_LOW_BATTERY) Serial.print("LOW_BATT");
Serial.print(",");
Serial.println(pwmValue);
}
}
Script registrador de puerto serie: serial_logger.py
Este script de Python lee la salida en serie en formato CSV del Arduino y la guarda en un archivo. Guarde esto en el mismo directorio que la carpeta de su proyecto de Arduino.
#!/usr/bin/env python3
"""
Serial Logger for Solar Night Light Controller
Reads CSV telemetry from Arduino and writes to 'telemetry.csv'
Requires: pip install pyserial
"""
import serial
import time
import argparse
def main():
parser = argparse.ArgumentParser(description="Log Arduino Serial Data to CSV")
parser.add_add_argument("--port", required=True, help="Serial port (e.g., COM3 or /dev/ttyACM0)")
parser.add_argument("--baud", type=int, default=115200, help="Baud rate")
args = parser.parse_args()
try:
ser = serial.Serial(args.port, args.baud, timeout=2)
print(f"Connected to {args.port} at {args.baud} baud.")
with open("telemetry.csv", "w") as f:
while True:
if ser.in_waiting > 0:
line = ser.readline().decode('utf-8').strip()
print(line)
if "Initialized" not in line:
f.write(line + "\n")
f.flush()
except serial.SerialException as e:
print(f"Error opening serial port: {e}")
except KeyboardInterrupt:
print("\nLogging stopped by user.")
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
if __name__ == "__main__":
main()
Comandos de compilación/flasheo/ejecución
Use Arduino CLI para compilar y flashear el firmware en su Arduino UNO R3. Asegúrese de que su Arduino esté conectado a través de USB.
Tabla de comandos
| Comando | Propósito |
|---|---|
arduino-cli core update-index | Actualiza la lista de núcleos de Arduino disponibles |
arduino-cli core install arduino:avr | Instala el núcleo requerido para el UNO R3 |
arduino-cli compile --fqbn arduino:avr:uno | Compila el sketch solar_night_light.ino |
arduino-cli upload --fqbn arduino:avr:uno --port <PORT> | Flashea el binario compilado en la placa |
Flujo de trabajo
- Obra su terminal y navegue hasta el directorio que contiene la carpeta
solar_night_light. - Asegúrese de que su núcleo esté actualizado:
arduino-cli core update-index
arduino-cli core install arduino:avr - Compile el firmware:
arduino-cli compile --fqbn arduino:avr:uno solar_night_light - Identifique su puerto (p. ej.,
COM3en Windows o/dev/ttyACM0en Linux). - Suba el firmware:
arduino-cli upload --fqbn arduino:avr:uno --port /dev/ttyACM0 solar_night_light - Inicie el registrador de Python para monitorear la salida (reemplace el puerto con su puerto real):
python3 serial_logger.py --port /dev/ttyACM0
Validación paso a paso
Realice estas comprobaciones para validar el funcionamiento lógico y eléctrico del controlador. Mantenga el registrador de Python en ejecución para poder observar el estado del sistema.
- Comprobación de calibración de voltaje del ADC
- Acción: Conecte una fuente de voltaje conocida (p. ej., una batería de 12V o fuente de alimentación de banco) a la entrada del divisor de la batería. Mida el voltaje real de la batería con un multímetro digital (DMM).
- Observación esperada: La columna
Battery_Ven la salida en serie debe coincidir con la lectura del DMM con una diferencia de ±0.2V. - Condición de aprobación: El Arduino escala con precisión la lectura analógica al voltaje del mundo real.
- Verificación del estado diurno
- Acción: Ilumine el LDR directamente con una linterna o luz de habitación brillante. Asegúrese de que el voltaje de la batería esté por encima de 11.5V.
- Observación esperada: La salida en serie reporta
DAYTIME,PWM_Outes0. El arreglo de LED de 12V permanece completamente apagado. - Condición de aprobación: El sistema identifica correctamente el día y desactiva la carga.
- Transición al anochecer e histéresis
- Acción: Cubra lentamente el LDR con su mano para simular el anochecer.
- Observación esperada:
Light_ADCdisminuye. Una vez que cae por debajo de300, el estado cambia aNIGHT_ONyPWM_Outsalta a255. El arreglo de LED se enciende. Descubrir ligeramente el LDR (el ADC sube a 350) no apaga el LED. - Condición de aprobación: El LED se enciende en la oscuridad y la banda muerta (300 a 450) evita que el LED parpadee en el umbral exacto.
- Activación de desconexión por bajo voltaje (LVD)
- Acción: Mientras está en el estado
NIGHT_ON, simule una batería agotándose reduciendo el voltaje de entrada al divisor por debajo de 10.5V (usando una fuente de alimentación variable o cambiando temporalmente la resistencia de 30kΩ por una de mayor valor). - Observación esperada: El estado cambia inmediatamente a
LOW_BATT.PWM_Outcae a0. El arreglo de LED se apaga. - Condición de aprobación: El controlador protege con éxito la batería al cortar la carga.
- Acción: Mientras está en el estado
- Bloqueo de reconexión del LVD
- Acción: Aumente el voltaje de entrada ligeramente a 11.0V.
- Observación esperada: El sistema permanece
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.




