Intervallomètre pour EOS350

 

Accueil
Astro
AVRastro

NB : Pour l'instant, cette page est en travaux.  Certaines infos n'ont pas été vérifiées car elles sont en cours d'édition.

Il s'agit d'un petit boitier qu'on branche sur la prise télécommande d'un EOS350D pour réaliser automatiquement une série de vues en pose longue :

  • il est autonome car il a sa propre pile, il ne demande aucun fil d'alimentation.
  • la prise télécommande : c'est une minijack stéréo, de 1mm5 qui sert à faire la mise au point et à déclencher la prise de vues.
  • le EOS350D de Canon est un très bon appareil pour l'astronomie, son capteur CMOS de 8Mpixels est très sensible aux faibles lumières et il peut faire des poses longues dans le mode "bulb".

Voici une photo de l'appareil en question :

EOS350D

La prise télécommande a deux fonctions : faire la mise au point et faire la prise de vues. En gros, quand on appuie sur le premier bouton, l'appareil fait la mise au point. Il faut lui laisser un peu de temps pour cela. La prise de vues dans le mode "bulb" se décompose en deux phases : d'abord le relevage du miroir puis la prise de vues. En gros, on appuie une première fois sur le bouton sans relacher, ça relève le miroir mais sans ouvrir l'obturateur. Ca permet de stabiliser l'appareil s'il est monté sur un pied qui vibre. La prise de vue démarre quand on relache le bouton. Il faut appuyer une seconde fois sur le bouton pour arrêter la prise de vues.


On branche TimEOS au port télécommande pour automatiser ces opérations. TimEOS permet de définir plusieurs paramètres :

  • la durée d'une prise de vue en 1/10 de secondes
  • le nombre de vues à la suite
  • définir le délai entre deux vues d'une série, s'il vaut zéro, TimEOS commence tout de suite la vue suivante
  • définir la durée du temps de stabilisation de l'appareil après relevage du miroir, par exemple 2 secondes
  • définir un incrément sur le temps de pose : en %, par exemple avec un incrément de 50%, si la première vue est programmée pour 1s, la deuxième fera 1,5s, la troisième fera 2.2s, la quatrième 3.4s, etc... Ca permet d'essayer plusieurs durées de poses sur le même sujet.
  • définir l'intensité du rétroéclairage afin de ne pas brûler les yeux la nuit.

Conception

TimEOS est composé :

  • d'un afficheur LCD 2 lignes de 8 caractères
  • de 4 boutons poussoirs pour choisir et changer les valeurs : menu suivant, menu précédent, valeur+, valeur-
  • d'une prise minijack stéréo male à brancher dans l'appareil.
  • d'une pile 9v dans un boitier plastique
  • un microcontrôleur

L'étude de ces éléments conduit à définir le nombre des entrées/sorties strictement nécessaires pour mettre le moins cher des microcontrôleurs. Le problème est d'être économe pour ne pas devoir prendre un pentium 64 double coeur.

  • L'afficheur LCD peut fonctionner en mode 4 bits : il ne faut que 8 fils : E, RS, RW, D4-D7, BL (backlight, rétroéclairage). Je ne compte pas l'alimentation 5v et la masse. On envoie deux types d'octets : soit des commandes (effacer l'écran, mettre le curseur à tel endroit...), soit du texte à afficher.
    • D4-D7 est le poids fort du caractère ou de la commande qu'on envoie au LCD. On doit d'abord écrire le poids fort puis le poids faible pour transmettre un octet. C'est à l'initialisation qu'on choisit le mode de fonctionnement : il y a une commande particulière pour ça.
    • RS est le fil qui indique si on envoie une commande (RS=0) ou une donnée (RS=1)
    • RW indique au LCD si on lui envoie des données (RW=0) ou si on lui demande d'en envoyer (RW=1). Ici, on met toujours RW à 0.
    • E est le fil qui indique au LCD quand les données sont valides : il est en permanence à 0, on place une donnée sur RS,RW et D4-D7 puis on met E à 1 pendant 250ns, sans changer les autres fils, et on peut remettre E à zéro.
    • BL est indépendant du LCD. C'est seulement un fil d'alimentation d'une LED verte qui éclaire l'afficheur. On le met à une tension variable pour avoir des intensités variables. Ici, j'ai utilisé une astuce : alimenter ce fil avec un PWM. Il s'agit d'un signal rectangulaire de fréquence fixe et de rapport cyclique variable. L'afficheur s'allume un certain temps et s'éteint le reste du temps, et ce cycle se répète très rapidement : plusieurs milliers de fois par seconde. En faisant varier le rapport cyclique, on fait donc varier l'intensité moyenne d'éclairement. Les PWM sont très facilement réalisés avec un microcontrôleur moderne : après configuration, il suffit d'affecter un registre avec une valeur qui donne le rapport cyclique.
  • Les boutons poussoirs sont reliés à des entrées du contrôleur. Il y a quatre boutons actifs bas à contact fugitif. Je n'ai pas vu l'intérêt de faire un multiplexage, donc chaque bouton est associé à une entrée spécifique.
  • La prise jack a besoin de deux sorties logiques. Je n'ai pas relié ces sorties à l'EOS car les niveaux logiques ne sont pas au même potentiel. J'ai utilisé un circuit CD4066 bien connu pour servir d'intermédiaire. Il s'agit d'un circuit contenant quatre interrupteurs statiques commandés par des niveaux TTL. Vu de l'EOS, c'est comme si on reliait la partie

