Eguzkigrafia eguzkiak zeruan (Lur planetako leku bakoitzean modu ezberdinean) daukan ibilbidea behatzen duen efektua argazkigintzako praktika eta kontzeptua da. Paisaian horrek duen efektua argazkigintza estenopeikoa, tratamentu digitala eta Internet bidezko hedapena konbinatzen duen prozedimentu espezifikoa da. Rebelatu gabeko argazkigintzako papera erabiltzen da , kamara estenopeikoa eta eskanerra erabiltzen da eguzkiak egunero zeruan (orduak eta hilabeteen arteko esposizio luzeak) egiten duen ibilbidea jasotzen duen irudiak sortzeko. Bere sorreratik dauka mundu osoko afizionatuen artean Internet bidez hedatzeko, kolaboratzeko eta partekatzeko zaletasuna eta nahia.
Proiektu honen helburua modu automatizatuan eguzki-analema jasotzea da. Eguzkiak zeruaren esferan duen batez besteko posiziotik (egun berean ordu berean eta leku beretik) aldentzen denean osatzen duen kurba da analema. Gehienetan, terminoa Eguzkiak urtean zehar betetzen dituen posizioek zeruan marrazten duten irudia izendatzeko erabiltzen da. Analemak zortzi (8) formako kurba osatzen du.
Analema eskuz jasotzeak urte batez jarraian ordu berean eta leku berean argazki bat ateratzea esan nahi du. Batzuetan zaila gertatzen denez hori egitea argazki kamara bat edukitzea egunero ordu berean argazki bat aterako duena ariketa hau egiteko oso baliagarria izan daiteke.
Proiektu honetan Arduino bidez kontrolatzen den kamara bat sortu da; ordu sinkronizaziorako RTC-a (real time clock) erabili da eta kanpoko elikatze-iturrien beharrik ez izateko bateria sistema bat eta eguzki-panel bat. Sistema horrek eguzkiaren irudia jasotzeko eragozpenik gabeko leku zailetan kokatzea ahalbidetzen du. Kamararen obturadorea (pinhole motakoa) servo de 9gr kontrolatzen du, zeinek pinhole-aren zuloa ezkutatzen duen pieza bat mugitzen duen.
Pausuz pausu
- Arduino Nano
- RTC DS3231 moduloa
- SparkFun SunnyBuddy
- Eguzki panela
- Lipo 1S 2000 mAh bateria
- Servo 9gr
- LED 5mm
- 220 Ohm ERresistentzia
- Konexio kablea
/* Eguzkigrafia kamararen kontrola David Pello 2019 Eguzkigrafia kamarako obtuladorearen irekiera kontrolatzen du servo eta RTC DS3231 erabiliz. Arduino Nano batentzat pentsatua. */ #include #include #include #include #include // Soft reset #define RESTART asm("jmp 0x0000") // secuencias #define TOMA_SOL2 #define TOMA_SOL3 // tiempos #define HORA_APERTURA_SOL1 16 #define MIN_APERTURA_SOL1 0 #define HORA_CIERRE_SOL1 16 #define MIN_CIERRE_SOL1 1 #define HORA_APERTURA_SOL2 17 #define MIN_APERTURA_SOL2 0 #define HORA_CIERRE_SOL2 17 #define MIN_CIERRE_SOL2 1 #define HORA_APERTURA_SOL3 18 #define MIN_APERTURA_SOL3 0 #define HORA_CIERRE_SOL3 18 #define MIN_CIERRE_SOL3 1 #define HORA_APERTURA_PAISAJE 9 #define MIN_APERTURA_PAISAJE 0 #define HORA_CIERRE_PAISAJE 10 #define MIN_CIERRE_PAISAJE 55 #define ANGULO_APERTURA 30 #define ANGULO_CIERRE 0 #define PIN_ACT_OBTURADOR 3 // Arduino D3 #define PIN_CONFIGURACION_I 6 // D6 #define PIN_CONFIGURACION_O 7 // D7 #define SLEEPTIME 30 // ESTADOS #define ESPERA_SOL1 0 #define ABRE_SOL1 1 #define ESPERA_SOL2 2 #define ABRE_SOL2 3 #define ESPERA_SOL3 4 #define ABRE_SOL3 5 #define ESPERA_PAISAJE 6 #define ABRE_PAISAJE 7 // variables DS3231 Clock; Servo obturador; byte anyo; byte mes; byte dia; byte dia_semana; byte hora; byte minuto; bool h12, pm, siglo; byte estado; struct rst_info* reset_info; int init_mode; byte ADay, AHour, AMinute, ASecond, ABits; bool ADy, A12h, Apm; void setup() { delay(1); // Iniciamos el I2C Wire.begin(); // Aseguramos que estamos en modo de 24h Clock.setClockMode(false); // Empezar de cero siglo = false; // LED pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); // IO pinMode(PIN_CONFIGURACION_I, INPUT_PULLUP); pinMode(PIN_CONFIGURACION_O, OUTPUT); // set to LOW digitalWrite(PIN_CONFIGURACION_O, LOW); // Y el puerto serie Serial.begin(115200); Serial.println(); Serial.println("Iniciando..."); // Vemos si tenemos que reiniciar o no. init_mode = digitalRead(PIN_CONFIGURACION_I); Serial.print("Configuración Leida: "); Serial.println(init_mode); if (init_mode) { // parpadeo digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); Serial.println("Continuando..."); // Cargamos el modo actual desde la eeprom estado = EEPROM.read(0); Serial.print("Estado leido: "); Serial.println(estado); // Leemos el RTC mes = Clock.getMonth(siglo); dia_semana = Clock.getDoW(); dia = Clock.getDate(); hora = Clock.getHour(h12, pm); minuto = Clock.getMinute(); Serial.println(); Serial.print("---- "); Serial.print(mes); Serial.print("/"); Serial.print(dia); Serial.print(" "); Serial.print(hora); Serial.print(":"); Serial.println(minuto); if (Clock.checkAlarmEnabled(1)) { Serial.println("nAlarm 1 enabled"); } Serial.print("Alarm 1: "); Clock.getA1Time(ADay, AHour, AMinute, ASecond, ABits, ADy, A12h, Apm); Serial.print(ADay, DEC); if (ADy) { Serial.print(" DoW"); } else { Serial.print(" Date"); } Serial.print(' '); Serial.print(AHour, DEC); Serial.print(' '); Serial.print(AMinute, DEC); Serial.print(' '); Serial.print(ASecond, DEC); Serial.print(' '); if (A12h) { if (Apm) { Serial.print('pm '); } else { Serial.print('am '); } } Serial.print(' '); Serial.println(ABits, BIN); } else { Serial.println("Iniciando desde cero..."); // parpadeo largo for (int i = 0; i < 20; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(100); } // iniciamos estado = ESPERA_SOL1; EEPROM.write(0, estado); // obturador cerrado obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); // Leemos el RTC mes = Clock.getMonth(siglo); dia_semana = Clock.getDoW(); hora = Clock.getHour(h12, pm); minuto = Clock.getMinute(); Serial.println(); Serial.print("---- "); Serial.print(hora); Serial.print(":"); Serial.println(minuto); // Ponemos la alarma (0x8 = 1000b = A4 A3 A2 A1 = horas,minutos,segundos da igual el día) Clock.setA1Time(0, HORA_APERTURA_SOL1, MIN_APERTURA_SOL1, 0, 0x8, false, false, false); // Y la activamos Clock.turnOnAlarm(1); } } void loop() { // reiniciamos el i2c // Wire.begin(); // Comprobamos alarma if (Clock.checkIfAlarm(1)) { Serial.println("Evento de alarma RTC!"); // Dependiendo del estado actual... switch (estado) { case ESPERA_SOL1: // Abrimos obturador estado = ABRE_SOL1; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_APERTURA); delay(250); obturador.detach(); Serial.println("Abriendo SOL1"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_CIERRE_SOL1, MIN_CIERRE_SOL1, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; case ABRE_SOL1: // Cerramos obturador // cambiamos el estado dependiendo de si hay más aperturas de sol #ifndef TOMA_SOL2 estado = ESPERA_PAISAJE; EEPROM.write(0, estado); EEPROM.commit(); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando SOL1 -> Espera Paisaje"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_PAISAJE, MIN_APERTURA_PAISAJE, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); #else estado = ESPERA_SOL2; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando SOL1 -> Espera SOL2"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_SOL2, MIN_APERTURA_SOL2, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); #endif break; case ESPERA_SOL2: // Abrimos obturador estado = ABRE_SOL2; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_APERTURA); delay(250); obturador.detach(); Serial.println("Abriendo SOL2"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_CIERRE_SOL2, MIN_CIERRE_SOL2, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; case ABRE_SOL2: // Cerramos obturador // cambiamos el estado dependiendo de si hay más aperturas de sol #ifndef TOMA_SOL3 estado = ESPERA_PAISAJE; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando SOL2... -> Espera paisaje"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_PAISAJE, MIN_APERTURA_PAISAJE, 0, 0x0, false, false, false); Clock.turnOnAlarm(1); #else estado = ESPERA_SOL3; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando SOL2... -> Espera SOL3"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_SOL3, MIN_APERTURA_SOL3, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); #endif break; case ESPERA_SOL3: // Abrimos obturador estado = ABRE_SOL3; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_APERTURA); delay(250); obturador.detach(); Serial.println("Abriendo SOL3"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_CIERRE_SOL3, MIN_CIERRE_SOL3, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; case ABRE_SOL3: // Cerramos obturador estado = ESPERA_PAISAJE; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando SOL3... -> Espera Paisaje"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_PAISAJE, MIN_APERTURA_PAISAJE, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; case ESPERA_PAISAJE: // Abrimos obturador estado = ABRE_PAISAJE; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_APERTURA); delay(250); obturador.detach(); Serial.println("Abriendo Paisaje"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_CIERRE_PAISAJE, MIN_CIERRE_PAISAJE, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; case ABRE_PAISAJE: // Cerramos obturador estado = ESPERA_SOL1; EEPROM.write(0, estado); obturador.attach(PIN_ACT_OBTURADOR); obturador.write(ANGULO_CIERRE); delay(250); obturador.detach(); Serial.println("Cerrando Paisaje -> Espera SOL1"); // ponemos la nueva alarma dia_semana = Clock.getDoW(); Clock.setA1Time(0, HORA_APERTURA_SOL1, MIN_APERTURA_SOL1, 0, 0x8, false, false, false); Clock.turnOnAlarm(1); break; } // Apagamos el i2c //Wire.end(); } // a dormir (bajo consumo) Serial.flush(); // wait for serial for (int i = 0 ; i < 15 ; i++) LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); RESTART; }
Eskeman azaldutako zirkuitua muntatu ondoren eta RTC -ak ordua ondo jarrita duela baieztatu ondoren (ordua jartzeko RTC DS3231 ematen duen adibidea erabiliz ) arduinoa goian azaldutako kodearekin programatu behar da. Horretarako nahi diren ordu kodeak konfiguratu beharko dira.
Denbora sekzioan hartualdi bakoitzaren orduak, minutuak eta segundoak aldatuko dira, eta TOMA_SOL2 eta TOMA_SOL3 komentatu edo deskomentatuko dugu, baldin eta bat, bi edo hiru hartualdi nahi ditugun (eta beraz galeriako irudiko adibideko analemen kasua bezalaxe).
Ondoren arduinoa kodearekin programatuko dugu eta sistema guztia erabiliko dugun kameraren barruan montatua utzi. Hermetikoa den kaxa bat erabiltzea gomendatzen da, hartualdien neurrien araberako PVC konexioen kaxa bat (gure pinholearen araberakoa, foku-distantzia, etab.). Serboa pieza batekin itsatsiko dugu, modu horretan serboa 0º posizioan dagoenean obtuladorea estaliko du. Frogaren bat egin genezake aurretik, arduinoaren inguruko serboaren kontrolarekin, posizioaren eta mugimenduaren zentzuaren jarraipena egiteko.
Eguzki-panela, hegoalderantz begira jarriko dugu eta ikuspegia zeruertzera begira, eguzki-esposizioa maximizatzeko helburuarekin.
Kamera itxi aurretik, kodea berabiarazi behar da. Horretarako eskeman I/O moduan markatuak dauden pinak konektatuko dira eta plakari elikatze-iturria jarriko diogu, horrekin programak ulertuko du zerotik hasi behar duela. Ondoren guztia deskonektatuko dugu, I/O pinak barne eta sistema berriz ere elikatzen jarriko dugu. Hemendik aurrera hartualdiak automatikoki egiteko prest geratuko da. Sistema bizirik ote dagoen ikusteko modua eskemako LED-era begiratzea izango da, 30 segundoero kliskatu beharko luke-eta.