Commande d’un APN reflex avec GPHOTO2

il est possible de commander et configurer un APN reflex moderne en remote via USB avec un Raspberry PI en utilisant la librairie GPHOTO2.cette option est très intéressante pour l’astro-photo, en particulier pour des time-laps en pauses longues. nous allons voir ici comment procéder.

le site internet dédié a Gphoto2 est accessible via ce lien: http://www.gphoto.org/

avant de poursuivre plus loin, il est important de verifier que votre APN reflexe est compatible avec la librairie, pour cela voir la liste ici:

liste des APN compatibles: http://www.gphoto.org/proj/libgphoto2/support.php

INSTRUCTION D’INSTALLATION

avant de pouvoir utiliser Gphoto2 il va falloir faire l’installation des prérequis et de la librairie elle même . ci dessous les instructions qui sont disponible dans le fichier joint en PDF pour pour pouvoir faire des copier coller des lignes de commandes.

PREREQUIS: installation des dependances:

sudo apt-get install git make autoconf libltdl-dev libusb-dev libexif-dev libpopt-dev libxml2-dev libjpeg-dev libgd-dev gettext autopoint

INSTALLATION DE libghoto2:

télécharger le code pour libgphoto2 ici: https://github.com/gphoto/libgphoto2.git

executer les commandes ci dessous pour installer libgphoto2

cd ~/libgphoto2
autoreconf --install --symlink
./configure
make
sudo make install

INSTALLATION DE ghoto2

télécharger le code pour gphoto2 ici: https://github.com/gphoto/gphoto2.git

executer les commandes ci dessous pour installer gphoto2

cd ~/gphoto2
autoreconf --install --symlink
./configure
make
sudo make install

MISE A JOUR DE LA CONFIGURATION RPI

ajouter la lignes ci dessous dans le fichierde configuration : /etc/ld.so.conf.d/libc.conf

/usr/local/lib

rafraichir le cache avant de continuer:

sudo ldconfig

créer les regles udev pour l’APN

/usr/local/lib/libgphoto2/print-camera-list udev-rules version 201 group plugdev mode 0660 | sudo tee /etc/udev/rules.d/90-libgphoto2.rules

créer la base de données pour udev

/usr/local/lib/libgphoto2/print-camera-list hwdb | sudo tee /etc/udev/hwdb.d/20-gphoto.hwdb

UTILISATION DE GPHOTO2

gphoto2 est un “catalogue” de fonctions permettant d’envoyer des commandes a votre APN reflex via le port USB et avec des commandes shell sous linux . voici la liste des commandes:

http://www.gphoto.org/doc/manual/ref-gphoto2-cli.html

nous allons en tester 2 pour cela connecter votre APN reflex a votre RPI via son cordon USB et executer la commande shell ci dessous pour verifier que votre Gphoto2 detecte bien votre APN:

gphoto2 –auto-detect

si le nom de votre Appareil photo apparait après l’exécution de la commande c’est que tout est OK et vous pouvez aller plus loin et exécuter le premier test en prenant une photo. pour cela exécuter la commande shell ci dessous:

gphoto2 –capture-image

UTILISATION DE GPHOTO2 AVEC PYTHON

le travail en mode de commande shell n’est pas des plus convivial particulierement la nuit en nomade . nous allons voir ici comment utiliser Gphoto2 via un programme python. pour cela, il faut d’abord installer le module python permettant d’encapsuler Gphoto2 . exécuter la commande:

sudo pip install -v gphoto2

nous allons maintenant écrire un petit programme Python qui permet de prendre une photo et de l’enregistrer sur le raspberry

import logging
import os
import subprocess
import sys

import gphoto2 as gp

logging.basicConfig(
        format='%(levelname)s: %(name)s: %(message)s', level=logging.WARNING)
callback_obj = gp.check_result(gp.use_python_logging())

def get_camera():
    camera = gp.Camera()
    camera.init()
    return camera

def capture_image_from_dslr():
    camera = get_camera()
    capture_image(camera)
    camera.exit()
    return 0

def capture_image(camera):
    print('Capturing image')
    file_path = camera.capture(gp.GP_CAPTURE_IMAGE)
    print('Camera file path: {0}/{1}'.format(file_path.folder, file_path.name))
    target = os.path.join('/tmp', file_path.name)
    print('Copying image to', target)
    camera_file = camera.file_get(
        file_path.folder, file_path.name, gp.GP_FILE_TYPE_NORMAL)
    camera_file.save(target)
    return 0
  
  if __name__ == "__main__":
    sys.exit(capture_image_from_dslr())