On arrive donc à 4 entrées, 9 sorties, 1 pwm. De nombreux microcontrôleurs peuvent convenir, mais j'aime beaucoup les microcontroleurs Atmel, dont un particulièrement : l'ATtiny 2313. Il est dimensionné idéalement pour ce projet. Il n'a pas besoin de circuits autour pour fonctionner. Il contient sa propre horloge interne (4MHz suffisamment précise pour ce projet). Il est très facile à programmer. Il contient assez de mémoire pour le programme prévu : 1024 instructions , 128 octets d'eeprom et 128 octets de ram. Il est résistant (je l'ai monté par erreur à l'envers, il a chauffé comme pas permis, mais marchait encore après).

Cliquer sur l'image pour aller sur la doc technique de ce contrôleur. Le résumé de la doc est ici.

vue du ATtiny 2313

Voici le brochage de ce composant. La plupart des pattes ont plusieurs fonctions en option. Par exemple la patte 9 sert d'entrée ou de sortie générale PD5 ou de fonction élaborée OC0B. Ce sont des registres de configuration et les fusibles qui définissent le rôle effectif de chaque patte. Ici, je n'ai mis que les fonctions que j'ai utilisées.

brochage du 2313

Voici l'affectation des pattes :

patte nom direction rôle
2 PD0 sortie mise au point
3 PD1 sortie prise de vue
6 PD2 entrée + pullup touche "moins"
7 PD3 entrée + pullup touche "plus"
8 PD4 entrée + pullup touche "menu moins"
11 PD6 entrée + pullup touche "menu plus"
9 OCOB sortie sortie PWM pour le rétroéclairage (attention, pas plus de 40mA)
12-15 PB0-3 entrée ou sortie DB4-7 données pour le LCD
16 PB4 sortie RW pour le LCD : 1 pour lire, 0 pour écrire dans le LCD
17 PB5 sortie Rs pour le LCD : 0 pour une commande, 1 pour un caractère
18 PB6 sortie E pour le LCD : 1 quand les données sont figées et valides

Certains choix sont arbitraires, d'autres sont obligatoires, par exemple OC0B, il n'y avait guère le choix. Il faut également signaler des contraintes électriques, les sorties du 2313 ne sont pas prévues pour plus de 40mA en continu. Il m'a donc fallu limiter le courant passant dans le rétroéclairage à l'aide d'une petite résistance non représentée sur le schéma plus bas.

J'ai utilisé le timer0 (8 bits) en mode PWM pour le rétroéclairage, et le timer1 (16 bits) en mode CTC (clear on compare match) pour servir de base de temps : son interruption est déclenchée exactement 10 fois par seconde en ajustant la valeur haute du timer (OCR1A).

Schéma électronique

 Voici le schéma réalisé avec Eagle en version libre (il existe une version pour Ubuntu et c'est elle que j'ai employé). Cliquez sur l'imagette pour voir le schéma en entier.

