Desde 1994 en la Red. La pagina de los aficionados a la electronica, informatica y otras curiosidades de la vida. No dudes en visitarnos.
Ahora 11 visitas.| 550427 Visitas (desde Dic. 2011), hoy: 1188 Visitas 1651 Pag. Vistas , ultimos 36 dias: 42869 Visitas. 66285 Pag. Vistas. Tu IP: 204.236.254.124
Que ando curioseando:
AutosuficienciaCosas de casaElectronicaEn InternetInformáticaMundo MisticoSin categoríaSociedadTe lo recomiendo

SEGUIDOR SOLAR CON ARDUINO


Ahora con tiempo he decidido rescatar del cajón los arduinos (un diecimila y un mini) que tenia desde hace dos años largos y con los que había trasteado un poco para probar, pero con los que no llegue a hacer nada medianamente interesante.
Mini central solar La finalidad de esta central es la de tener una fuente de alimentación de 5V para cargar los aparatos electrónicos (principalmente móviles) usando energía solar, aunque después de todo el motivo principal es el de empezar un poco mas en serio con la electrónica y todo el mundo de arduino, programar en C incluido.
Materiales Los materiales necesarios son un par de placas solares guiados mediante un soporte articulado que hara de seguidor con movimiento de guiñada (pan) y cabeceo (tilt) accionado mediante sus respectivos servos y controlados por un arduino mini. La energía entregada por las placas es almacenada en una batería de litio cuya carga así como la gestión de la alimentación la realiza un regulador (ligeramente modificado). También para el sensor de luz son necesarias tres fotorresistencias (LDR) y otras tres resistencias de 1KΩ, conectores, placa virgen y unas laminas de pvc. Aparte de estos elementos para montar el conjunto también necesite una caja donde meter la electrónica (arduino mini, batería, regulador, cableado, conexiones, etc), un perfil de aluminio en U (en mi caso de 15x10x1.5mm), cableado, conectores, fundas termoretractiles, tornilleria y un conector jack de alimentación de 5.5 para la salida de 5V.
Herramientas Para montar esto aparte de las herramientas típicas como alicates, destornilladores, llave inglesa, limas, cúter, pinzas, etc, también emplee las siguientes herramientas:
Soldador
Este es necesario para fabricar la placa de sensores de luz asi como desoldar un componente y puentearlo.
Soplador de aire caliente
Para realizar algunos empalmes de cables con cables y cables con conectores y ahorrar soldaduras, aislar la unión eléctricamente así como para reforzar la unión es necesario un soplador de aire caliente (en mi caso la Dremel VersaTip) para utilizar las fundas termoretractiles o camisas.
Minitaladro o también normalmente llamado simplemente: Dremel
Aunque no es estrictamente necesario, si que viene muy bien tanto para realizar entre otras cosas cortes, hendiduras, taladros y pulido de los perfiles y tornillo de fijación.
Polimetro
Prácticamente imprescindible para realizar las comprobaciones eléctricas de continuidad y voltaje para cercionarse de que todo este correcto.
Pistola de cola termofusible
Para pegar las laminas en cruz que guían la luz hacia los sensores.
Cloruro férrico
Para realizar la placa de sensores y dibujar las pistas use un rotulador permanente para después con el ácido (el cloruro férrico) atacar el cobre de la placa.
 
