Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Plataforma Seguidora Solar de Precisión con Servos para Captura Óptima de Energía

Componentes y materiales

ComponenteCantidadNotas
Fotorresistencias (LDR)4
LED RGB NeoPixel (Adafruit Flora, pack 4)1O LED RGB multicolor equivalente
Pulsadores 12 mm (normalmente abiertos)2SparkFun o equivalentes
Sensor de temperatura1
Arduino UNO1
Servos 180° (RobotGeek o Futaba S3003)2Uno para giro (base), otro para inclinación
Resistencias 10 kΩ6
Resistencia 220 Ω1Para LED
Condensadores 100 µF2
Panel solar 80×80 mm1Amazon o similar

Herramientas necesarias

Aplicaciones y servicios

Descripción del proyecto

Otra implementación usando dos servos de 180° y cuatro fotorresistencias para orientar un pequeño panel solar hacia la zona de mayor intensidad lumínica.

Los motores realizan pequeños movimientos para apuntar el panel al área más brillante.

Incluye un LED multicolor que indica si el sistema está habilitado. Dos pulsadores permiten activar/desactivar los motores.

Hay rutinas para mover los motores a posiciones comandadas vía puerto serie, usando códigos numéricos. Los movimientos independientes están programados para ser suaves, evitando golpes mecánicos por cambios bruscos de posición.

Código (Versión 2.0 - Q2)

// Scott Mangiacotti, Tucson, Arizona, Mayo 2018 - Q2 Version 2.0
#include <Servo.h>

const int GIVE_BACK_TIME = 125;

// Pines entrada
const int I_RED_BUTTON_PIN = 4;
const int I_GREEN_BUTTON_PIN = 2;
const int I_LDR1_PIN = A3; // sup-izq
const int I_LDR2_PIN = A2; // sup-der
const int I_LDR3_PIN = A1; // inf-izq
const int I_LDR4_PIN = A0; // inf-der

// Pines salida
const int O_RED_LED_PIN = 9;
const int O_GREEN_LED_PIN = 11;
const int O_BLUE_LED_PIN = 10;
const int O_TWIST_SERVO_PIN = 5;
const int O_TILT_SERVO_PIN = 6;

// Variables globales
bool gRunning = false;
bool gTrackToLightEnabled = false;
bool gVerboseDiagMode = false;
Servo gServoTwist;
int gServoTwistPositionCommand;
bool gServoTwistMoveIP;
Servo gServoTilt;
bool gServoTiltMoveIP;
int gServoTiltPositionCommand;
int gLDR1, gLDR2, gLDR3, gLDR4;

void setup() {
  Serial.begin(9600);
  pinMode(I_RED_BUTTON_PIN, INPUT);
  pinMode(I_GREEN_BUTTON_PIN, INPUT);
  pinMode(O_RED_LED_PIN, OUTPUT);
  pinMode(O_GREEN_LED_PIN, OUTPUT);
  pinMode(O_BLUE_LED_PIN, OUTPUT);
  startup();
}

void loop() {
  // Procesar comandos serie
  if (Serial.available() > 0) {
    int iControlCode = Serial.parseInt();
    processSerialMessage(iControlCode);
  }

  // Botón verde: activar seguimiento
  int iGreenButton = digitalRead(I_GREEN_BUTTON_PIN);
  if (iGreenButton == HIGH && gRunning == false) {
    enableTracking();
    gTrackToLightEnabled = true;
  }

  // Botón rojo: desactivar
  int iRedButton = digitalRead(I_RED_BUTTON_PIN);
  if (iRedButton == HIGH && gRunning == true) {
    disableTracking();
  }

  // Leer fotorresistencias
  readPhotoResistors();
  averageTopTwoSensors();
  averageBottomTwoSensors();

  // Ajustar servos según luz
  if (gRunning == true) {
    if (gTrackToLightEnabled == true) {
      trackToLightSensors();
    } else {
      smoothMoveTwist();
      smoothMoveTilt();
    }
  }
  delay(GIVE_BACK_TIME);
}

void enableTracking() {
  gRunning = true;
  gServoTwist.attach(O_TWIST_SERVO_PIN);
  gServoTilt.attach(O_TILT_SERVO_PIN);
  digitalWrite(O_GREEN_LED_PIN, HIGH);
  digitalWrite(O_RED_LED_PIN, LOW);
  Serial.println("servos enabled");
}

void disableTracking() {
  gRunning = false;
  gTrackToLightEnabled = false;
  gServoTwist.detach();
  gServoTilt.detach();
  gServoTwistPositionCommand = gServoTwist.read();
  gServoTwistMoveIP = false;
  gServoTiltPositionCommand = gServoTilt.read();
  gServoTiltMoveIP = false;
  digitalWrite(O_RED_LED_PIN, HIGH);
  digitalWrite(O_GREEN_LED_PIN, LOW);
  Serial.println("servos disabled");
}

