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 de paneles solares con seguimiento de luz y servocontrolados

Componentes y suministros

Foto resistor
× 4
LED Adafruit Flora RGB Neopixel - Paquete de 4
o LED multicolor RBG equivalente
× 1
Interruptor de botón SparkFun de 12 mm
o botón pulsador normalmente abierto equivalente
× 2
Sensor de temperatura
× 1
Arduino UNO
× 1
RobotGeek Robot Servo de 180 grados
o equivalente. Usé servos Futaba S3003
× 2
Resistencia de 10k ohmios
× 6
Resistencia 221 ohm
Usé 220 ohmios
× 1
Condensador 100 µF
× 2
panel solar (80 mm x 80 mm)
se puede comprar en Amazon.com o equivalente
× 1

Herramientas y máquinas necesarias

Herramientas manuales y algunas tuercas y tornillos pequeños para crear el soporte
Base sólida para montar el servomotor "twist".
Usé un pequeño bloque de madera
Metal flexible o pequeñas láminas de aluminio rígido que se pueden moldear en un soporte en forma de "L"
Usé aprox. Aluminio de 3 mm de espesor con poco menos de 2 cm de ancho
Metal delgado y flexible para formar un soporte para sostener la plataforma del panel solar y móntelo en el servo "twist"
Usé tiras de acero delgadas compradas en una ferretería que normalmente se usan para unir los conductos de HVAC. Tiene orificios de montaje pretaladrados para mayor facilidad

Aplicaciones y servicios en línea

Arduino IDE
Microsoft Excel para documentación y notas

Acerca de este proyecto

Esta es otra implementación del uso de dos servos de 180 grados y cuatro fotorresistencias para poder rastrear un pequeño panel solar para alinearlo con el área de mayor intensidad de luz.

Los motores hacen pequeños movimientos para intentar apuntar el panel solar hacia la luz más brillante.

También hay un LED multicolor para indicar si el sistema está habilitado o no. Y dos pulsadores para habilitar / deshabilitar los motores.

Hay algunas rutinas que se pueden usar para mover los motores a las posiciones ordenadas. Los comandos se realizan a través de la interfaz del puerto serie y una serie de códigos / comandos numéricos que se pueden enviar al Arduino Uno.

Los comandos de movimiento independientes están programados para proporcionar movimientos (algo) suaves en lugar de comandos de posición inmediatos que hacen que el mecanismo mecánico se mueva violentamente.

Código

  • código Q2