Programación La programación ha sido bastante sencilla ya que que solo había que realizar el control del seguidor y este era bastante facil por lo que no ha habido complicaciones con el código fuente. Lo difícil, el control de los servos, se resuelve empleando una librería que incluye el entorno de arduino.
Electrónica Empezando por el regulador que gestiona la energía de la central hay que destacar que el componente TS1117BCP50 que es un regulador de voltaje que baja los 12V hasta los 5V lo quite de la placa para a continuación puentear la entrada de 12V directamente hasta donde este tenia la salida de 5V. Esto es debido a que en mi caso las placas que uso tienen un valor de pico de 5.5V y el controlador de carga de la batería, un MAX1555, acepta dos entradas de 3.7 a 7.0V y 3.7 a 6.0V. Cada placa va a una de las entradas y dado que este controlador solo selecciona una al mismo tiempo un panel siempre esta de respaldo por si el otro falla o no le llega luz con la intensidad necesaria. La batería esta conectada a sus terminales correspondientes. La placa dispone de un convertidor DC/DC, el MAX1674, que es el que finalmente nos proporciona la alimentación de 5V a partir de la energía de la batería. Respecto al sensor de luz para el guiado este no es mas que tres divisores de tensión formados por una fotorresistencia y una resistencia de 1K. Las resistencias de 1K están conectadas a tierra mientras que las fotorresistencias no estan conectadas a la alimentación de 5V directamente sino a una salida digital del arduino mini que permanece en alto únicamente para realizar las lecturas de los sensores para ahorrar algo de energía. Por ultimo las conexiones del arduino son las siguientes tal y como se ha programado:
D9
D10
Señal de control de los servos que controlan los eje vertical y horizontal respectivamente.
D12
Alimentación para los divisores de tensión.
A0
A1
A2
Conectado al punto medio de los divisores de tensión. El primero es el sensor de referencia mientras que el segundo y tercero son para los sensores vertical y horizontal situados a la derecha y debajo del de referencia respectivamente.
5V
La alimentación conectada al regulador.
GND
Tierra, masa, común o como lo quieras llamar.
 
Construcción

El primer paso es montar el mecanismo del seguidor junto con los servos para hacernos una idea del radio que abarcara al realizar los movimientos en ambos ejes y visualizar como deberán colocarse los paneles y como sera el brazo de soporte.

Montaremos el soporte para los dos paneles solares y el sensor con un trozo del perfil de aluminio al que le hemos realizado cuatro taladros y dos cortes para poder introducirlo en el seguidor. Estos primeros se fijaran con tornillos de cabeza plana y ancha con los que atraparlos y retenerlos. A su vez el perfil se fija al seguidor con un tornillo con tuerca.

Lo siguiente es unir el seguidor al brazo de soporte. Este es otro trozo del mismo tipo de perfil al que se le ha practicado un rebaje para dejar un hueco donde acomodar el cuerpo del servo que soporta el seguidor. Para fijar este se hace mediante dos pequeños tacos de madera que presionan a las pestañas del servo contra el perfil.

Por ultimo, en el otro extremo del brazo soporte sera donde se introduzca la cabeza de un tornillo rebajada con la Dremel hasta hacer que esta tenga el mismo grosor que la medida interior del perfil. Por seguridad y para evitar que el perfil no se da de si con el movimiento provocado por el viento he pasado un par de tornillos con tuerca a cada lado del tornillo de sujeción con la que aprisionarlo.

La caja que alberga toda la electrónica la he mecanizado un poco realizando unos rebajes en la parte baja poder albergar el perfil del soporte. Una vez cerrada la tapa de la caja esta quedara fijada al brazo.

Para el sensor, mediante unas laminas de PVC he fabricado una cruceta larga para separar los sensores en sectores diferentes y asi poder determinar de donde procede la luz. Esta va unida a la placa de sensores con unos cuantos puntos de cola termofusible.

Montaje

Una vez que tenemos preparado todos los materiales pasamos al montaje. Este consistirá en ir ensamblando las piezas que hemos ido creando y sobre todo en realizar el cableado.

Respecto al cableado tuve un pequeño problema con los cables que utilice para el sensor ya que el grosor de estos hacia que el seguidor no se quedara quieto tras orientarse ya que los cables tiraban.

Para resolverlo corte por lo sano y sustituí un tramo por hilo de cobre esmaltado sacado de un trasformador con lo que el problema se resolvió.