void trackToLightSensors() {
  float fTop, fBottom, fLeft, fRight;
  int iTwistMoveCommand, iTiltMoveCommand;
  int iMoveAmount = 5; // Grados por escaneo (combinado con GIVE_BACK_TIME define agresividad)

  iTwistMoveCommand = gServoTwist.read();
  iTiltMoveCommand = gServoTilt.read();

  fTop = averageTopTwoSensors();
  fBottom = averageBottomTwoSensors();
  fLeft = averageLeftTwoSensors();
  fRight = averageRightTwoSensors();

  // Giro (twist)
  if (fLeft > fRight) iTwistMoveCommand += iMoveAmount;
  else if (fRight > fLeft) iTwistMoveCommand -= iMoveAmount;

  // Inclinación (tilt)
  if (fTop > fBottom) iTiltMoveCommand += iMoveAmount;
  else if (fBottom > fTop) iTiltMoveCommand -= iMoveAmount;

  // Límites
  if (iTwistMoveCommand < 0) iTwistMoveCommand = 0;
  if (iTwistMoveCommand > 179) iTwistMoveCommand = 179;
  if (iTiltMoveCommand < 45) iTiltMoveCommand = 45;
  if (iTiltMoveCommand > 135) iTiltMoveCommand = 135;

  gServoTwist.write(iTwistMoveCommand);
  gServoTilt.write(iTiltMoveCommand);

  if (gVerboseDiagMode) {
    Serial.println("tl,tr,bl,br,top,btm,left,right,twist,tilt:");
    Serial.print(gLDR1); Serial.print(", "); Serial.print(gLDR2); Serial.print(", ");
    Serial.print(gLDR3); Serial.print(", "); Serial.print(gLDR4); Serial.print(", ");
    Serial.print(fTop); Serial.print(", "); Serial.print(fBottom); Serial.print(", ");
    Serial.print(fLeft); Serial.print(", "); Serial.print(fRight); Serial.print(", ");
    Serial.print(iTwistMoveCommand); Serial.print(", "); Serial.println(iTiltMoveCommand);
  }
}

void readPhotoResistors() {
  gLDR1 = analogRead(I_LDR1_PIN);
  gLDR2 = analogRead(I_LDR2_PIN);
  gLDR3 = analogRead(I_LDR3_PIN);
  gLDR4 = analogRead(I_LDR4_PIN);
}

void smoothMoveTwist() {
  int iCurrentPos = gServoTwist.read();
  int iMoveAmountPerScan = 1; // Grados por escaneo
  int iNewMoveCommand;

  if (iCurrentPos == gServoTwistPositionCommand) {
    gServoTwistMoveIP = false; return;
  } else gServoTwistMoveIP = true;

  iNewMoveCommand = iCurrentPos;
  if (iCurrentPos < gServoTwistPositionCommand) iNewMoveCommand += iMoveAmountPerScan;
  else iNewMoveCommand -= iMoveAmountPerScan;

  if (iNewMoveCommand < 0) iNewMoveCommand = 0;
  if (iNewMoveCommand > 179) iNewMoveCommand = 179;

  gServoTwist.write(iNewMoveCommand);

  if (gVerboseDiagMode) {
    Serial.print("Twist move: "); Serial.print(iNewMoveCommand); Serial.print(", "); Serial.println(gServoTwistPositionCommand);
  }
}

void smoothMoveTilt() {
  int iCurrentPos = gServoTilt.read();
  int iMoveAmountPerScan = 1;
  int iNewMoveCommand;

  if (iCurrentPos == gServoTiltPositionCommand) {
    gServoTiltMoveIP = false; return;
  } else gServoTiltMoveIP = true;

  iNewMoveCommand = iCurrentPos;
  if (iCurrentPos < gServoTiltPositionCommand) iNewMoveCommand += iMoveAmountPerScan;
  else iNewMoveCommand -= iMoveAmountPerScan;

  if (iNewMoveCommand < 0) iNewMoveCommand = 0;
  if (iNewMoveCommand > 179) iNewMoveCommand = 179;

  gServoTilt.write(iNewMoveCommand);

  if (gVerboseDiagMode) {
    Serial.print("Tilt move: "); Serial.print(iNewMoveCommand); Serial.print(", "); Serial.println(gServoTiltPositionCommand);
  }
}

float averageTopTwoSensors() { return (gLDR1 + gLDR2) / 2.0; }
float averageBottomTwoSensors() { return (gLDR3 + gLDR4) / 2.0; }
float averageLeftTwoSensors() { return (gLDR1 + gLDR3) / 2.0; }
float averageRightTwoSensors() { return (gLDR2 + gLDR4) / 2.0; }