Código Q2 Arduino
 // Scott Mangiacotti // Tucson, Arizona USA // Mayo 2018 // Q2 // Versión 2.0 # include  // Constantsint const GIVE_BACK_TIME =125; // Constantes para inputint const I_RED_BUTTON_PIN =4; int const I_GREEN_BUTTON_PIN =2; int const I_LDR1_PIN =A3; // arriba izquierda const I_LDR2_PIN =A2; // arriba a la derecha const I_LDR3_PIN =A1; // abajo a la izquierda const I_LDR4_PIN =A0; // abajo a la derecha // Constantes para las salidasint const O_RED_LED_PIN =9; int const O_GREEN_LED_PIN =11; int const O_BLUE_LED_PIN =10; int const O_TWIST_SERVO_PIN =5; int const O_TILT_SERVO_PinningPIN =false golR golR variables;; bool gVerboseDiagMode =false; Servo gServoTwist; int gServoTwistPositionCommand; // comando positionbool gServoTwistMoveIP; // movimiento en progresoServo gServoTilt; bool gServoTiltMoveIP; // movimiento en progresoint gServoTiltPositionCommand; // posición ordenadaint gLDR1; int gLDR2; int gLDR3; int gLDR4; // Se ejecuta una vezvoid setup () {// Abre un puerto serie Serial.begin (9600); // Configurar entradas digitales pinMode (I_RED_BUTTON_PIN, INPUT); pinMode (I_GREEN_BUTTON_PIN, ENTRADA); // Configurar salidas digitales pinMode (O_RED_LED_PIN, OUTPUT); pinMode (O_GREEN_LED_PIN, SALIDA); pinMode (O_BLUE_LED_PIN, SALIDA); // Ejecuta la rutina de inicio startup ();} // Ejecuta continuamentevoid loop () {// Procesamiento de recepción de mensajes de puerto serie if (Serial.available ()> 0) {int iControlCode; iControlCode =Serial.parseInt (); processSerialMessage (iControlCode); } // Leer el botón verde int iGreenButton; iGreenButton =digitalRead (I_GREEN_BUTTON_PIN); if (iGreenButton ==HIGH &&gRunning ==false) {enableTracking (); gTrackToLightEnabled =true; } // Leer el botón rojo int iRedButton; iRedButton =digitalRead (I_RED_BUTTON_PIN); if (iRedButton ==HIGH &&gRunning ==true) {disableTracking (); } // Leer toda la instrumentación en variables globales readPhotoResistors (); averageTopTwoSensors (); averageBottomTwoSensors (); // Ajusta las posiciones de los servos de acuerdo con la luz de los fotoresistores if (gRunning ==true) {if (gTrackToLightEnabled ==true) {// Haz pequeños movimientos de los servos basados ​​en los niveles de luz de los fotorresistores trackToLightSensors (); } else {// Realiza pequeños movimientos basados ​​en los comandos del usuario en el puerto serie. Evita movimientos de alta velocidad en el mecanismo smoothMoveTwist (); smoothMoveTilt (); }} // Dar un poco de tiempo de retraso (GIVE_BACK_TIME);} // Activar el seguimiento del servovoid enableTracking () {// Establecer variables globales para que otras partes del programa sepan que los motores están listos para funcionar gRunning =true; // Adjuntar a los servomotores gServoTwist.attach (O_TWIST_SERVO_PIN); gServoTilt.attach (O_TILT_SERVO_PIN); // Enciende el LED verde y apaga el LED rojo digitalWrite (O_GREEN_LED_PIN, HIGH); digitalWrite (O_RED_LED_PIN, BAJO); // Publicar los resultados Serial.println ("servos habilitados");} // Desactivar el seguimiento del servovoid disableTracking () {gRunning =false; gTrackToLightEnabled =false; // Desconectar de los servomotores gServoTwist.detach (); gServoTilt.detach (); // Limpiar comando mover y mover variables en proceso (IP) gServoTwistPositionCommand =gServoTwist.read (); gServoTwistMoveIP =falso; // Limpiar comando mover y mover variables en proceso (IP) gServoTiltPositionCommand =gServoTilt.read (); gServoTiltMoveIP =falso; // Enciende el LED rojo, apaga el LED verde digitalWrite (O_RED_LED_PIN, HIGH); digitalWrite (O_GREEN_LED_PIN, BAJO); // Publicar resultados Serial.println ("servos desactivados");} // Seguimiento a la luz según los valores del fotosensorvoid trackToLightSensors () {float fTop; float fBottom; float fLeft; flotar fRight; int iTwistMoveCommand; int iTiltMoveCommand; int iMoveAmount; // Inicializar // La siguiente variable determina cuántos grados de movimiento potencial para ambos servos // por escaneo del programa. Este número en combinación con la constante global // denominada 'GIVE_BACK_TIME' determina qué tan agresivos serán los movimientos. iMoveAmount =5; // Obtener las posiciones actuales de los servos iTwistMoveCommand =gServoTwist.read (); iTiltMoveCommand =gServoTilt.read (); // Obtener promedios fTop =averageTopTwoSensors (); fBottom =averageBottomTwoSensors (); fLeft =averageLeftTwoSensors (); fRight =averageRightTwoSensors (); // Calcula el movimiento giratorio if (fLeft> fRight) {// Move positivo iTwistMoveCommand + =iMoveAmount; } else if (fRight> fLeft) {// Mover iTwistMoveCommand negativo - =iMoveAmount; } else {// Igual. no se mueva} // Calcular el movimiento de inclinación si (fTop>
 fBottom) {// Mover iTiltMoveCommand positivo + =iMoveAmount; } else if (fBottom> fTop) {// Mover iTiltMoveCommand negativo - =iMoveAmount; } else {// Igual. don't move} // Control de límites giro comando mover servo if (iTwistMoveCommand <0) {iTwistMoveCommand =0; } si (iTwistMoveCommand> 179) {iTwistMoveCommand =179; } // Control de límites comando de movimiento del servo de inclinación if (iTiltMoveCommand <45) {iTiltMoveCommand =45; } si (iTiltMoveCommand> 135) {iTiltMoveCommand =135; } // Realizar movimientos gServoTwist.write (iTwistMoveCommand); gServoTilt.write (iTiltMoveCommand); // Publicar resultados if (gVerboseDiagMode ==true) {Serial.println ("tl, tr, bl, br, top avg, bottom avg, left avg, right avg, twist move, tilt move:"); 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 (derecho); Serial.print (","); Serial.print (iTwistMoveCommand); Serial.print (","); Serial.println (iTiltMoveCommand); }} // leer valores de fotoresistores en variables globalesvoid readPhotoResistors () {// Los valores vienen escalados 0-1024 gLDR1 =analogRead (I_LDR1_PIN); gLDR2 =analogRead (I_LDR2_PIN); gLDR3 =analogRead (I_LDR3_PIN); gLDR4 =analogRead (I_LDR4_PIN);} // Cuando se ordena a los servos a una posición, se mueven a una velocidad rápida .// Demasiado rápido afectará potencialmente la estructura mecánica que sostiene y mueve // ​​el panel solar y la plataforma del sensor de luz. Esta rutina toma un "comando de movimiento" // y hace pequeños movimientos incrementales hasta que el servo está en la posición deseada .// Esta rutina es para el servo motor de torsión montado en la base smoothMoveTwist () {int iCurrentPos; int iMoveAmountPerScan; int iNewMoveCommand; // Establecer la cantidad de movimiento por escaneo en grados. // La combinación de esta variable y la constante global 'GIVE_BACK_TIME' determina la velocidad de movimiento general iMoveAmountPerScan =1; // Determinar la posición actual iCurrentPos =gServoTwist.read (); // ¿Estamos en posición? if (iCurrentPos ==gServoTwistPositionCommand) {gServoTwistMoveIP =false; regreso; } else {gServoTwistMoveIP =true; } // Empezar donde estamos actualmente en iNewMoveCommand =iCurrentPos; // Determinar la cantidad de movimiento si (iCurrentPos  179) {iNewMoveCommand =179; } // Mover gServoTwist.write (iNewMoveCommand); // Publicar los resultados if (gVerboseDiagMode ==true) {// todo:Serial.print ("Girar el movimiento del servo (este movimiento, total):"); Serial.print (iNewMoveCommand); Serial.print (","); Serial.println (gServoTwistPositionCommand); }} // Cuando se ordena a los servos a una posición, se mueven a gran velocidad. // Demasiado rápido afectará potencialmente la estructura mecánica que sostiene y mueve // ​​el panel solar y la plataforma del sensor de luz. Esta rutina toma un "comando de movimiento" // y hace pequeños movimientos incrementales hasta que el servo está en la posición deseada .// Esta rutina es para el servo motor de inclinación montado en el soporte smoothMoveTilt () {int iCurrentPos; int iMoveAmountPerScan; int iNewMoveCommand; // Establecer la cantidad de movimiento por escaneo en grados. // La combinación de esta variable y la constante global 'GIVE_BACK_TIME' determina la velocidad de movimiento general iMoveAmountPerScan =1; // Determinar la posición actual iCurrentPos =gServoTilt.read (); // ¿Estamos en posición? if (iCurrentPos ==gServoTiltPositionCommand) {gServoTiltMoveIP =false; regreso; } else {gServoTiltMoveIP =true; } // Empezar donde estamos actualmente en iNewMoveCommand =iCurrentPos; // Determinar la cantidad de movimiento si (iCurrentPos  179) {iNewMoveCommand =179; } // Mover gServoTilt.write (iNewMoveCommand); // Publicar resultados if (gVerboseDiagMode ==true) {// todo:Serial.print ("Movimiento del servo de inclinación (este movimiento, total):"); Serial.print (iNewMoveCommand); Serial.print (","); Serial.println (gServoTiltPositionCommand); }} // Tome el promedio matemático de los dos LDR en la parte superior de panelfloat averageTopTwoSensors () {float fAvg; // Math fAvg =(gLDR1 + gLDR2) / 2.0; return fAvg;} // Toma el promedio matemático de los dos LDR en la parte inferior de panelfloat averageBottomTwoSensors () {float fAvg; // Math fAvg =(gLDR3 + gLDR4) / 2.0; return fAvg;} // Toma el promedio matemático de los dos LDR a la izquierda de panelfloat averageLeftTwoSensors () {float fAvg; // Math fAvg =(gLDR1 + gLDR3) / 2.0; return fAvg;} // Toma el promedio matemático de los dos LDR a la derecha de panelfloat averageRightTwoSensors () {float fAvg; // Math fAvg =(gLDR2 + gLDR4) / 2.0; return fAvg;} // Procesar los mensajes recibidos desde la interfaz del puerto serie // El parámetro de entrada iControlCode es el valor recibido desde el puerto serie para ser procesado // Los primeros dos dígitos son el comando de control, los tres restantes son el valor para procesar void processSerialMessage (int iControlCode) {int iControlCommand; int iControlValue; // Calcular comando y valor iControlCommand =iControlCode / 1000; iControlValue =iControlCode% 1000; // Informe de comando y valor Serial.print ("código de control:"); Serial.println (iControlCode); Serial.print ("comando de control:"); Serial.println (iControlCommand); Serial.print ("valor de control:"); Serial.println (iControlValue); // Categoría de comando misceláneo if (iControlCommand ==10) {if (iControlValue ==0) {gVerboseDiagMode =true; digitalWrite (O_BLUE_LED_PIN, HIGH); Serial.println ("modo de diagnóstico iniciado"); } más si (iControlValue ==1) {gVerboseDiagMode =falso; digitalWrite (O_BLUE_LED_PIN, BAJO); Serial.println ("modo de diagnóstico detenido"); } más si (iControlValue ==2) {reportProductInfo (); } else if (iControlValue ==3) {// LED rojo en digitalWrite (O_RED_LED_PIN, HIGH); Serial.println ("led rojo encendido"); } else if (iControlValue ==4) {// LED rojo apagado digitalWrite (O_RED_LED_PIN, LOW); Serial.println ("led rojo apagado"); } else if (iControlValue ==5) {// LED verde en digitalWrite (O_GREEN_LED_PIN, HIGH); Serial.println ("led verde encendido"); } else if (iControlValue ==6) {// LED verde apagado digitalWrite (O_GREEN_LED_PIN, LOW); Serial.println ("led verde apagado"); } else if (iControlValue ==7) {// LED azul en digitalWrite (O_BLUE_LED_PIN, HIGH); Serial.println ("led azul encendido"); } else if (iControlValue ==8) {// LED azul apagado digitalWrite (O_BLUE_LED_PIN, LOW); Serial.println ("led azul apagado"); } else if (iControlValue ==9) {// Muestra el valor LDR1 Serial.print ("Valor LDR1:"); Serial.println (gLDR1); } else if (iControlValue ==10) {// Muestra el valor LDR2 Serial.print ("Valor LDR2:"); Serial.println (gLDR2); } else if (iControlValue ==11) {// Muestra el valor LDR3 Serial.print ("Valor LDR3:"); Serial.println (gLDR3); } else if (iControlValue ==12) {// Muestra el valor LDR4 Serial.print ("Valor LDR4:"); Serial.println (gLDR4); } else if (iControlValue ==13) {// Activar el modo de seguimiento enableTracking (); } else if (iControlValue ==14) {// Desactiva el modo de seguimiento disableTracking (); } else if (iControlValue ==19) {if (gRunning ==true &&gServoTwistMoveIP ==false &&gServoTiltMoveIP ==false) {gServoTwistPositionCommand =90; gServoTiltPositionCommand =90; Serial.println ("giro e inclinación de los servos comandados a 90 grados"); }} else if (iControlValue ==21) {if (gRunning ==true) {gTrackToLightEnabled =true; Serial.println ("Seguimiento a fuente de luz habilitado"); }} else if (iControlValue ==22) {gTrackToLightEnabled =false; Serial.println ("Pista a fuente de luz deshabilitada"); } else {Serial.print ("valor de control no válido:"); Serial.println (iControlValue); }} // Categoría de comando Servo1 (giro) if (iControlCommand ==11) {if (iControlValue> =0 &&iControlValue <=179) {// Mover el servo1 a la posición if (gRunning ==true &&gServoTwistMoveIP ==false) { gServoTwistPositionCommand =iControlValue; gServoTwistMoveIP =true; Serial.print ("Move twist servo command:"); Serial.println (gServoTwistPositionCommand); }} else {Serial.print ("valor de control no válido:"); Serial.println (iControlValue); }} // Categoría de comando Servo2 (inclinación) if (iControlCommand ==12) {if (iControlValue> =0 &&iControlValue <=179) {// Mover el servo2 a la posición // Mover el servo1 a la posición if (gRunning ==true &&gServoTiltMoveIP ==falso) {gServoTiltPositionCommand =iControlValue; gServoTiltMoveIP =true; Serial.print ("Mover comando de servo de inclinación:"); Serial.println (gServoTiltPositionCommand); } else {Serial.print ("el servo de inclinación no está habilitado o se está moviendo en curso"); Serial.print (gRunning); Serial.print (","); Serial.println (gServoTiltMoveIP); }} else {Serial.print ("valor de control no válido:"); Serial.println (iControlValue); }} // Fin de la cadena de solicitud Serial.println ("-----");} // Ejecutar una secuencia de pasos para las funciones de autoprueba, habilitar los servos y entrar en el modo de seguimiento de luz void startup () {int iDelay; // Inicializar iDelay =500; // Mostrar información de la aplicación reportProductInfo (); retraso (iDelay); // Enciende el LED rojo processSerialMessage (10003); retraso (iDelay); // Apague el LED rojo, encienda el LED verde processSerialMessage (10004); processSerialMessage (10005); retraso (iDelay); // Apague el LED verde, encienda el LED azul processSerialMessage (10006); processSerialMessage (10007); retraso (iDelay); // Apaga el LED azul, muestra los valores de la fotorresistencia (los cuatro) processSerialMessage (10008); processSerialMessage (10009); processSerialMessage (10010); processSerialMessage (10011); processSerialMessage (10012); retraso (iDelay); // Habilitar servos enableTracking (); retraso (iDelay); // Mueve los servos a la posición inicial processSerialMessage (10019); retraso (iDelay); // Deshabilitar servos disableTracking (); // Diga adiós Serial.println ("secuencia de inicio completada");} // Envíe la información del producto al puerto serialvoid reportProductInfo () {// Informe del producto y otra información al puerto serial Serial.println ("q versión 2" ); Serial.println ("Tucson, Arizona, EE. UU."); Serial.println ("mayo de 2018"); Serial.print ("suma de comprobación"); Serial.println ("58BA-D969-2F82-08FD-2078-2777-396D-E1AA");} 

Piezas y carcasas personalizadas

q2_assembly_details_RCbi893qzA.zip

Esquemas

q2_schematic_TVp7kakwNa.fzz

Proceso de manufactura

  1. Sistema de calefacción solar
  2. Célula solar
  3. Adquisición de datos en tiempo real del panel solar usando Arduino
  4. Persianas inteligentes
  5. Seguidor solar basado en Internet de las cosas (IoT)
  6. SmartPostBox
  7. Panel de seguidor solar de doble eje con modo automático y manual
  8. Rastreador solar de panel solar - Cargador de teléfono
  9. Entendiendo la energía solar
  10. Panel solar:problemas de calidad y puntos clave de control
  11. Proceso de fabricación de paneles solares:¿Cómo se fabrican los paneles solares?