Tras el cableado solo realizar las conexiones dentro de la caja donde afortunadamente pude meter todo sin quedar espacio para meter nada mas y gracias. Después probé que todo funcionara y de nuevo a dar gracias.

Por ultimo solo quedaba ponerlo en su lugar definitivo, en la terraza. Dado que donde vivo tiene la barandilla de cristal ligeramente tintado prácticamente trasparente puse la central solar tras el cristal para protegerlo del viento y cerca del suelo para que no le tape el sol al bajar el toldo.

La barandilla es metálica y por suerte tenia un agujero para un tornillo que quite (tranquilos, no es estructuralmente esencial para la barandilla) y lo sustituí por el mio ya mecanizado. Lo siguiente era introducir a presión el tornillo en el perfil de soporte y asegurarlo pasando los tornillos con su tuerca en los agujeros de ambos lados con lo que el invento estaba terminado.

PruebasDespués de esto había que esperar a que el aparato siguiera al sol y así lo hizo. El movimiento que realiza tras ver un ciclo completo (una rotación de la tierra, de día a noche y de nuevo al día) es de vaivén. Es decir, teniendo en cuenta que el arco que gira es de unos 135 grados siendo 0 prácticamente el sur y 135 el noreste el movimiento es de 0 → 135, 135 → 0 en vez de lo que se puede esperar de 0 → 135, 0. Esto es debido a que al amanecer el cielo que es donde quedo apuntando al atardecer del día anterior sigue siendo lo mas brillante pero al ir subiendo el sol la luz va incidiendo mas y mas sobre el edificio de enfrente que esta un poco a la izquierda y refleja parcialmente la luz y por eso vuelve poco a poco hacia donde sale el sol en vez de golpe.Las pruebas que me quedan son las de esperar a que llueva, ver si sigue funcionando y si es necesario impermeabilizarlo mejor. La prueba del viento ya la ha superado y por suerte (o mala suerte) en Zaragoza los días de viento fuerte no se hacen esperar.

ConclusionesBueno, un proyecto sencillito para empezar a trastear mas en serio con el arduino. En cuanto a los paneles solares, haciendo pruebas, me parece que el esfuerzo de montar un seguidor no compensa demasiado frente a orientarlo y fijarlo convenientemente e invertir si es necesario en paneles mas eficientes. Aun así, desde luego verlo moverse mola mas.En cuanto a posibles ampliaciones el siguiente paso quizás sea poner algún sucedáneo de estación meteorológica, y sobre todo que se comunique con el resto del mundo inalambricamente para probar XBee, pero desde luego cambiando la caja porque no cabe nada mas ahora.

 
 
<pre>#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <Servo.h>

// Depuracion.
boolean depuracion = false;

// Seguidor.
Servo seguidor_servo_vertical_controlador;
int seguidor_servo_vertical_pin = 9;
int seguidor_servo_vertical_angulo_valor = 90;
int seguidor_servo_vertical_angulo_min = 5;
int seguidor_servo_vertical_angulo_max = 175;
Servo seguidor_servo_horizontal_controlador;
int seguidor_servo_horizontal_pin = 10;
int seguidor_servo_horizontal_angulo_valor = 90;
int seguidor_servo_horizontal_angulo_min = 5;
int seguidor_servo_horizontal_angulo_max = 175;
int seguidor_servo_alimentacion_pin = 2;
int seguidor_orientacion_alimentacion_pin = 12;
int seguidor_orientacion_referencia_valor;
int seguidor_orientacion_referencia_pin = 0;
int seguidor_orientacion_vertical_valor;
int seguidor_orientacion_vertical_pin = 1;
int seguidor_orientacion_horizontal_valor;
int seguidor_orientacion_horizontal_pin = 2;
int seguidor_orientacion_desviacion_max = 50;
boolean seguidor_actualizacion_activo = false;

// Inicializacion.
void setup(){
  if(depuracion) Serial.begin(9600);

  seguidor_inicializar();
}