void processSerialMessage(int iControlCode) {
  int iControlCommand = iControlCode / 1000;
  int iControlValue = iControlCode % 1000;

  Serial.print("control code: "); Serial.println(iControlCode);
  Serial.print("command: "); Serial.println(iControlCommand);
  Serial.print("value: "); Serial.println(iControlValue);

  if (iControlCommand == 10) { // Miscelánea
    switch (iControlValue) {
      case 0: gVerboseDiagMode = true; digitalWrite(O_BLUE_LED_PIN, HIGH); Serial.println("diagnostics started"); break;
      case 1: gVerboseDiagMode = false; digitalWrite(O_BLUE_LED_PIN, LOW); Serial.println("diagnostics stopped"); break;
      case 2: reportProductInfo(); break;
      case 3: digitalWrite(O_RED_LED_PIN, HIGH); Serial.println("red led on"); break;
      case 4: digitalWrite(O_RED_LED_PIN, LOW); Serial.println("red led off"); break;
      case 5: digitalWrite(O_GREEN_LED_PIN, HIGH); Serial.println("green led on"); break;
      case 6: digitalWrite(O_GREEN_LED_PIN, LOW); Serial.println("green led off"); break;
      case 7: digitalWrite(O_BLUE_LED_PIN, HIGH); Serial.println("blue led on"); break;
      case 8: digitalWrite(O_BLUE_LED_PIN, LOW); Serial.println("blue led off"); break;
      case 9: Serial.print("LDR1: "); Serial.println(gLDR1); break;
      case 10: Serial.print("LDR2: "); Serial.println(gLDR2); break;
      case 11: Serial.print("LDR3: "); Serial.println(gLDR3); break;
      case 12: Serial.print("LDR4: "); Serial.println(gLDR4); break;
      case 13: enableTracking(); break;
      case 14: disableTracking(); break;
      case 19: if (gRunning && !gServoTwistMoveIP && !gServoTiltMoveIP) { gServoTwistPositionCommand = 90; gServoTiltPositionCommand = 90; Serial.println("servos to 90 deg"); } break;
      case 21: if (gRunning) { gTrackToLightEnabled = true; Serial.println("light tracking enabled"); } break;
      case 22: gTrackToLightEnabled = false; Serial.println("light tracking disabled"); break;
      default: Serial.print("invalid value: "); Serial.println(iControlValue);
    }
  } else if (iControlCommand == 11) { // Servo giro
    if (iControlValue >= 0 && iControlValue <= 179 && gRunning && !gServoTwistMoveIP) {
      gServoTwistPositionCommand = iControlValue; gServoTwistMoveIP = true;
      Serial.print("Twist cmd: "); Serial.println(gServoTwistPositionCommand);
    } else Serial.print("invalid value: "); Serial.println(iControlValue);
  } else if (iControlCommand == 12) { // Servo inclinación
    if (iControlValue >= 0 && iControlValue <= 179 && gRunning && !gServoTiltMoveIP) {
      gServoTiltPositionCommand = iControlValue; gServoTiltMoveIP = true;
      Serial.print("Tilt cmd: "); Serial.println(gServoTiltPositionCommand);
    } else Serial.print("tilt not ready: "); Serial.print(gRunning); Serial.print(", "); Serial.println(gServoTiltMoveIP);
  }
  Serial.println("-----");
}

void startup() {
  int iDelay = 500;
  reportProductInfo(); delay(iDelay);
  processSerialMessage(10003); delay(iDelay); // Red ON
  processSerialMessage(10004); processSerialMessage(10005); delay(iDelay); // Red OFF, Green ON
  processSerialMessage(10006); processSerialMessage(10007); delay(iDelay); // Green OFF, Blue ON
  processSerialMessage(10008); processSerialMessage(10009); processSerialMessage(10010); processSerialMessage(10011); processSerialMessage(10012); delay(iDelay); // LDRs
  enableTracking(); delay(iDelay);
  processSerialMessage(10019); delay(iDelay); // Home position
  disableTracking();
  Serial.println("startup completed");
}

void reportProductInfo() {
  Serial.println("q version 2");
  Serial.println("tucson, arizona usa");
  Serial.println("may 2018");
  Serial.print("checksum "); Serial.println("58BA-D969-2F82-08FD-2078-2777-396D-E1AA");
}

Partes personalizadas

Archivos de ensamblaje: q2_assembly_details.zip

Esquemático

Archivo Fritzing: q2_schematic.fzz

Proceso de manufactura

  1. Sistemas de calefacción solar: de soluciones pasivas a activas para calefacción sostenible del hogar
  2. Células solares: de los primeros experimentos a la fotovoltaica moderna – tecnología, producción y perspectivas
  3. Monitorización en Tiempo Real de Panel Solar con Arduino: Sistema de Adquisición de Datos de Bajo Coste
  4. Persianas Inteligentes: Control Automático de Luz con Arduino y Energía Solar
  5. Seguidor Solar IoT: Gestión Inteligente de Energía con Arduino
  6. SmartPostBox: Buzón Inteligente IoT con Notificaciones por Email
  7. Seguidor Solar de Doble Eje con Control Automático y Manual: Sistema Eficiente de Seguimiento Solar
  8. Cargador solar portátil con seguidor solar Arduino y control de servo
  9. Aprovechamiento de la energía solar: guía completa para una energía limpia y fiable
  10. Calidad de paneles solares: puntos de control esenciales para rendimiento óptimo
  11. Cómo se fabrican los paneles solares: guía paso a paso para producción de energía solar de alta calidad