INTERFACE GRAPIQUE AVEC TKINTER : TIME LAPS PAUSE LONGUE

nous allons voir ici comment créer une interface graphique ergonomique avec Tkinter pour lancer des commandes au travers de menus . le programme ci dessous permet de faire une serie de photo en pause longue , il fonctionne avec un ecran tactile et affiche un cadre avec menu dans lequel on peut faire varier un certain nombre de paramètres de prise de vue.

NOTA: il a ete optimisé pour un CANON EOS M50.

les paramètres sont :

  • durée de pause pour chaque photo => reglage par slider de 0 a 180 secondes
  • intervalle entre chaque photo=> reglage par slider de 0 a 100 secondes
  • nombre de photo=> reglage par slider de 0 a 100 photos
  • en haut a droite sensibliité ISO=> reglage par choix dans liste de valeur
  • un bouton bleu en bas a gauche de lancement de séquence de prise de vue , une fois le cycle lancé , un message affiche le statu d’avancement en bas de l’ecran entre les 2 boutons
  • un bouton rouge en bas a gauche pour quitter le programme

programme en fichier txt

a copier coller dans votre editeur python ou a enregistrer directement avec l’extension “.py”

import tkinter as tk
import signal
import os
import subprocess
import time

win = tk.Tk()
win.title(" AStrophoto Pauses Longues")

### WIDGETS ###
canvas1 = tk.Canvas(win, width = 550, height = 320, relief = 'raised')
canvas1.pack()
slider1 = tk.Scale(win, from_=0, to=180, orient='horizontal', resolution=5, tickinterval=60, length=300, label='pause (s)')
canvas1.create_window(170,50, window=slider1)
slider2 = tk.Scale(win, from_=0, to=100, orient='horizontal', resolution=1, tickinterval=25, length=300, label='intervale (s)')
canvas1.create_window(170,130, window=slider2)
slider3 = tk.Scale(win, from_=0, to=100, orient='horizontal', resolution=1, tickinterval=25, length=300, label='nombre')
canvas1.create_window(170,210, window=slider3)
label1 = tk.Label(win, text='ISO')
label1.config(font=('helvetica', 15))
canvas1.create_window(450,24, window=label1)
spinbox1 = tk.Spinbox(win, values=["250","320","400","500","640","800","1000","1250","1600","2000","2500","3200","4000","5000","6400" ],width=4)
spinbox1.config(font=('helvetica', 30))
canvas1.create_window(450,60, window=spinbox1)

### Event Functions ###
def killgphoto2Process():
    p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
    out, err = p.communicate()
    for line in out.splitlines():
        if b'gvfsd-gphoto2' in line:
            pid = int(line.split(None,1)[0])
            os.kill(pid, signal.SIGKILL)
def takepicture():    
    tmpPause = int(slider1.get())
    isovalue = int(spinbox1.get())
    interPause = int(slider2.get())
    nbrPhoto = int(slider3.get())
    tempphoto = (tmpPause + interPause)
    print("def BULB et def ISO")
    subprocess.run(["gphoto2","--set-config","shutterspeed=bulb"])
    time.sleep(2)
    print("Bulb OK")
    subprocess.run(["gphoto2","--set-config","iso="+str(isovalue)])
    time.sleep(2)
    print("ISO OK")
    i=1
    while i <= nbrPhoto :
        label2=tk.Label(win,text='photo '+str(i)+'/'+str(nbrPhoto)+' reste '+ str((nbrPhoto - i)*tempphoto)+ ' secondes', fg='blue',font=('helvetica',14, 'bold'),width=25)
        canvas1.create_window(275,300, window=label2)
        win.update_idletasks()
        print("i=",(i))
        subprocess.run(["gphoto2","--set-config","eosremoterelease=2"])
        time.sleep(tmpPause)
        subprocess.run(["gphoto2","--set-config","eosremoterelease=4"])
        time.sleep(2)
        print("photo",(i))
        time.sleep(interPause)
        i=i+1
def close():
    win.destroy()    # ferme le pgme

takePic = tk.Button (text='LANCER', command=takepicture, bg='blue', fg='white', font=('helvetica',10, 'bold'))
canvas1.create_window(50,300, window=takePic)
exitButton = tk.Button(text='QUITTER', command=close, bg='red', fg='white', font=('helvetica',10, 'bold'))
canvas1.create_window(500,300, window=exitButton)
killgphoto2Process()            
win.mainloop() # Loops forever

pour finir , une petite video de démo/test