schéma de TimEOS

Pour le principe de fonctionnement, ce n'est pas compliqué, IC1 est le microcontrôleur, il est relié directement à l'afficheur et aux boutons. IC2 est le circuit qui isole le montage de l'EOS.

La prise jack est reliée comme ceci :

brochage jack

Pour faire la mise au point, il suffit de relier 1 à 2. Pour démarrer ou arrêter une pose, il suffit de relier 1 et 3. C'est ce que fait le CD4066.

Réalisation

Je n'ai malheureusement pas de fournisseur pour des circuits imprimés. J'ai fait un montage sur plaquette à trous. Il suffit de placer les composants et de les relier en passant des fils. Ca n'est pas moins fiable et ça permet de mettre au point l'électronique. Enfin... ici, ça a marché du premier coup.

Le mieux est de faire un plan d'implantation très précis pour chaque ensemble du schéma, sur du papier quadrillé avec les composants à leur échelle et des couleurs pour les fils à placer. Il faut avoir le schéma du montage bien en tête pour ne pas commettre d'erreurs ou d'oublis.

Voici ce que ça donne une fois branché et sans boitier. L'image montre le choix du temps de pose : 15 secondes.

image de TimeEOS

L'image suivante montre le menu démarrer la série, il suffit d'appuyer sur le bouton "plus" pour lancer le décompte.

TimeEOS prêt à démarrer

L'image suivante montre l'affichage en cours d'une série : il reste 12 secondes dans la pose actuelle et il reste encore 3 poses à faire. La petite taille de l'afficheur et le remplissage presque complet du contrôleur rendent difficile de mettre plus de textes.

TimeEOS dans une série

Le coût global brute des composants est d'environ 15€. Le contrôleur coûte 2€30, l'afficheur est la pièce la plus chère, environ 8 à 9€ chez Sélectronic ou Gotronic. Evidemment, il faut déjà de l'outillage et du savoir-faire pour le réaliser.

Logiciel

C'est la partie la plus intéressante pour moi. Il m'a fallu trouver des solutions élégantes pour faire un logiciel confortable tenant peu de place. On doit pouvoir changer les valeurs définissant les séries de poses : nombre de poses, durée de la première, augmentation des durées, délai de mise au point, délai de stabilisation, délai entre deux poses, intensité du rétroéclairage. Les limitations sont l'afficheur de 2 lignes de 8 caractères et seulement 4 boutons.

Voici ce que j'ai choisi. TimEOS affiche une "page" par paramètre à définir, on passe d'une page à l'autre avec deux boutons, menusvt et menuprec.  L'une des pages permet de démarrer la série de poses.

Chaque "page" contient deux lignes, la première ligne est le nom du paramètre, par exemple : "Tps pose", la seconde ligne est le nombre d'unités du paramètre, par exemple "10s". Les deux autres boutons permettent de faire varier le paramètre : plus ou moins. Selon le paramètre, l'incrémentation et la décrémentation se font de 1 en 1 ou avec d'autres pas. L'un des problèmes a été de réduire la longueur des libellés à la largeur de l'afficheur soit 8 caractères. D'autre part, il n'y a pas beaucoup de place en mémoire pour des textes. Je les ai presque tous mis en eeprom afin de pouvoir les traduire si besoin sans reprogrammer la mémoire flash.

Voici les différents aspects du logiciel.

Gestion du temps

Le principe de base est qu'il y a une base de temps qui exécute une fonction exactement 10 fois par seconde. Cette fonction a pour rôles :

  • de regarder si le clavier (les boutons) ont été enfoncés ou relachés et d'appeler la fonction de gestion du menu,
  • de faire avancer les poses en cours : décrémenter le temps restant sur la pose courante et le cas échéant de passer à la pose suivante

Gestion du menu

Le principe est : selon la touche qui est enfoncée, on change de menu ou on fait varier le paramètre devant lequel on se trouve. La fonction de menu affiche aussi les textes : libellés et valeurs ou état de TimEOS : nombre de poses restant à faire, durée restante dans la pose courante...

Gestion du clavier

Cette partie doit produire un code représentant la touche enfoncée sur les boutons : un code spécifique pour chaque touche et aussi un code indiquant qu'aucune touche n'a été enfoncée.