// Marcha.
void loop(){
  // Actualizamos el estado de los servos.
  seguidor_actualizar_estado();

  // Dormimos el arduino.
  reposar();
}

// Control del seguidor.

void seguidor_inicializar(){
  pinMode(seguidor_orientacion_alimentacion_pin, OUTPUT);
  pinMode(seguidor_servo_alimentacion_pin, OUTPUT);

  digitalWrite(seguidor_orientacion_alimentacion_pin, LOW);
  digitalWrite(seguidor_servo_alimentacion_pin, LOW);

  seguidor_actualizar_estado();
}

void seguidor_actualizar_estado(){
  // Comprobamos si ya se esta actualizando la orientacion.
  if(seguidor_actualizacion_activo){
    return;
  }

  // Ajustamos la orientacion.

  // Marcamos que estamos realizando el proceso.
  seguidor_actualizacion_activo = true;

  // Alimentamos el sensor.
  digitalWrite(seguidor_orientacion_alimentacion_pin, HIGH);

  // Realizamos una lectura para despertar el ADC.

  // Mientras sea necesario orientamos el seguidor.
  do{
    delay(50);
  }while(seguidor_actualizar_estado_orientacion());

  // Quitamos la alimentacion al sensor.
  digitalWrite(seguidor_orientacion_alimentacion_pin, LOW);

  // Marcamos el fin de la actualizacion de la orientacion.
  seguidor_actualizacion_activo = false;
}

boolean seguidor_actualizar_estado_orientacion(){
  // Referencia.
  seguidor_orientacion_referencia_valor = analogRead(seguidor_orientacion_referencia_pin);

  // Vertical.

  seguidor_orientacion_vertical_valor = analogRead(seguidor_orientacion_vertical_pin);

  int seguidor_orientacion_vertical_desviacion_valor = seguidor_orientacion_referencia_valor - seguidor_orientacion_vertical_valor;

  int seguidor_orientacion_vertical_desviacion_abs = abs(seguidor_orientacion_vertical_desviacion_valor);

  if(seguidor_orientacion_vertical_desviacion_abs > seguidor_orientacion_desviacion_max){
    if(seguidor_orientacion_vertical_desviacion_valor > 0){
      seguidor_servo_vertical_angulo_valor--;

    }else{
      seguidor_servo_vertical_angulo_valor++;
    }

    seguidor_servo_vertical_angulo_valor = constrain(seguidor_servo_vertical_angulo_valor, seguidor_servo_vertical_angulo_min, seguidor_servo_vertical_angulo_max);
  }

  // Horizontal.

  seguidor_orientacion_horizontal_valor = analogRead(seguidor_orientacion_horizontal_pin);

  int seguidor_orientacion_horizontal_desviacion_valor = seguidor_orientacion_referencia_valor - seguidor_orientacion_horizontal_valor;

  int seguidor_orientacion_horizontal_desviacion_abs = abs(seguidor_orientacion_horizontal_desviacion_valor);

  if(seguidor_orientacion_horizontal_desviacion_abs > seguidor_orientacion_desviacion_max){
    if(seguidor_orientacion_horizontal_desviacion_valor > 0){
      seguidor_servo_horizontal_angulo_valor--;

    }else{
      seguidor_servo_horizontal_angulo_valor++;
    }

    seguidor_servo_horizontal_angulo_valor = constrain(seguidor_servo_horizontal_angulo_valor, seguidor_servo_horizontal_angulo_min, seguidor_servo_horizontal_angulo_max);
  }

  if(depuracion) Serial.print("R: ");
  if(depuracion) Serial.println(seguidor_orientacion_referencia_valor);
  if(depuracion) Serial.print("V: ");
  if(depuracion) Serial.println(seguidor_orientacion_vertical_valor);
  if(depuracion) Serial.println(seguidor_servo_vertical_angulo_valor);
  if(depuracion) Serial.println(seguidor_orientacion_vertical_desviacion_valor);
  if(depuracion) Serial.print("H: ");
  if(depuracion) Serial.println(seguidor_orientacion_horizontal_valor);
  if(depuracion) Serial.println(seguidor_servo_horizontal_angulo_valor);
  if(depuracion) Serial.println(seguidor_orientacion_horizontal_desviacion_valor);
  if(depuracion) Serial.println("----");
  if(depuracion) delay(500);

  boolean continuar_orientacion=false;

  if(
     seguidor_orientacion_vertical_desviacion_abs < seguidor_orientacion_desviacion_max
  && seguidor_orientacion_horizontal_desviacion_abs < seguidor_orientacion_desviacion_max
  ){
    continuar_orientacion = false;

  }else if(
     seguidor_servo_vertical_angulo_min < seguidor_servo_vertical_angulo_valor && seguidor_servo_vertical_angulo_valor < seguidor_servo_vertical_angulo_max
  || seguidor_servo_horizontal_angulo_min < seguidor_servo_horizontal_angulo_valor && seguidor_servo_horizontal_angulo_valor < seguidor_servo_horizontal_angulo_max
  ){
    continuar_orientacion = true;

  }else{
    continuar_orientacion = false;
  }

  if(!continuar_orientacion){
    seguidor_servo_vertical_controlador.detach();
    seguidor_servo_horizontal_controlador.detach();

    digitalWrite(seguidor_servo_alimentacion_pin, LOW);

    return continuar_orientacion;
  }

  digitalWrite(seguidor_servo_alimentacion_pin, HIGH);

  seguidor_servo_vertical_controlador.attach(seguidor_servo_vertical_pin);
  seguidor_servo_vertical_controlador.write(seguidor_servo_vertical_angulo_valor);

  seguidor_servo_horizontal_controlador.attach(seguidor_servo_horizontal_pin);
  seguidor_servo_horizontal_controlador.write(seguidor_servo_horizontal_angulo_valor);

  return continuar_orientacion;
}

