WiFi Camera with Motion Detection Reference Design
Controls
Availability & Pricing
Distributor | Qty 1 | |
---|---|---|
Digi-Key | $0.04–$36.00 | |
LCSC | $0.00–$0.03 |
Assets
id=WiFi Camera with Motion Detection-removebg-preview
Simulation
Image
BluetoothSerial
para la comunicación.Explicación del CódigoCpp
#include <BluetoothSerial.h> // Crear una instancia para el puerto serie Bluetooth BluetoothSerial SerialBT; // Pines del ESP32 const int pinSensorLlama = 14; const int pinMotorA1 = 32; const int pinMotorA2 = 33; const int pinMotorB1 = 25; const int pinMotorB2 = 26; const int pinBombaAgua = 27; // Variables bool robotIniciado = false; bool fuegoDetectado = false; void setup() { // Iniciar comunicación serie para depuración Serial.begin(115200); // Iniciar comunicación Bluetooth SerialBT.begin("Robot_Bluetooth"); Serial.println("El Bluetooth se ha iniciado correctamente"); // Configurar pines de entrada y salida pinMode(pinSensorLlama, INPUT); pinMode(pinMotorA1, OUTPUT); pinMode(pinMotorA2, OUTPUT); pinMode(pinMotorB1, OUTPUT); pinMode(pinMotorB2, OUTPUT); pinMode(pinBombaAgua, OUTPUT); // Apagar motores y bomba inicialmente detenerMotores(); digitalWrite(pinBombaAgua, LOW); } void loop() { // Revisar si hay datos recibidos a través de Bluetooth if (SerialBT.available()) { char datoRecibido = SerialBT.read(); // Comandos de control para el robot if (datoRecibido == 'I') { robotIniciado = !robotIniciado; // Alternar el estado del robot SerialBT.println("Estado del robot: " + String(robotIniciado ? "Iniciado" : "Detenido")); } else if (robotIniciado) { controlarMotores(datoRecibido); } } // Detectar fuego fuegoDetectado = digitalRead(pinSensorLlama) == HIGH; // Accionar bomba de agua si se detecta fuego if (fuegoDetectado) { activarBombaAgua(); } else { detenerBombaAgua(); } } void controlarMotores(char comando) { switch (comando) { case 'A': // Adelante moverAdelante(); break; case 'R': // Retroceder moverAtras(); break; case 'I': // Izquierda girarIzquierda(); break; case 'D': // Derecha girarDerecha(); break; case 'S': // Stop detenerMotores(); break; } } void moverAdelante() { digitalWrite(pinMotorA1, HIGH); digitalWrite(pinMotorA2, LOW); digitalWrite(pinMotorB1, HIGH); digitalWrite(pinMotorB2, LOW); } void moverAtras() { digitalWrite(pinMotorA1, LOW); digitalWrite(pinMotorA2, HIGH); digitalWrite(pinMotorB1, LOW); digitalWrite(pinMotorB2, HIGH); } void girarIzquierda() { digitalWrite(pinMotorA1, LOW); digitalWrite(pinMotorA2, HIGH); digitalWrite(pinMotorB1, HIGH); digitalWrite(pinMotorB2, LOW); } void girarDerecha() { digitalWrite(pinMotorA1, HIGH); digitalWrite(pinMotorA2, LOW); digitalWrite(pinMotorB1, LOW); digitalWrite(pinMotorB2, HIGH); } void detenerMotores() { digitalWrite(pinMotorA1, LOW); digitalWrite(pinMotorA2, LOW); digitalWrite(pinMotorB1, LOW); digitalWrite(pinMotorB2, LOW); } void activarBombaAgua() { digitalWrite(pinBombaAgua, HIGH); } void detenerBombaAgua() { digitalWrite(pinBombaAgua, LOW); }
Serial Bluetooth Terminal
).Explicación del códigoCpp
#include <BluetoothSerial.h> #include <Servo.h> #include <NewPing.h> #include <DHT.h> #define TRIG_PIN 5 #define ECHO_PIN 18 #define MAX_DISTANCE 200 // Distancia máxima a medir (en cm) #define MOTOR1_PIN1 12 #define MOTOR1_PIN2 14 #define MOTOR2_PIN1 27 #define MOTOR2_PIN2 26 #define ENABLE_PIN 13 #define SERVO_PIN 23 #define RAIN_SENSOR_PIN 4 #define DHT_PIN 19 #define DHT_TYPE DHT11 BluetoothSerial SerialBT; Servo myservo; NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); DHT dht(DHT_PIN, DHT_TYPE); bool isRobotActive = false; int servoPos = 0; float rainThreshold = 300.0; // Ajusta el valor según el sensor void setup() { Serial.begin(115200); SerialBT.begin("ESP32_FoodRobot"); // Configura el nombre Bluetooth pinMode(MOTOR1_PIN1, OUTPUT); pinMode(MOTOR1_PIN2, OUTPUT); pinMode(MOTOR2_PIN1, OUTPUT); pinMode(MOTOR2_PIN2, OUTPUT); pinMode(ENABLE_PIN, OUTPUT); pinMode(RAIN_SENSOR_PIN, INPUT); myservo.attach(SERVO_PIN); dht.begin(); } void loop() { if (SerialBT.available()) { char command = SerialBT.read(); if (command == 'S') { // 'S' para Start isRobotActive = true; SerialBT.println("Robot iniciado"); } else if (command == 'P') { // 'P' para Parar isRobotActive = false; SerialBT.println("Robot detenido"); stopRobot(); } } if (isRobotActive) { checkForRain(); detectAndFeed(); avoidObstacles(); } } void checkForRain() { float rainValue = analogRead(RAIN_SENSOR_PIN); if (rainValue > rainThreshold) { SerialBT.println("Lluvia detectada. Moviendo el robot a cubierta."); moveToShelter(); } } void detectAndFeed() { float distance = sonar.ping_cm(); if (distance > 0 && distance < 50) { // Ajusta según preferencia SerialBT.println("Mascota detectada. Dispensando comida."); dispenseFood(); } } void avoidObstacles() { float distance = sonar.ping_cm(); if (distance > 0 && distance < 30) { // Ajusta según preferencia SerialBT.println("Obstáculo detectado. Esquivando."); maneuverAroundObstacle(); } } void moveToShelter() { digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(2000); // Ajusta el tiempo según la distancia a la cubierta stopRobot(); } void dispenseFood() { myservo.write(90); // Abrir paso de comida delay(2000); // Tiempo suficiente para dispensar comida myservo.write(0); // Cerrar paso de comida } void maneuverAroundObstacle() { // Ejemplo sencillo de maniobra de evasión digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, HIGH); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(500); // Ajusta según sea necesario digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(1000); } void stopRobot() { digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, LOW); digitalWrite(MOTOR2_PIN2, LOW); }
setup()
.Explicación del código con variables en españolCpp
#include <BluetoothSerial.h> #include <Servo.h> #include <NewPing.h> #include <DHT.h> #define PIN_TRIG 5 #define PIN_ECHO 18 #define DISTANCIA_MAXIMA 200 // Distancia máxima a medir (en cm) #define MOTOR1_PIN1 12 #define MOTOR1_PIN2 14 #define MOTOR2_PIN1 27 #define MOTOR2_PIN2 26 #define PIN_HABILITAR 13 #define PIN_SERVO 23 #define PIN_SENSOR_LLUVIA 4 #define PIN_DHT 19 #define TIPO_DHT DHT11 BluetoothSerial SerialBT; Servo miServo; NewPing sonar(PIN_TRIG, PIN_ECHO, DISTANCIA_MAXIMA); DHT dht(PIN_DHT, TIPO_DHT); bool robotActivo = false; int posicionServo = 0; float umbralLluvia = 300.0; // Ajusta el valor según el sensor void setup() { Serial.begin(115200); SerialBT.begin("ESP32_RobotAlimentaMascotas"); // Configura el nombre Bluetooth pinMode(MOTOR1_PIN1, OUTPUT); pinMode(MOTOR1_PIN2, OUTPUT); pinMode(MOTOR2_PIN1, OUTPUT); pinMode(MOTOR2_PIN2, OUTPUT); pinMode(PIN_HABILITAR, OUTPUT); pinMode(PIN_SENSOR_LLUVIA, INPUT); miServo.attach(PIN_SERVO); dht.begin(); } void loop() { if (SerialBT.available()) { char comando = SerialBT.read(); if (comando == 'I') { // 'I' para Iniciar robotActivo = true; SerialBT.println("Robot iniciado"); } else if (comando == 'P') { // 'P' para Parar robotActivo = false; SerialBT.println("Robot detenido"); detenerRobot(); } } if (robotActivo) { verificarLluvia(); detectarYAlimentar(); evitarObstaculos(); } } void verificarLluvia() { float valorLluvia = analogRead(PIN_SENSOR_LLUVIA); if (valorLluvia > umbralLluvia) { SerialBT.println("Lluvia detectada. Moviendo el robot a cubierta."); moverAlRefugio(); } } void detectarYAlimentar() { float distancia = sonar.ping_cm(); if (distancia > 0 && distancia < 50) { // Ajusta según preferencia SerialBT.println("Mascota detectada. Dispensando comida."); dispensarComida(); } } void evitarObstaculos() { float distancia = sonar.ping_cm(); if (distancia > 0 && distancia < 30) { // Ajusta según preferencia SerialBT.println("Obstáculo detectado. Esquivando."); maniobrarAlrededorDelObstaculo(); } } void moverAlRefugio() { digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(2000); // Ajusta el tiempo según la distancia a la cubierta detenerRobot(); } void dispensarComida() { miServo.write(90); // Abrir paso de comida delay(2000); // Tiempo suficiente para dispensar comida miServo.write(0); // Cerrar paso de comida } void maniobrarAlrededorDelObstaculo() { // Ejemplo sencillo de maniobra de evasión digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, HIGH); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(500); // Ajusta según sea necesario digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(1000); } void detenerRobot() { digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, LOW); digitalWrite(MOTOR2_PIN2, LOW); }
setup()
.Image
Conexiones 1. Conexiones del Sensor Ultrasónico (HC-SR04)Cpp
#include <BluetoothSerial.h> #include <Servo.h> #include <NewPing.h> #include <DHT.h> #define PIN_TRIG 5 #define PIN_ECHO 18 #define DISTANCIA_MAXIMA 200 // Distancia máxima a medir (en cm) #define MOTOR1_PIN1 12 #define MOTOR1_PIN2 14 #define MOTOR2_PIN1 27 #define MOTOR2_PIN2 26 #define PIN_HABILITAR 13 #define PIN_SERVO 23 #define PIN_DHT 19 #define TIPO_DHT DHT11 BluetoothSerial SerialBT; Servo miServo; NewPing sonar(PIN_TRIG, PIN_ECHO, DISTANCIA_MAXIMA); DHT dht(PIN_DHT, TIPO_DHT); bool robotActivo = false; float umbralHumedad = 80.0; // Ajusta el valor de umbral de humedad según el ambiente void setup() { Serial.begin(115200); SerialBT.begin("ESP32_RobotAlimentaMascotas"); // Configura el nombre Bluetooth pinMode(MOTOR1_PIN1, OUTPUT); pinMode(MOTOR1_PIN2, OUTPUT); pinMode(MOTOR2_PIN1, OUTPUT); pinMode(MOTOR2_PIN2, OUTPUT); pinMode(PIN_HABILITAR, OUTPUT); miServo.attach(PIN_SERVO); dht.begin(); } void loop() { if (SerialBT.available()) { char comando = SerialBT.read(); if (comando == 'I') { // 'I' para Iniciar robotActivo = true; SerialBT.println("Robot iniciado"); } else if (comando == 'P') { // 'P' para Parar robotActivo = false; SerialBT.println("Robot detenido"); detenerRobot(); } } if (robotActivo) { verificarLluvia(); detectarYAlimentar(); evitarObstaculos(); } } void verificarLluvia() { float humedad = dht.readHumidity(); if (isnan(humedad)) { Serial.println("Error leyendo del DHT11!"); return; } if (humedad > umbralHumedad) { SerialBT.println("Lluvia detectada. Moviendo el robot a cubierta."); moverAlRefugio(); } } void detectarYAlimentar() { float distancia = sonar.ping_cm(); if (distancia > 0 && distancia < 50) { // Ajusta según preferencia SerialBT.println("Mascota detectada. Dispensando comida."); dispensarComida(); } } void evitarObstaculos() { float distancia = sonar.ping_cm(); if (distancia > 0 && distancia < 30) { // Ajusta según preferencia SerialBT.println("Obstáculo detectado. Esquivando."); maniobrarAlrededorDelObstaculo(); } } void moverAlRefugio() { digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(2000); // Ajusta el tiempo según la distancia a la cubierta detenerRobot(); } void dispensarComida() { miServo.write(90); // Abrir paso de comida delay(2000); // Tiempo suficiente para dispensar comida miServo.write(0); // Cerrar paso de comida } void maniobrarAlrededorDelObstaculo() { // Ejemplo sencillo de maniobra de evasión digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, HIGH); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(500); // Ajusta según sea necesario digitalWrite(MOTOR1_PIN1, HIGH); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, HIGH); digitalWrite(MOTOR2_PIN2, LOW); delay(1000); } void detenerRobot() { digitalWrite(MOTOR1_PIN1, LOW); digitalWrite(MOTOR1_PIN2, LOW); digitalWrite(MOTOR2_PIN1, LOW); digitalWrite(MOTOR2_PIN2, LOW); }
Image
Explicación del Código:Cpp
#include <Arduino.h> #include <BluetoothSerial.h> #include <DHT.h> #include <Servo.h> #define DHTPIN 4 // Pin del sensor DHT11 #define DHTTYPE DHT11 // Tipo de sensor DHT #define ECHO_PIN 19 // Pin de echo del sensor ultrasónico #define TRIG_PIN 18 // Pin de trigger del sensor ultrasónico #define MOTOR_A1 25 // Pin 1 del motor A #define MOTOR_A2 26 // Pin 2 del motor A #define MOTOR_B1 27 // Pin 1 del motor B #define MOTOR_B2 14 // Pin 2 del motor B #define SERVO_PIN 13 // Pin del servomotor DHT dht(DHTPIN, DHTTYPE); BluetoothSerial SerialBT; Servo servoMotor; bool robotIniciado = false; float distanciaAnterior = 0; void setup() { Serial.begin(115200); SerialBT.begin("RobotMascota"); // Nombre Bluetooth Serial.println("El dispositivo BT está listo para emparejamiento"); pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); pinMode(MOTOR_A1, OUTPUT); pinMode(MOTOR_A2, OUTPUT); pinMode(MOTOR_B1, OUTPUT); pinMode(MOTOR_B2, OUTPUT); servoMotor.attach(SERVO_PIN); dht.begin(); } void loop() { if (SerialBT.available()) { char comando = SerialBT.read(); if (comando == 'I') { // Inicializar robot robotIniciado = true; Serial.println("Robot Inicializado"); } } if (robotIniciado) { float humedad = dht.readHumidity(); float temperatura = dht.readTemperature(); if (humedad < 20) { // Activar servomotor para dispensar comida servoMotor.write(90); // Posición de apertura delay(2000); // Esperar 2 segundos servoMotor.write(0); // Posición de cierre } if (humedad > 70) { // Detecta lluvia y moverse a un lugar seco moverRobot(false, true); // Mover adelante hasta encontrar un lugar seco } // Evitar obstáculos float distancia = medirDistancia(); if ($$distancia < 30 $$ && $$distancia > 0$$ || distanciasCambiada(distancia)) { moverRobot(true, false); // Moverse hacia atrás delay(1000); moverRobot(false, false); // Girar a la derecha delay(1000); } else { moverRobot(false, true); // Moverse hacia adelante } } } bool distanciasCambiada(float nuevaDistancia) { bool cambiado = $$(abs(nuevaDistancia - distanciaAnterior) > 10$$); // Distancia ha cambiado significativamente distanciaAnterior = nuevaDistancia; return cambiado; } float medirDistancia() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); long duracion = pulseIn(ECHO_PIN, HIGH); float distancia = duracion * 0.034 / 2; return distancia; } void moverRobot(bool retroceder, bool avanzar) { if (retroceder) { digitalWrite(MOTOR_A1, LOW); digitalWrite(MOTOR_A2, HIGH); digitalWrite(MOTOR_B1, LOW); digitalWrite(MOTOR_B2, HIGH); } else if (avanzar) { digitalWrite(MOTOR_A1, HIGH); digitalWrite(MOTOR_A2, LOW); digitalWrite(MOTOR_B1, HIGH); digitalWrite(MOTOR_B2, LOW); } else { // Girar digitalWrite(MOTOR_A1, HIGH); digitalWrite(MOTOR_A2, LOW); digitalWrite(MOTOR_B1, LOW); digitalWrite(MOTOR_B2, HIGH); } }
moverRobot
: Controla los motores para moverse hacia adelante, atrás o girar.Descripción de Funcionalidades:Cpp
#include <BluetoothSerial.h> #include <Servo.h> #include <HCSR04.h> #include <DHT.h> // Configuración del módulo Bluetooth BluetoothSerial SerialBT; // Pines del ESP32 const int pinUltrasonicoTrig = 32; const int pinUltrasonicoEcho = 33; const int pinDHT11 = 25; const int pinServo = 27; const int pinMotorIn1 = 26; const int pinMotorIn2 = 14; const int pinMotorEn = 12; // Configuración del sensor DHT11 DHT dht(pinDHT11, DHT11); // Configuración del servomotor y el sensor ultrasónico Servo servomotor; UltraSonicDistanceSensor sensorUltrasonico(pinUltrasonicoTrig, pinUltrasonicoEcho); // Variables de estado bool robotEncendido = false; int distanciaMascota; int distanciaObstaculo; float temperatura; float humedad; void setup() { Serial.begin(115200); SerialBT.begin("RobotAlimentador"); // Nombre del dispositivo Bluetooth Serial.println("El Bluetooth ha sido inicializado."); // Configuración de pines pinMode(pinMotorIn1, OUTPUT); pinMode(pinMotorIn2, OUTPUT); pinMode(pinMotorEn, OUTPUT); // Inicialización de componentes dht.begin(); servomotor.attach(pinServo); servomotor.write(0); // Posición cerrada del paso de comida } void loop() { if (SerialBT.available()) { char data = SerialBT.read(); if (data == '1') { robotEncendido = true; Serial.println("Robot Encendido."); } } if (robotEncendido) { // Leer sensores distanciaMascota = sensorUltrasonico.measureDistanceCm(); delay(50); // Pequeña pausa para evitar lecturas erróneas temperatura = dht.readTemperature(); humedad = dht.readHumidity(); // Detectar presencia de la mascota if (distanciaMascota < 50) { // Ajustar la distancia según sea necesario abrirComida(); } // Evitar obstáculos else if (distanciaMascota < 20) { // Ajustar la distancia según sea necesario detenerMotor(); // Lógica para esquivar obstáculos (girar o retroceder) } // Detectar lluvia if (humedad > 80) { // Ajustar el umbral de humedad según sea necesario moverRobotLugarSeguro(); } } } void abrirComida() { servomotor.write(90); // Abrir el paso de comida delay(5000); // Duración de la apertura (ajustar según sea necesario) servomotor.write(0); // Cerrar el paso de comida } void detenerMotor() { digitalWrite(pinMotorIn1, LOW); digitalWrite(pinMotorIn2, LOW); analogWrite(pinMotorEn, 0); } void moverRobotLugarSeguro() { // Lógica para mover el robot a un lugar seguro digitalWrite(pinMotorIn1, HIGH); digitalWrite(pinMotorIn2, LOW); analogWrite(pinMotorEn, 255); delay(2000); // Ajustar la duración del movimiento detenerMotor(); }
BluetoothSerial
para comunicarse con el ESP32 desde un dispositivo móvil. El botón virtual envía un '1' para inicializar el robot.pinMotorIn1
y pinMotorIn2
controlan la dirección del motor.pinMotorEn
controla la velocidad del motor.pinUltrasonicoTrig
y pinUltrasonicoEcho
.pinDHT11
.pinServo
.Instrucciones:Cpp
#include <Arduino.h> #include <BluetoothSerial.h> #include <Servo.h> #include <DHT.h> // Pines y variables const int trigPin = 13; const int echoPin = 12; const int pinDHT = 14; const int motorPin1 = 27; const int motorPin2 = 26; const int motorPin3 = 25; const int motorPin4 = 33; const int servoPin = 15; const int distanciaDeteccion = 20; // cm para detectar mascotas const int distanciaObstaculo = 10; // cm para evitar obstáculos const float temperaturaLluvia = 30.0; // Threshold para detectar lluvia DHT dht(pinDHT, DHT11); Servo servoMotor; BluetoothSerial SerialBT; bool robotActivo = false; // Función para inicializar comunicación Bluetooth void iniciarBluetooth() { SerialBT.begin("RobotMascota"); } // Función para leer la distancia del sensor ultrasónico float leerDistancia() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duracion = pulseIn(echoPin, HIGH); float distancia = duracion * 0.034 / 2; return distancia; } // Función para mover el motor a una dirección específica void moverMotores(int pin1, int pin2, int pin3, int pin4) { digitalWrite(motorPin1, pin1); digitalWrite(motorPin2, pin2); digitalWrite(motorPin3, pin3); digitalWrite(motorPin4, pin4); } // Función para abrir el contenedor de comida void alimentarMascota() { servoMotor.write(90); // Mueve el servomotor para abrir el paso de comida delay(2000); // Espera 2 segundos servoMotor.write(0); // Cierra el paso de comida } // Función para leer los datos del sensor DHT11 float leerHumedad() { return dht.readHumidity(); } float leerTemperatura() { return dht.readTemperature(); } void setup() { Serial.begin(115200); iniciarBluetooth(); dht.begin(); servoMotor.attach(servoPin); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); } void loop() { if (SerialBT.available()) { char comando = SerialBT.read(); if (comando == 'a') { robotActivo = !robotActivo; } } if (robotActivo) { float distancia = leerDistancia(); float humedad = leerHumedad(); float temperatura = leerTemperatura(); if (distancia <= distanciaDeteccion) { alimentarMascota(); } if (temperatura >= temperaturaLluvia) { // Mueva los motores hacia el refugio moverMotores(HIGH, LOW, HIGH, LOW); } else if (distancia <= distanciaObstaculo) { // Evitar obstáculos moverMotores(LOW, HIGH, HIGH, LOW); // Ejemplo: girando a la izquierda } else { // Mover el robot hacia adelante moverMotores(HIGH, LOW, LOW, HIGH); } } }
Servo
DHT
NewPing
Parte del Código para ESP32Cpp
#include <Servo.h> #include <NewPing.h> #include "DHT.h" #define TRIGGER_PIN 12 #define ECHO_PIN 11 #define MAX_DISTANCE 200 #define DHTPIN 2 #define DHTTYPE DHT11 #define MOTOR_PIN_1 3 #define MOTOR_PIN_2 4 #define MOTOR_PIN_3 5 #define MOTOR_PIN_4 6 #define SERVOPIN 7 Servo servoComida; DHT dht(DHTPIN, DHTTYPE); NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); int distancia_det_mascota = 50; // En centímetros int distancia_det_obstaculos = 30; // En centímetros void setup() { Serial.begin(9600); servoComida.attach(SERVOPIN); pinMode(MOTOR_PIN_1, OUTPUT); pinMode(MOTOR_PIN_2, OUTPUT); pinMode(MOTOR_PIN_3, OUTPUT); pinMode(MOTOR_PIN_4, OUTPUT); dht.begin(); // Inicializar los motores apagados digitalWrite(MOTOR_PIN_1, LOW); digitalWrite(MOTOR_PIN_2, LOW); digitalWrite(MOTOR_PIN_3, LOW); digitalWrite(MOTOR_PIN_4, LOW); } void loop() { float h = dht.readHumidity(); // Humedad para detectar lluvia float t = dht.readTemperature(); // Temperatura ambiente // Verificar si hay lluvia if (h > 90) { mover('B'); // Mover hacia un lugar cubierto } else { unsigned int dist = sonar.ping_cm(); if (dist < distancia_det_mascota && dist > 0) { alimentarMascota(); } else if (dist < distancia_det_obstaculos && dist > 0) { evitarObstaculo(); } else { mover('A'); // Mover adelante cuando no hay obstáculos } } delay(1000); } void alimentarMascota() { servoComida.write(90); // Rotación para abrir el dispensador delay(2000); // Esperar un tiempo para que caiga la comida servoComida.write(0); // Volver a la posición original } void evitarObstaculo() { mover('I'); // Giro a la izquierda delay(500); mover('A'); // Mover adelante delay(500); } void mover(char direccion) { switch (direccion) { case 'A': digitalWrite(MOTOR_PIN_1, HIGH); digitalWrite(MOTOR_PIN_2, LOW); digitalWrite(MOTOR_PIN_3, HIGH); digitalWrite(MOTOR_PIN_4, LOW); break; case 'B': digitalWrite(MOTOR_PIN_1, LOW); digitalWrite(MOTOR_PIN_2, HIGH); digitalWrite(MOTOR_PIN_3, LOW); digitalWrite(MOTOR_PIN_4, HIGH); break; case 'I': digitalWrite(MOTOR_PIN_1, LOW); digitalWrite(MOTOR_PIN_2, HIGH); digitalWrite(MOTOR_PIN_3, HIGH); digitalWrite(MOTOR_PIN_4, LOW); break; case 'D': digitalWrite(MOTOR_PIN_1, HIGH); digitalWrite(MOTOR_PIN_2, LOW); digitalWrite(MOTOR_PIN_3, LOW); digitalWrite(MOTOR_PIN_4, HIGH); break; default: digitalWrite(MOTOR_PIN_1, LOW); digitalWrite(MOTOR_PIN_2, LOW); digitalWrite(MOTOR_PIN_3, LOW); digitalWrite(MOTOR_PIN_4, LOW); } }
BluetoothSerial
.Cpp
#include "BluetoothSerial.h" BluetoothSerial SerialBT; const int virtualButtonPin = 0; // Pin GPIO virtual para el botón de inicio void setup() { Serial.begin(115200); SerialBT.begin("RobotAlimentador"); // Nombre Bluetooth pinMode(virtualButtonPin, INPUT); } void loop() { if(SerialBT.available()) { String mensaje = SerialBT.readString(); if (mensaje == "INICIAR") { iniciarRobot(); } } delay(20); } void iniciarRobot() { SerialBT.println("El robot ha sido iniciado."); // Aquí se podría enviar una señal al Arduino Nano para comenzar el flujo // por ejemplo usando un pin específico. }
Plaintext
(ESP32:GPIO0) ---- (Arduino Nano:8)
Plaintext
(Arduino Nano:Digital 12) ---(HC-SR04 TRIGGER) (Arduino Nano:Digital 11) ---(HC-SR04 ECHO) (Arduino Nano:Digital 2) ---- (DHT11 DATA) (Arduino Nano:Digital 3) ---- (H-Bridge IN1) (Arduino Nano:Digital 4) ---- (H-Bridge IN2) (Arduino Nano:Digital 5) ---- (H-Bridge IN3) (Arduino Nano:Digital 6) ---- (H-Bridge IN4) (Arduino Nano:Digital 7) ---- (Servomotor Señal)
D2
).GND
con una resistencia de pull-down para evitar falsos positivos.Trig
al pin digital D3
Echo
al pin digital D4
D5
IN1
y IN2
a pines digitales D6
y D7
IN3
y IN4
a pines digitales D8
y D9
D10
Programa para ESP32 con BluetoothCpp
#include <Servo.h> #include <DHT.h> // Definición de pines const int pinBoton = 2; const int pinTrig = 3; const int pinEcho = 4; const int pinDHT11 = 5; const int pinMotor1A = 6; const int pinMotor1B = 7; const int pinMotor2A = 8; const int pinMotor2B = 9; const int pinServo = 10; // Creación de objetos Servo servo; DHT dht(pinDHT11, DHT11); // Variables bool alimentando = false; bool enMovimiento = false; void setup() { // Inicialización de pines pinMode(pinBoton, INPUT); pinMode(pinTrig, OUTPUT); pinMode(pinEcho, INPUT); pinMode(pinMotor1A, OUTPUT); pinMode(pinMotor1B, OUTPUT); pinMode(pinMotor2A, OUTPUT); pinMode(pinMotor2B, OUTPUT); servo.attach(pinServo); // Inicialización de comunicación serial y sensores Serial.begin(9600); dht.begin(); } void loop() { // Leer estado del botón bool botonPresionado = digitalRead(pinBoton); if (botonPresionado) { // Lógica para alimentar if (!alimentando) { servo.write(90); // Abrir el paso de la comida delay(3000); // Esperar 3 segundos servo.write(0); // Cerrar el paso de la comida alimentando = true; } // Leer sensores float h = dht.readHumidity(); float t = dht.readTemperature(); // Medir distancia long distancia = medirDistancia(); // Lógica de movimiento if (distancia < 20) { evitarObstaculo(); } else if (h > 80) { moverALugarSeco(); } else { moverFrente(); } } else { alimentando = false; pararMov(); } } long medirDistancia() { digitalWrite(pinTrig, LOW); delayMicroseconds(2); digitalWrite(pinTrig, HIGH); delayMicroseconds(10); digitalWrite(pinTrig, LOW); long duracion = pulseIn(pinEcho, HIGH); return (duracion / 2) / 29.1; // Convertir a cm } void evitarObstaculo() { digitalWrite(pinMotor1A, LOW); digitalWrite(pinMotor1B, HIGH); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); delay(500); pararMov(); } void moverALugarSeco() { digitalWrite(pinMotor1A, HIGH); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); delay(2000); // Moverse por 2 segundos a un lugar seco pararMov(); } void moverFrente() { digitalWrite(pinMotor1A, HIGH); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); } void pararMov() { digitalWrite(pinMotor1A, LOW); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, LOW); digitalWrite(pinMotor2B, LOW); }
Cpp
#include <BluetoothSerial.h> #include <Servo.h> #include <DHT.h> // Definición de pines const int pinTrigger = 3; const int pinEcho = 4; const int pinDHT11 = 5; const int pinMotor1A = 6; const int pinMotor1B = 7; const int pinMotor2A = 8; const int pinMotor2B = 9; const int pinServo = 10; // Creación de objetos BluetoothSerial SerialBT; Servo servo; DHT dht(pinDHT11, DHT11); // Variables bool robotEncendido = false; void setup() { // Inicialización de pines pinMode(pinTrigger, OUTPUT); pinMode(pinEcho, INPUT); pinMode(pinMotor1A, OUTPUT); pinMode(pinMotor1B, OUTPUT); pinMode(pinMotor2A, OUTPUT); pinMode(pinMotor2B, OUTPUT); servo.attach(pinServo); // Inicialización de Bluetooth y sensores Serial.begin(9600); dht.begin(); SerialBT.begin("RobotMascota"); } void loop() { if (SerialBT.available()) { String comando = SerialBT.readString(); if (comando == "ENCENDER") { robotEncendido = true; Serial.println("Robot encendido"); } else if (comando == "APAGAR") { robotEncendido = false; Serial.println("Robot apagado"); } else if (comando == "ALIMENTAR") { alimentar(); } } if (robotEncendido) { controlarRobot(); } else { pararMov(); } } void controlarRobot() { // Leer sensor ultrasónico long distancia = medirDistancia(); // Leer sensor de clima float h = dht.readHumidity(); float t = dht.readTemperature(); // Lógica de movimiento if (distancia < 20) { evitarObstaculo(); } else if (h > 80) { moverALugarSeco(); } else { moverFrente(); } } long medirDistancia() { digitalWrite(pinTrigger, LOW); delayMicroseconds(2); digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); digitalWrite(pinTrigger, LOW); long duracion = pulseIn(pinEcho, HIGH); return (duracion / 2) / 29.1; // Convertir a cm } void evitarObstaculo() { digitalWrite(pinMotor1A, LOW); digitalWrite(pinMotor1B, HIGH); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); delay(500); pararMov(); } void moverALugarSeco() { digitalWrite(pinMotor1A, HIGH); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); delay(2000); // Moverse por 2 segundos a un lugar seco pararMov(); } void moverFrente() { digitalWrite(pinMotor1A, HIGH); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, HIGH); digitalWrite(pinMotor2B, LOW); } void pararMov() { digitalWrite(pinMotor1A, LOW); digitalWrite(pinMotor1B, LOW); digitalWrite(pinMotor2A, LOW); digitalWrite(pinMotor2B, LOW); } void alimentar() { servo.write(90); // Abrir el paso de la comida delay(3000); // Esperar 3 segundos servo.write(0); // Cerrar el paso de la comida }
Cpp
#include <Servo.h> #include <DHT.h> #define TRIG_PIN 3 #define ECHO_PIN 4 #define DHT_PIN 5 #define DHT_TYPE DHT11 #define MOTOR_IN1 6 #define MOTOR_IN2 7 #define MOTOR_IN3 8 #define MOTOR_IN4 9 #define ENA 10 #define ENB 11 #define SERVO_PIN 12 #define BOTON_PIN 2 DHT dht(DHT_PIN, DHT_TYPE); Servo servo; bool robotEncendido = false; // Declaraciones de funciones void avanzar(); void retroceder(); void detenerMotores(); float medirDistancia(); bool detectarLluvia(); // Variables del Bluetooth (añade la librería adecuada para tu módulo Bluetooth) char comandoBluetooth; bool bluetoothEncendido = false; void setup() { pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); pinMode(MOTOR_IN1, OUTPUT); pinMode(MOTOR_IN2, OUTPUT); pinMode(MOTOR_IN3, OUTPUT); pinMode(MOTOR_IN4, OUTPUT); pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT); pinMode(BOTON_PIN, INPUT_PULLUP); Serial.begin(9600); dht.begin(); servo.attach(SERVO_PIN); servo.write(0); // Cierra el servo // Configuración del Bluetooth (ajusta según tu módulo) Serial1.begin(9600); // Usar Serial1 si tienes un modulo Bluetooth en el Nano Every, de lo contrario usa SoftwareSerial } void loop() { // Chequea botón físico if (digitalRead(BOTON_PIN) == LOW) { robotEncendido = !robotEncendido; delay(300); // De-bounce } if (robotEncendido) { Serial.println("Robot Encendido"); // Chequear comandos Bluetooth if (Serial1.available()) { comandoBluetooth = Serial1.read(); if (comandoBluetooth == 'E') { bluetoothEncendido = !bluetoothEncendido; } } if (bluetoothEncendido) { // Agrega comportamiento si el Bluetooth está encendido Serial.println("Bluetooth Encendido"); } else { // Sistema de detección de mascotas y obstáculos float distancia = medirDistancia(); if (distancia < 30) { Serial.println("Mascota Detectada, Abriendo Comida"); servo.write(90); // Abre el paso de comida delay(5000); servo.write(0); // Cierra el paso de comida } else if (distancia < 10) { Serial.println("Obstáculo Detectado"); retroceder(); delay(2000); detenerMotores(); } // Detector de lluvia if (detectarLluvia()) { Serial.println("Lluvia Detectada, Moviendo a Lugar Seguro"); avanzar(); delay(5000); // Simulando movimiento a lugar seguro detenerMotores(); } } } else { Serial.println("Robot Apagado"); detenerMotores(); } delay(1000); } void avanzar() { digitalWrite(MOTOR_IN1, HIGH); digitalWrite(MOTOR_IN2, LOW); digitalWrite(MOTOR_IN3, HIGH); digitalWrite(MOTOR_IN4, LOW); analogWrite(ENA, 255); analogWrite(ENB, 255); } void retroceder() { digitalWrite(MOTOR_IN1, LOW); digitalWrite(MOTOR_IN2, HIGH); digitalWrite(MOTOR_IN3, LOW); digitalWrite(MOTOR_IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); } void detenerMotores() { digitalWrite(MOTOR_IN1, LOW); digitalWrite(MOTOR_IN2, LOW); digitalWrite(MOTOR_IN3, LOW); digitalWrite(MOTOR_IN4, LOW); analogWrite(ENA, 0); analogWrite(ENB, 0); } float medirDistancia() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); float duracion = pulseIn(ECHO_PIN, HIGH); float distancia = $duracion / 2.0 * 0.0343$; return distancia; } bool detectarLluvia() { float humedad = dht.readHumidity(); if (humedad > 80.0) { return true; // Se puede cambiar el umbral según necesidad } return false; }
ESP32_BLE_Arduino
:Cpp
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> BLEServer *pServer = nullptr; BLECharacteristic *pCharacteristic = nullptr; bool deviceConnected = false; bool commandReceived = false; #define SERVICE_UUID "12345678-1234-1234-1234-123456789012" #define CHARACTERISTIC_UUID "87654321-4321-4321-4321-210987654321" void setup() { Serial.begin(115200); BLEDevice::init("ESP32 Robot"); pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setValue("E"); // Default value pService->start(); BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->setScanResponse(true); pAdvertising->setMinPreferred(0x06); pAdvertising->setMinPreferred(0x12); BLEDevice::startAdvertising(); } void loop() { if (commandReceived) { String command = pCharacteristic->getValue().c_str(); if (command == "E") { // Enviar señal al Arduino Nano Serial.println('E'); } commandReceived = false; } delay(1000); } class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } };
Código ESP32 (Bluetooth):Cpp
#include <Servo.h> #include <DHT.h> // Pines #define TRIG_PIN 2 #define ECHO_PIN 3 #define MOTOR_IN1 4 #define MOTOR_IN2 5 #define SERVO_PIN 6 #define DHT_PIN 7 #define RAIN_SENSOR_PIN 8 #define BUTTON_PIN 9 #define DHT_TYPE DHT11 Servo servo; DHT dht(DHT_PIN, DHT_TYPE); bool isRobotOn = false; void setup() { pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); pinMode(MOTOR_IN1, OUTPUT); pinMode(MOTOR_IN2, OUTPUT); pinMode(RAIN_SENSOR_PIN, INPUT); pinMode(BUTTON_PIN, INPUT_PULLUP); servo.attach(SERVO_PIN); dht.begin(); Serial.begin(9600); } void loop() { // Toggle robot on/off with button if (digitalRead(BUTTON_PIN) == LOW) { delay(100); // Debounce isRobotOn = !isRobotOn; while (digitalRead(BUTTON_PIN) == LOW); // Wait for release } if (isRobotOn) { // Check for pet presence (Ultrasonic Sensor) if (detectPet()) { feedPet(); } // Check for rain if (isRaining()) { moveRobotToShelter(); } else { avoidObstaclesAndMove(); } delay(1000); // Delay for stability } } // Function to detect pet presence bool detectPet() { long duration, distance; digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); duration = pulseIn(ECHO_PIN, HIGH); distance = (duration / 2) / 29.1; if (distance < 30) { // Assume pet is within 30 cm return true; } else { return false; } } // Function to feed pet void feedPet() { servo.write(90); // Open the food passage delay(3000); // Wait for food to be dispensed servo.write(0); // Close the food passage } // Function to check for rain bool isRaining() { return digitalRead(RAIN_SENSOR_PIN) == LOW; } // Function to move the robot to shelter void moveRobotToShelter() { // Move forward digitalWrite(MOTOR_IN1, HIGH); digitalWrite(MOTOR_IN2, LOW); } // Function to avoid obstacles and move void avoidObstaclesAndMove() { // Check for obstacles long duration, distance; digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); duration = pulseIn(ECHO_PIN, HIGH); distance = (duration / 2) / 29.1; if (distance < 20) { // If obstacle detected within 20 cm // Stop or change direction digitalWrite(MOTOR_IN1, LOW); digitalWrite(MOTOR_IN2, LOW); } else { // Move forward digitalWrite(MOTOR_IN1, HIGH); digitalWrite(MOTOR_IN2, LOW); } }
BluetoothSerial
. El siguiente código crea una simple comunicación Bluetooth donde puedes encender y apagar el robot:Conexión entre Arduino Nano y ESP32:Cpp
#include <BluetoothSerial.h> BluetoothSerial SerialBT; // Variable to hold the robot state bool robotState = false; void setup() { Serial.begin(115200); SerialBT.begin("PetFeederRobot"); // Name of your Bluetooth device Serial.println("The device started, now you can pair it with bluetooth!"); } void loop() { if (SerialBT.available()) { char receivedChar = SerialBT.read(); if (receivedChar == '1') { robotState = true; // Turn on the robot SerialBT.println("Robot is ON"); } else if (receivedChar == '0') { robotState = false; // Turn off the robot SerialBT.println("Robot is OFF"); } } }
Cpp
#define ESP32_PIN 10 void setup() { // ... pinMode(ESP32_PIN, INPUT); } void loop() { // ... if (digitalRead(ESP32_PIN) == HIGH) { isRobotOn = true; } else { isRobotOn = false; } // ... }
ESP32_BLE_Arduino
.ESP32:Plaintext
- Añadir un botón conectado entre el pin D2 y GND. - Habilitar el resistor pull-up interno en el código.
Código para Arduino Nano:Plaintext
- No se requiere modificación física, solo el código.
Código para ESP32:Cpp
const int buttonPin = 2; // Pin donde está conectado el botón físico const int ledPin = 13; // Pin para el LED de encendido bool isOn = false; void setup() { pinMode(buttonPin, INPUT_PULLUP); pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { if (digitalRead(buttonPin) == LOW) { delay(50); // Debounce if (digitalRead(buttonPin) == LOW) { isOn = !isOn; while (digitalRead(buttonPin) == LOW); // Esperar hasta que se suelte el botón } } if (isOn) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } // Otros códigos de control para el robot }
ESP32_BLE_Arduino
para crear un botón virtual.ResumenCpp
#include <BLEDevice.h> #include <BLEUtils.h> #include <BLEServer.h> // UUIDs para el servicio y la característica (puedes cambiarlos si deseas) #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" bool isOn = false; const int ledPin = 2; // Pin para el LED de encendido class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue(); if (value.length() > 0) { if (value == "1") { isOn = true; } else if (value == "0") { isOn = false; } } } }; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(115200); BLEDevice::init("ESP32_Control"); BLEServer *pServer = BLEDevice::createServer(); BLEService *pService = pServer->createService(SERVICE_UUID); BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pCharacteristic->setValue("0"); pService->start(); BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->start(); } void loop() { if (isOn) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } // Otros códigos de control para el robot }
Código para ESP32Cpp
#include <Servo.h> #include <DHT.h> #define TRIG_PIN 2 #define ECHO_PIN 3 #define DHT_PIN 4 #define DHT_TYPE DHT11 #define IN1 5 #define IN2 6 #define IN3 7 #define IN4 8 #define ENA 9 #define ENB 10 Servo servoMotor; DHT dht(DHT_PIN, DHT_TYPE); void setup() { Serial.begin(9600); pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT); servoMotor.attach(11); dht.begin(); stopMotors(); } void loop() { float distance = measureDistance(); float h = dht.readHumidity(); float t = dht.readTemperature(); if (isPetDetected(distance)) { feedPet(); } if (isRaining(h, t)) { moveUnderShelter(); } else { avoidObstacles(distance); } delay(500); } float measureDistance() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); long duration = pulseIn(ECHO_PIN, HIGH); float distance = duration * 0.034 / 2; return distance; } bool isPetDetected(float distance) { return distance < 30; // Ajustar según sea necesario } void feedPet() { servoMotor.write(90); // Abrir paso de comida delay(3000); // Mantener abierto 3 segundos servoMotor.write(0); // Cerrar paso de comida } bool isRaining(float h, float t) { // Asume que si la humedad está por encima de 80% y temperatura es < 20°C es lluvia return h > 80 && t < 20; } void moveUnderShelter() { setMotorsForward(); delay(5000); // Moverse al refugio durante 5 segundos stopMotors(); } void avoidObstacles(float distance) { if (distance < 15) { stopMotors(); setMotorsBackward(); delay(1000); // Retroceder durante 1 segundo stopMotors(); turnRight(); delay(1000); // Girar durante 1 segundo stopMotors(); } else { setMotorsForward(); } } void setMotorsForward() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENA, 255); analogWrite(ENB, 255); } void setMotorsBackward() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); } void turnRight() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); } void stopMotors() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); analogWrite(ENA, 0); analogWrite(ENB, 0); }
Conexiones Arduino Nano:Cpp
#include <Servo.h> #include <DHT.h> #define TRIG_PIN 22 #define ECHO_PIN 23 #define DHT_PIN 21 #define DHT_TYPE DHT11 #define IN1 18 #define IN2 19 #define IN3 25 #define IN4 26 #define ENA 14 #define ENB 27 Servo servoMotor; DHT dht(DHT_PIN, DHT_TYPE); void setup() { Serial.begin(9600); pinMode(TRIG_PIN, OUTPUT); pinMode(ECHO_PIN, INPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT); servoMotor.attach(13); dht.begin(); stopMotors(); } void loop() { float distance = measureDistance(); float h = dht.readHumidity(); float t = dht.readTemperature(); if (isPetDetected(distance)) { feedPet(); } if (isRaining(h, t)) { moveUnderShelter(); } else { avoidObstacles(distance); } delay(500); } float measureDistance() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); long duration = pulseIn(ECHO_PIN, HIGH); float distance = duration * 0.034 / 2; return distance; } bool isPetDetected(float distance) { return distance < 30; // Ajustar según sea necesario } void feedPet() { servoMotor.write(90); // Abrir paso de comida delay(3000); // Mantener abierto 3 segundos servoMotor.write(0); // Cerrar paso de comida } bool isRaining(float h, float t) { // Asume que si la humedad está por encima de 80% y temperatura es < 20°C es lluvia return h > 80 && t < 20; } void moveUnderShelter() { setMotorsForward(); delay(5000); // Moverse al refugio durante 5 segundos stopMotors(); } void avoidObstacles(float distance) { if (distance < 15) { stopMotors(); setMotorsBackward(); delay(1000); // Retroceder durante 1 segundo stopMotors(); turnRight(); delay(1000); // Girar durante 1 segundo stopMotors(); } else { setMotorsForward(); } } void setMotorsForward() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENA, 255); analogWrite(ENB, 255); } void setMotorsBackward() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); } void turnRight() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); } void stopMotors() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); analogWrite(ENA, 0); analogWrite(ENB, 0); }
Explicación del códigoCpp
#include "esp_camera.h" #include <WiFi.h> #include <WiFiClient.h> #include <ESP32_MailClient.h> // Configuración de la cámara #define CAMERA_MODEL_AI_THINKER #include "camera_pins.h" // Configuración del PIR #define PIR_PIN 13 // GPIO 13 para PIR sensor // Configuración de WiFi const char* ssid = "TU_SSID"; const char* password = "TU_CONTRASEÑA"; // Configuración de correo electrónico SMTPSession smtp; const char* smtp_server = "smtp.example.com"; const char* smtp_user = "[email protected]"; const char* smtp_password = "your-email-password"; const char* recipient_email = "[email protected]"; const char* subject = "Movimiento Detectado"; // Función para capturar la imagen void captureAndSendPhoto() { camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if (!fb) { Serial.println("Captura de foto fallida"); return; } // Enviar foto por correo electrónico smtp.connect(smtp_server, 587); smtp.login(smtp_user, smtp_password); SMTP_Message message; message.sender.email = smtp_user; message.sender.name = "ESP32-CAM"; message.subject = subject; message.addRecipient("", recipient_email); SMTP_Attachment att; att.data = fb->buf; // asignar el buffer de la foto att.filename = "photo.jpg"; att.mime = "image/jpg"; message.addAttachment(att); smtp.send(&message); esp_camera_fb_return(fb); } void setup() { Serial.begin(115200); pinMode(PIR_PIN, INPUT); // Configuración WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Conectando a WiFi..."); } Serial.println("Conectado a WiFi"); // Configuración cámara camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sccb_sda = SIOD_GPIO_NUM; config.pin_sccb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.pin_xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if (psramFound()) { config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } // Inicializar cámara esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Error al inicializar la cámara: 0x%x", err); return; } Serial.println("Cámara inicializada"); } void loop() { if (digitalRead(PIR_PIN) == HIGH) { Serial.println("Movimiento detectado!"); captureAndSendPhoto(); delay(10000); // Esperar 10 segundos para evitar múltiples capturas seguidas } delay(100); }
Table
Component | Pin | Connections |
---|---|---|
LM339 (Comparator, U1) | Pin 4 (Inverting input) | R1:P2, to load |
LM339 (Comparator, U1) | Pin 5 (Non-inverting input) | Reference voltage (via Zener diode or voltage divider) |
LM339 (Comparator, U1) | Pin 2 (Output) | Q1:Gate (G) via 10kΩ pull-up resistor |
Current Sense Resistor (R1) | P1 | Q1:Source (S) |
Current Sense Resistor (R1) | P2 | Load, U1:Pin 4 (Inverting input) |
N-channel MOSFET (Q1) | Drain (D) | Positive voltage source |
N-channel MOSFET (Q1) | Source (S) | R1:P1 |
N-channel MOSFET (Q1) | Gate (G) | U1:Pin 2 (Output) via 10kΩ pull-up resistor, connected to ground via 10kΩ pull-down resistor |
10kΩ Pull-down Resistor | Q1:Gate (G) to GND | |
Decoupling Capacitor | Across VCC and GND of LM339 |