Ensuite, il y a un mécanisme (automate à états finis) qui permet de gérer des répétitions de touches. Ainsi, quand on garde le doigt sur un même bouton pendant un certain temps, plusieurs codes sont produits : telle touche enfoncée, aucune touche, telle touche, aucune... Il suffit juste de compter depuis combien de temps la même touche est enfoncée et selon le temps, on génère des codes ou pas. Ca simplifie énormément la fonction de menu qui n'a pas à se soucier de cette gestion.

Ce module peut être facilement adapté à un autre montage.

Gestion de l'afficheur

Cette partie permet d'afficher des textes sur le LCD. Elle gère le mode 4 bits et les signaux de commande (bit banging).

Programme source

J'ai une légère (...) préférence pour les logiciels libres, donc j'ai fait appel à la suite GPL pour avr : avr-gcc également disponible sous forme de paquets pour Ubuntu. Il y a quelques critiques à faire sur certains choix de programmation (la gestion de la constante zéro me semble catastrophique pour les entiers 8 bits) mais globalement le code est très compact et très efficace. J'ai compilé le même logiciel sur avrgcc et sur la version d'essai du compilateur IAR, avec un bien meilleur résultat pour gcc (code 15% plus compact sur 2Ko de code objet), alors qu'il est gratuit et que IAR est payant.

J'ai utilisé quelques outils confortables pour programmer :

  • un template de Makefile fait par Pat Deegan chez http://electrons.psychogenic.com. Il suffit de changer quelques lignes pour s'adapter à un nouveau logiciel.
  • un programmateur d'AVR basé sur la note avr910 de chez Atmel que j'ai réalisé avec les informations trouvées sur ce lien (deustche sprache) : j'ai modifié la partie RS232 de leur schéma en remplaçant les transistors par un MAX232, j'ai enlevé le quartz d'horloge et utilisé l'horloge interne, donc j'ai modifié leur logiciel pour la vitesse d'horloge différente. Auparavant, j'utilisais un programmateur sur port parallèle, basé sur ce lien, mais j'avais souvent des erreurs de programmation dans les gros programmes parce que mon cable parallèle était trop long. Maintenant, je n'en ai plus une seule avec l'AVR910.
  • le logiciel avrdude disponible dans Ubuntu. J'ai juste redéfini une entrée pour mon programmateur puisque les vitesses de communication série sont plus grandes.

Sources en GPL

Je fournis le source sous licence GPL. Vous avez donc obligation de conserver ma signature (nom) dans les fichiers si vous utilisez une partie de ce programme. Ne finassez pas, si vous récupérez des parties de ce programmes, soyez honnête en me citant.

Dans compat.h, j'ai défini un certain nombre de macros pour faciliter le portage entre gcc et iar, et parce que je préfère cette syntaxe, par exemple pour manipuler les bits des registres.

Source main.c
Fichier inclus compat.h
Fichier Makefile pour compiler avec avr-gcc

Commentaires sur les sources

--pas fini--
Mémorisation des paramètres dans l'eeprom

Les valeurs choisies pour les poses et le rétroéclairage peuvent être mémorisées dans l'eeprom afin de retrouver les mêmes au prochain allumage de l'appareil. J'ai regroupé toutes les valeurs dans une structure : struct Configuration qui est écrite dans les premiers octets de l'eeprom. Ces valeurs sont relues au reset pour initialiser les séries. Simplement, la même structure est stockée en ram et c'est elle qui est affichée et mise à jour dans les menus et utilisée par l'automate de gestion des séries. 

Programmation du LCD

Initialisation en mode 4 bits... pas fini

Ecriture de caractères...

Gestion des textes affichés

Les textes sont stockés dans l'eeprom, par groupes de 4 caractères. La fonction WriteTextAdr4 reçoit un code, c'est l'adresse dans l'eeprom des 4 caractères à afficher. Ca a l'intérêt de libérer des octets dans la mémoire flash. Ca permet également de mettre en commun des mots identiques qu'on retrouve dans différentes chaines, tels que "pose".

Configuration des timers