// Pone a dormir el micro y activa el watchdog para despertarlo pasado un periodo de tiempo.
void reposar(){
  // Habilitamos el watchdog.
  watchdog_interrupcion_activar();

  // Sleep mode control register
  // SMCR: – – – – SM2 SM1 SM0 SE
  // SM2
  //   SM1
  //     SM0
  //       Sleep mode
  // 0 0 0 Idle
  // 0 0 1 ADC noise reduction
  // 0 1 0 Power-down
  // 0 1 1 Power-save
  // 1 0 0 Reserved
  // 1 0 1 Reserved
  // 1 1 0 Standby
  // 1 1 1 Reserved
  //
  // SLEEP_MODE_IDLE < SLEEP_MODE_ADC < SLEEP_MODE_PWR_SAVE < SLEEP_MODE_STANDBY < SLEEP_MODE_PWR_DOWN

  // Establecemos el modo de dormir.
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Desconexion de perifericos.

  // En los modos IDLE y ADC el comparador analogico hay que deshabilitarlo, pero si usamos la referencia interna hay que deshabillitarlo en todos los modos.
  ACSR |= 1<<ACD;

  // El conversor A/D siempre esta activo en todos los modos de dormir.
  power_adc_disable();

  // Desconectamos el resto.
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
  power_twi_disable();
  power_usart0_disable();

  // Permitimos dormir al micro.
  sleep_enable();

  // Ponemos a dormir al micro.
  sleep_cpu();

  // ZZZ. ZZZ.

  // Tras ejecutar la rutina ISR de la interrupcion que ha despertado el micro continua la ejecucion.

  // Permitimos dormir al micro.
  sleep_disable();

  // Habilitamos todo.
  power_all_enable();
}