Le timer0 est un 8 bits, il est configuré en mode "phase correct PWM" en mettant les bonnes valeurs dans les deux registres TCCR0. On valide la sortie OCR0B qui est reliée au rétroéclairage du LCD. L'intensité du rétroéclairage est définie par OCR0B : 255 pour le plein éclairage, 0 pour l'extinction complète.

Le timer1 est un 16 bits. Il est configuré en mode "clear timer on compare match", ce qui signifie qu'il revient à zéro lorsque le compte TCNT1A devient égal à la limite placée dans le registre OCR1A. On peut changer cette limite, ça permet de définir très précisément la fréquence des retours à zéro. J'ai ensuite activé la routine d'interruption associée au retours à zéro : TIMER1_COMPA, ce qui permet d'appeler une fonction à chaque retour à zéro.

Routine d'interruption

Cette fonction est appelée exactement 10 fois par seconde -- le nombre 10 peut être modifié en changeant la constante TICKS. Sa valeur initiale correspond à la fréquence de l'horloge (1 MHz), au taux de prédivision (prescaler global) choisi (/4) et au taux de division du timer1 (/2). Les paramètres choisis font qu'il faut mettre 24999 dans OCR1A pour avoir exactement 10 interruptions par seconde. Il faut noter que l'horloge interne du 2313 n'est pas aussi précise qu'un quartz : elle dérive dans le temps selon la température et elle est différente d'un composant à l'autre de quelques %. Pour cette raison, j'ai prévu un menu pour changer la valeur de OCR1A (menu calibration) si on constate une trop grande différence avec un chronomètre. Attention, comme tout est lié à ce timer, il faut restreindre OCR1A à une plage raisonnable sinon on risque de perdre définitivement la main : trop ou pas assez d'interruptions par seconde.

La routine d'interruption appelle la fonction d'avancement des séries de poses et la fonction de lecture du clavier.

Avancement des séries de poses

Le principe est d'utiliser un automate à état : la variable globale EtatAutomate indique ce qui est en cours : une pose, la mise au point... La variable RestantCpt indique combien de secondes il reste à attendre dans cet état. La fonction de gestion de l'automate est appelée une seule fois par seconde. Elle décrémente le compteur RestantCpt et l'arrivée à zéro entraîne le passage à l'action suivante.

Par exemple, quand on fait la mise au point, on décrémente RestantCpt à chaque appel. Quand il arrive à zéro, on passe dans le mode relevage du miroir et on réaffecte RestantCpt avec le nombre de secondes qu'il faut attendre pour le miroir. Evidemment, quand l'attente est nulle, on passe au mode suivant.

Gestion du clavier

Le principe est de regarder les entrées du 2313. Si l'un des fils est à zéro, on prend note de cette touche. Ensuite, si la même touche était déjà enfoncée, on regarde depuis combien de ticks. Selon le nombre de ticks, on affecte la variable globale Touche. Par exemple, au bout de 2 ticks, on met le code NONE, puis à 20 ticks, on met le code de la touche et à 21 ticks, on remet NONE... ainsi de suite pour simuler une répétition.

Menu

La fonction de menu commence par afficher le titre du menu et la valeur qu'il permet de modifier. Ensuite elle attend un code clavier indiquant une touche enfoncée. Selon la touche, elle change de menu ou modifie la valeur courante, ou encore lance la série de pose.

Compilation et programmation des mémoires flash et eeprom

Le programme compilé avec IAR-AVR remplit quasiment entièrement la mémoire flash et l'eeprom. Gcc est plus économe. Les deux compilateurs mettent en commun de nombreuses parties de code, notamment dans les switchs de la fonction menu. Le programme est donc compilé en moins de 1000 instructions ce qui est remarquable car le source est long. On voit les limites de la programmation manuelle en assembleur : un humain peut améliorer de petites sections du programme mais pas autant de lignes.

La programmation des deux mémoires ne pose aucun problème avec AVR911 et le makefile.

Bilan

L'utilisateur du boitier, un fana d'astronomie, en est très content. Ce boitier est autonome, économique et fonctionnel. Il ne rajoute pas de fil dans les pattes et est très fiable.


Accueil | Astro | AVRastro

La dernière mise à jour de ce site date du 14/10/2007. © Pierre Nerzic 2007.