ISR(WDT_vect) {
  // Deshabilitamos el watchdog.
  watchdog_interrupcion_desactivar();
}
void watchdog_interrupcion_activar(){
  // MCUSR: – – – – WDRF BORF EXTRF PORF
  //                Flag que indica la ocurrencia del reset del watchdog. Se debe borrar para poder borrar WDTCSR:WDE ya que sobreescribe a este ultimo cuando esta habilitado.

  // WDTCSR: WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0
  //         Indica la interrupcion del watchdog. Se borra automaticamente tras salir de la rutina de interrupcion del watchdog.
  //                   >             >    >    >     Periodo de espera del watchdog antes de saltar.
  //              Bandera para habilitar la interrupcion del watchdog.
  //                        Fusible para permitir (durante 4 ciclos) cambiar las propiedades del registro del watchdog.
  //                             Bandera para habilitar provocar la ejecucion de la rutina de reset del watchdog.
  //
  // 0 0 0 0 2K     16ms   | 2048       16ms
  // 0 0 0 1 4K     32ms   | 4096       32ms
  // 0 0 1 0 8K     64ms   | 8192       64ms
  // 0 0 1 1 16K    0.125s | 16384     128ms
  // 0 1 0 0 32K    0.25s  | 32768     256ms
  // 0 1 0 1 64K    0.5s   | 65536     512ms
  // 0 1 1 0 128K   1.0s   | 131072   1024ms
  // 0 1 1 1 256K   2.0s   | 262144   2048ms
  // 1 0 0 0 512K   4.0s   | 524288   4096ms
  // 1 0 0 1 1024K  8.0s   | 1048576  8192ms
  // WDP3    Number of Typical time-out at
  //   WDP2         WDT oscillator cycles VCC = 5.0V
  //     WDP1
  //       WDP0

  // Deshabilitamos las interrupciones temporalmente para que no se activen mientras editamos las propiedades del watchgdog.
  cli(); // SREG &= B01111111;

  // Reiniciamos el reloj del watchdog.
  wdt_reset();

  // Borramos la bandera que indica el reset del watchdog (para asegurarnos de poder deshabilitar WDTCSR:WDE).
  MCUSR &= ~(1<<WDRF);

  // Mandamos la orden para activar la posibilidad de cambiar las propiedades del watchdog y borrar el reset del watchdog. Debemos cambiarlas antes de 4 ciclos.
  WDTCSR |= (1<<WDCE) | (1<<WDE);

  // Establecemos la nueva configuracion del registro de control del watchdog.
  WDTCSR = ((1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0) | (1<<WDIE)) & ~(1<<WDE);

  // Rehabilitamos las interrupciones.
  sei(); // SREG |= B10000000;
}
void watchdog_interrupcion_desactivar() {
  // Deshabilitamos las interrupciones temporalmente para que no se activen mientras editamos las propiedades del watchgdog.
  cli(); // SREG &= B01111111;

  // Reiniciamos el reloj del watchdog.
  wdt_reset();

  // Borramos la bandera que indica el reset del watchdog (para asegurarnos de poder deshabilitar WDTCSR:WDE).
  MCUSR &= ~(1<<WDRF);

  // Mandamos la orden para activar la posibilidad de cambiar las propiedades del watchdog y borrar el reset del watchdog. Debemos cambiarlas antes de 4 ciclos.
  WDTCSR |= (1<<WDCE) | (1<<WDE);

  // Deshabilitamos todo el watchdog.
  WDTCSR = B00000000;

  // Rehabilitamos las interrupciones.
  sei(); // SREG |= B10000000;
}</pre>

Fuente: http://vac2.net/bitacora/actualizacion_seguidor.

Comentarios (2)

Javier23 julio 2014 at 2:56

En la parte superior tienes un cuadrado verde y uno azul… a qué corresponden estos? Espero que me puedas ayudar, ya que estoy probando este proyecto y sólo me detiene esto. Saludos.

pesadillo27 julio 2014 at 12:15

El cuadrado azul corresponde con el sistema de batería de alimentación, y el verde con el sistema de regulación de alimentación proveniente de los paneles solares y baterías.

Escribe un comentario

Tu comentario