Controleur de Lumière : Différence entre versions
(→Design du circuit) |
(→Fichiers finaux) |
||
(79 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
{{Projet | {{Projet | ||
− | |status= Prototype | + | |status=Prototype |
− | + | |image=Light.control.soldered.board.jpg | |
+ | |description=Une centrale de phares clignotants pour velo ou velomobile | ||
+ | |license=CC-by-sa-3.0 | ||
+ | |contributeurs=Cedric | ||
+ | |ingrédients=electronique | ||
|name=Contrôleur de lumière | |name=Contrôleur de lumière | ||
− | |||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
− | |||
− | |||
==Résumé== | ==Résumé== | ||
Ligne 16 : | Ligne 13 : | ||
J'en profite pour réaliser une centrale phares/clignotants pour mon vélomobile. | J'en profite pour réaliser une centrale phares/clignotants pour mon vélomobile. | ||
+ | |||
+ | Pour exploiter un peu plus les possibilités du tiny (car sans ça j'aurais put fair tout ça sans microcontroleur), je vais créer des fonctionnalités de type code/phares (en PWM) et clignotants/warnings | ||
==Design du circuit== | ==Design du circuit== | ||
Ligne 25 : | Ligne 24 : | ||
La carte est pourvue d'un régulateur de tension, ainsi, les lumières pourront être alimentés à différentes tensions. | La carte est pourvue d'un régulateur de tension, ainsi, les lumières pourront être alimentés à différentes tensions. | ||
− | D'après le [http://www.fairchildsemi.com/ds/ND/NDS355AN.pdf datasheet] du mosfet (N) , on peut alimenter le circuit jusquà 30V | + | D'après le [http://www.fairchildsemi.com/ds/ND/NDS355AN.pdf datasheet] du mosfet (N) , et du [http://www.ti.com/lit/ds/symlink/lm3480.pdf régulateur] on peut alimenter le circuit jusquà 30V |
[[Fichier:Light.central.44.cad]] | [[Fichier:Light.central.44.cad]] | ||
+ | |||
+ | [[Image:Light.central.traces.name.png|300px]] | ||
+ | [[Image:Light.central.44.interior.holes.png|300px]] | ||
+ | |||
+ | ATTENTION il n'ya pas de diode à l'entrée du régulateur ! si on branche l'alim à l'envers, il brule ! | ||
+ | |||
+ | [[image:Light.central.board.png|500px]] | ||
+ | |||
+ | ===Liste des composants=== | ||
+ | |||
+ | |||
+ | |||
+ | {| border="1" | ||
+ | !identifiant | ||
+ | !composant | ||
+ | !quantité | ||
+ | |- | ||
+ | |D1,D2,D3 | ||
+ | |Leds rouge 1206 cms | ||
+ | |3 | ||
+ | |- | ||
+ | |R1 | ||
+ | | Résistance 1206 cms 10Ko | ||
+ | |1 | ||
+ | |- | ||
+ | |R2,R3,R4 | ||
+ | | Résistance 1206 cms 100 Ohms | ||
+ | |3 | ||
+ | |- | ||
+ | |C1 | ||
+ | | condensateur 1206 cms 1uF | ||
+ | |1 | ||
+ | |- | ||
+ | |IC1 | ||
+ | | ATtiny44SSU | ||
+ | |1 | ||
+ | |- | ||
+ | |IC2 | ||
+ | | régulateur 5V/100mA [http://radiospares-fr.rs-online.com/web/p/regulateurs-de-tension-a-faible-chute-ldo/5045115/ LM3480IM3-5.0] | ||
+ | |1 | ||
+ | |- | ||
+ | |T1,T2,T3 | ||
+ | | Mosfets [http://fr.farnell.com/fairchild-semiconductor/nds355an/n-ch-mosfet-30v-1-7a-super-sot/dp/1835420?Ntt=1835420 N 30V 1.7A ] | ||
+ | |3 | ||
+ | |- | ||
+ | |J1 | ||
+ | | Connecteur ISP 6 broches | ||
+ | |1 | ||
+ | |- | ||
+ | |J2,J3,J4,J5 | ||
+ | | borniers à vis pas de 3.5mm | ||
+ | |4 | ||
+ | |||
+ | |} | ||
+ | |||
+ | ==Fabrication== | ||
+ | |||
+ | Lors de la gravure, comme j'étais incertain de l'horizontalité du plan de travail, j'ai réglé dans fabmodules une profondeur légèrement plus importante que la normale : 0.12mm au lieu de 0.1 | ||
+ | |||
+ | [[Image:Light.control.milled.board.jpg|400px]] | ||
+ | |||
+ | On voit la différence car les inter-pistes sont beaucoup plus creux, alors les pistes et les motifs fins sont plus fragiles : c'est notamment flagrant pour le texte, mais il faudra se méfier lors de la soudure, car les pistes fines pourront avoir tendance à se décoller. | ||
+ | |||
+ | [[Image:Light.control.soldered.board.jpg|400px]] | ||
+ | |||
+ | Bien que je m'améliore à chaque fois, je pense que j'ai encore quelques progrès à faire en soudure ;) | ||
+ | |||
+ | Les borniers à vis, traversants, sont soudés au dos du circuit. | ||
+ | |||
+ | |||
+ | |||
+ | J'ai utilisé le petit code ci-dessous pour tester le circuit : j'ai dut m'y reprendre à plusieurs fois pour corriger toutes les petites erreurs de soudure. | ||
+ | |||
+ | ==Code== | ||
+ | |||
+ | Je vais coder en C, en partant des exemples [http://academy.cba.mit.edu/classes/output_devices/index.html du cours du jour] | ||
+ | |||
+ | ===fonctionnement désiré=== | ||
+ | |||
+ | ====en entrée==== | ||
+ | |||
+ | 3 interrupteurs sont câblés avec le connecteur ISP aux entrées PA4, PA5 et PA6 reglées en pullup | ||
+ | |||
+ | |||
+ | 1 bouton poussoir (PA4) : à chaque relâchement du bouton on change de mode pour les phares : | ||
+ | code > phares > éteint | ||
+ | |||
+ | pendant l'appui, on est en plein phares (pour faire des appels de phares) | ||
+ | |||
+ | |||
+ | 2 interrrupteurs monostables (PA5 et PA6) : les clignotants | ||
+ | |||
+ | si on déclenche un clignotant alors que le bouton des phares est allumé, on passe en warnings. | ||
+ | |||
+ | |||
+ | |||
+ | ====en sortie==== | ||
+ | |||
+ | Les pins PA0 PA1 PA2 sont câblé sur les mosfets | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===Premier test=== | ||
+ | |||
+ | Pour valider le circuit | ||
+ | |||
+ | j'ai fait un code simple qui fait clignoter les sorties | ||
+ | |||
+ | [[file:Hello.blink.3.44.zip]] | ||
+ | |||
+ | J'avais commencé avec une alimentation à découpage de récupération, mais le microcontroleur ne répondait pas bien. Il semble que l'alimentation chutait beaucoup en tension sous la charge, pourtant pas si énorme... | ||
+ | |||
+ | Finalement, j'ai mis une pile 9V et ça fonctionne bien | ||
+ | |||
+ | ===interruptions=== | ||
+ | Les clignotants...clignoteront, donc, ça serai judicieux d'utiliser des interruptions pour détecter les changements des boutons même pendant le delay de clignotement. | ||
+ | |||
+ | quelques ressources à propos des interruptions sur le tiny : | ||
+ | |||
+ | http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=105493 | ||
+ | |||
+ | http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html | ||
+ | |||
+ | |||
+ | dans le [http://www.atmel.com/Images/doc8006.pdf datasheet], on voit que les trois entrées des boutons sont sur le même port d'interruption | ||
+ | |||
+ | |||
+ | J'ai pour l'instant pas implémenté la fonction warning. | ||
+ | |||
+ | Pour mettre en action les interruptions, j'ai renseigné la fonction '''ISR(PCINT0_vect)''' qui est appelée à chaque interruption sur les pins concernés. | ||
+ | |||
+ | Il faut donc écrire dans cette fonction les tests et les actions à effectuer en cas d'actionnement d'un des pins surveillés | ||
+ | |||
+ | <code lang=c> | ||
+ | ISR(PCINT0_vect) // interrupt service routine | ||
+ | { // called when PCINT0 changes state | ||
+ | |||
+ | |||
+ | |||
+ | /////////////BLINKERS | ||
+ | if((!(button_pins & LeftBton_pin)) && blink_mode==0 ){ | ||
+ | blink_mode=1; | ||
+ | } | ||
+ | |||
+ | if((!(button_pins & RightBton_pin)) && blink_mode==0 ){ | ||
+ | blink_mode=2; | ||
+ | } | ||
+ | |||
+ | if((button_pins & RightBton_pin) && blink_mode==2){ | ||
+ | blink_mode=0; | ||
+ | } | ||
+ | |||
+ | if((button_pins & LeftBton_pin) && blink_mode==1){ | ||
+ | blink_mode=0; | ||
+ | } | ||
+ | |||
+ | |||
+ | /////////////////LIGHT | ||
+ | if(!(button_pins & LightBton_pin) && btonLightState==0){ | ||
+ | //LightBton_pin rise up | ||
+ | // | ||
+ | btonLightState=1; | ||
+ | } | ||
+ | if((button_pins & LightBton_pin) && btonLightState==1){ | ||
+ | |||
+ | //LightBton_pin rise down | ||
+ | btonLightState=0; | ||
+ | //change light mode | ||
+ | if(light_mode<2) { | ||
+ | light_mode+=1; | ||
+ | }else{ | ||
+ | light_mode=0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | Ensuite, dans le début du programme, j'ai activé le port d'interruption lié aux pins 0 à 7, soit PCIE0 | ||
+ | |||
+ | Puis réglé le masque de surveillance sur les pins qui m'interressent (pour ne pas que la routine se déclanche lorsque les sorties sont activées | ||
+ | |||
+ | enfin, j'ai activé le mode interrupt : | ||
+ | |||
+ | <code lang=c> | ||
+ | GIMSK |= (1<<PCIE0); // enable PCIE0 interrupt | ||
+ | PCMSK0 = (1<<PCINT4)|(1<<PCINT5)|(1<<PCINT6); // pin change mask: listen to portA 4, 5 and 6 | ||
+ | sei(); //Enable Global Interrupt | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ===pwm=== | ||
+ | |||
+ | pour régler l'intensité des lumières je compte utiliser du PWM | ||
+ | |||
+ | hélas, les sorties que j'ai utilisées n'on pas la fonction hardware | ||
+ | |||
+ | heureusement, on peut fabriquer un pwm en soft : | ||
+ | |||
+ | http://www.kobakant.at/DIY/?p=3393 | ||
+ | |||
+ | La difficulté est de faire du PWM sur les phares sans perdre la temporisation des clignotants | ||
+ | |||
+ | le principe est le suivant : | ||
+ | |||
+ | Blink_delay correspond à la durée de clignotement des clignotants | ||
+ | |||
+ | |||
+ | * on allume les clignotants si besoin | ||
+ | |||
+ | * pendant 10 cycles d'une durée de (Blink_delay/10) on allume (et on étient si besoin) les phares | ||
+ | |||
+ | * on étiend les clignotants | ||
+ | |||
+ | * pendant 10 cycles d'une durée de (Blink_delay/10) on allume (et on étient si besoin) les phares | ||
+ | |||
+ | |||
+ | le code de ce pwm du pauvre est : | ||
+ | |||
+ | <code lang=c> | ||
+ | void poormanPWM(){//for lights | ||
+ | int i; | ||
+ | for (i=0; i<10; i++) { | ||
+ | if(light_mode!=0){ | ||
+ | set(Lights_port,Light_pin); // Turn light on if necessary | ||
+ | }else{ | ||
+ | clear(Lights_port,Light_pin);//else shut it | ||
+ | } | ||
+ | long_delay_ms(blink_delay/20); | ||
+ | if(light_mode==1) clear(Lights_port,Light_pin); // Turn light off half time in low mode | ||
+ | long_delay_ms(blink_delay/20); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | Lensemble du code final est téléchargeable ici : [[Fichier:Light.control.44.c.zip]] | ||
+ | |||
+ | ==Essais== | ||
+ | |||
+ | |||
+ | on programme le tiny en tapant | ||
+ | make -f Light.control.44.make program-usbtiny | ||
+ | |||
+ | |||
+ | ===à vide=== | ||
+ | Comme j'ai mis des leds témoin sur le circuit, j'ai put coder tout le programme sans mettre de charge sur les mosfets. | ||
+ | |||
+ | j'avais également monté un petit tableau de bord de fortune pour câbler des interrupteurs. | ||
+ | |||
+ | Le comportement est complètement conforme à mes attentes : | ||
+ | |||
+ | * chaque appui sur le bouton poussoir des phares change de mode d'éclairage : OFF / LOW / HIGH | ||
+ | |||
+ | * Les clignotants s'allument et s'éteignent sans (pratiquement) interférer avec le phare | ||
+ | |||
+ | |||
+ | |||
+ | ===en charge=== | ||
+ | |||
+ | [[Image:Light.control.working.board.jpg|600px]] | ||
+ | |||
+ | j'ai câblé un petit ruban de led 12V pour tester. Il est un peu sous alimenté, mais ça fera l'affaire pour le moment. | ||
+ | |||
+ | Le mosfet des phares fonctionne bien | ||
+ | |||
+ | Hélas, lorsque j'active un des clignotants, cela ne fonctionne plus. | ||
+ | |||
+ | En testant les mosfets des clignotants, je m'aperçoi qu'ils ne fonctionnent pas. Il doit y avoir un problème de soudure mais je ne suis pas au lab. Je devrais corriger ça plus tard. | ||
+ | |||
+ | ===Diagnostic (temporaire)=== | ||
+ | |||
+ | * les mosfets des clignotants sont à revoir | ||
+ | * peut-être que la charge cumulée des leds indicateurs fait chuter la tension du régulateur qui est un peu limite : il serait bien | ||
+ | ** de changer le régulateur par un plus puissant | ||
+ | ** de mettre des résistances plus fortes sur les leds indicateurs | ||
+ | |||
+ | ou bien mon circuit d'indication perturbe le déclenchement du mosfet, il faudrait alors mettre les leds indicateurs en aval du mosfet (avec des résistances dimensionnées pour la tension d'alimentation) | ||
+ | |||
+ | ==Version 2== | ||
+ | |||
+ | je modifie le circuit pour trois raisons : | ||
+ | |||
+ | * installer un régulateur plus puissant | ||
+ | * élargir les pistes de puissance | ||
+ | * ajouter un capteur de lumière pour piloter les phares | ||
+ | |||
+ | ===régulateur de tension=== | ||
+ | Le nouveau régulateur peut fournir jusqu'à 1 Ampère : http://fr.rs-online.com/web/p/regulateurs-de-tension-a-faible-chute-ldo/7615618/ | ||
+ | [http://docs-europe.electrocomponents.com/webdocs/10fa/0900766b810fa44b.pdf datasheet:LM2940IMP] | ||
+ | |||
+ | Tension d'entrée maxi : 24V | ||
+ | protection contre les cablages inversés | ||
+ | |||
+ | vu la puissance, je peux envisager d'alimenter les lampes avec | ||
+ | |||
+ | Par contre, il apparait qu'il faut un condensateur de lissage d'au moins 22uF : absent du fabinventory | ||
+ | |||
+ | J'ai heureusement trouvé des condensateurs 47uF dans l'atelier... | ||
+ | |||
+ | J'ai du créer un objet dans fabModules : | ||
+ | |||
+ | <code lang="python">class C_5mm(part): | ||
+ | class C_5mm(part): | ||
+ | # | ||
+ | # 5mm capacitor | ||
+ | # | ||
+ | # | ||
+ | def __init__(self,value=''): | ||
+ | self.value = value | ||
+ | self.labels = [] | ||
+ | self.pad = [point(0,0,0)] | ||
+ | #self.shape = rectangle(-.02,.02,-.11,-.019) | ||
+ | self.shape = cube(-.02,.02,-.11,-.019, 0,0) | ||
+ | self.pad.append(point(0,0.05,0)) | ||
+ | self.labels.append(self.text(self.pad[1].x,self.pad[1].y,self.pad[1].z,'-')) | ||
+ | self.shape = add(self.shape,cube(-.02,.02,.019,.11,0,0)) | ||
+ | self.pad.append(point(.0,-.05,0)) | ||
+ | self.labels.append(self.text(self.pad[2].x,self.pad[2].y,self.pad[2].z,'+'))</code> | ||
+ | |||
+ | à noter que j'ai découvert une particularité du code : pour faire des traces qui ne dessinent pas aussi des trous, il faut utiliser des primitives de volume (cube, cylinder...), les formes plates (square,circle) provoquant des trous. | ||
+ | |||
+ | ===Le circuit principal=== | ||
+ | |||
+ | j'ai repris le même schéma en élargissant les pistes de puissance. | ||
+ | |||
+ | J'ai créé une dérivation pour avoir le choix d'alimenter les lampes soit en 5V régulé, soit avec l'alimentation principale (6 à 12V) | ||
+ | |||
+ | [[image:Light.central.v2.44.board.png|300px]][[image:Light.central.v2.44.cut.png|300px]][[image:Light.central.v2.44.traces.png|300px]] | ||
+ | |||
+ | les fichiers sont en 72pixels/mm | ||
+ | |||
+ | *R2,R3,R4 = 100k | ||
+ | |||
+ | ===Le capteur de lumière=== | ||
+ | |||
+ | en alternative au bouton, j'ai produit un détecteur de lumière pour actionner les phares directement quand la lumière ambiante baisse. | ||
+ | |||
+ | [[image:Light.Detector.board.png|100px]] | ||
+ | [[image:Light.Detector.cut.png|100px]] | ||
+ | [[image:Light.Detector.traces.png|100px]] | ||
+ | |||
+ | le capteur est un Optek OP580 (phototransistor) | ||
+ | |||
+ | |||
+ | |||
+ | Work in progress : [[Media:Lumvelo.zip]] | ||
+ | |||
+ | |||
+ | ===Fabrication=== | ||
+ | |||
+ | ====Fraisage==== | ||
+ | |||
+ | Le circuit est réalisé en fraisage avec la Modela MDX20 | ||
+ | |||
+ | ====Soudure des composants==== | ||
+ | |||
+ | [[image:Lumvelo.soude.jpg|600px]] | ||
+ | |||
+ | ====Cablage==== | ||
+ | |||
+ | Le circuit a deux ou trois options de cablage : | ||
+ | * on peut choisir la tension d'alimentation des lumières | ||
+ | * on peut éventuellement cabler le capteur de lumière avec les interupteurs (du code doit être écrit) | ||
+ | |||
+ | [[image:LightControl.wiring.png|600px]] | ||
+ | |||
+ | ===Tests=== | ||
+ | |||
+ | sans charge, ça fonctionne bien | ||
+ | |||
+ | mais lorsqu'on câble des leds derrière les mosfets, ça fait des trucs bizarres | ||
+ | |||
+ | Avec Laurent, j'ai découvert que même sans charge, l'alim perd 1 V quand on actionne les inter de clignotants : ça fait beaucoup alors je check mon code | ||
+ | |||
+ | Je pense que les entrées en pullup fonctionnent bizarrement. | ||
+ | |||
+ | |||
+ | Je vérifie la mise en oeuvre des résistances pullup http://www.micahcarrick.com/avr-tutorial-switch-debounce.html | ||
+ | |||
+ | |||
+ | |||
+ | ===Debuggage=== | ||
+ | |||
+ | Avec l'aide de Laurent, j'ai réussi à isoler le problème : | ||
+ | |||
+ | En voulant configurer mes entrées numériques en "pullup", je les ai configurées en sortie, donc lorsqu'on actionnai un interrupteur, elles tentaient de fournir un maximum de courant (car étant reliées à la masse, elle provoquaient un court circuit). | ||
+ | |||
+ | J'ai donc changé le code : | ||
+ | |||
+ | <code lang=C> | ||
+ | // initialise button pins pullup | ||
+ | // | ||
+ | set(button_port,LeftBton_pin); | ||
+ | set(button_port,RightBton_pin) ; | ||
+ | set(button_port,LightBton_pin); | ||
+ | //initialise inputs | ||
+ | set(Lights_direction,LeftBton_pin); | ||
+ | set(Lights_direction,RightBton_pin); | ||
+ | set(Lights_direction,LightBton_pin) ; | ||
+ | </code> | ||
+ | |||
+ | |||
+ | par | ||
+ | |||
+ | <code lang=C> | ||
+ | // initialise button pins pullup | ||
+ | |||
+ | button_port |= _BV(PA4); | ||
+ | button_port |= _BV(PA5); | ||
+ | button_port |= _BV(PA6); | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Finalement le code fonctionne ! | ||
+ | |||
+ | |||
+ | ===Fichiers finaux=== | ||
+ | |||
+ | Je publie d'hors et déjà les [[media:LightControl.V2.zip|fichiers de fabrication finaux]], avant d'[[Controleur_de_Lumière/Implantation|implanter le circuit]] dans mon vélomobile | ||
+ | |||
+ | [[Catégorie:FabAcademy]] |
Version actuelle en date du 15 octobre 2014 à 14:46
Une centrale de phares clignotants pour velo ou velomobile
Contributeur·ice·s
Statut du projet
Prototype
Statut de la publication
License
CC-by-sa-3.0
Inspiration
Fichiers source
Machines
Matériaux
Lien
Résumé
Le travail de cette semaine à la fabacademy est de construire un circuit actionneur, et de le piloter avec un microcontrolleur.
J'en profite pour réaliser une centrale phares/clignotants pour mon vélomobile.
Pour exploiter un peu plus les possibilités du tiny (car sans ça j'aurais put fair tout ça sans microcontroleur), je vais créer des fonctionnalités de type code/phares (en PWM) et clignotants/warnings
Design du circuit
J'utilise FabModules pour dessiner le circuit : make_cad_png
Il s'agit d'un ATTINY44, piloté par 3 interrupteurs, pour actionner 3 mosfets.
La carte est pourvue d'un régulateur de tension, ainsi, les lumières pourront être alimentés à différentes tensions.
D'après le datasheet du mosfet (N) , et du régulateur on peut alimenter le circuit jusquà 30V
ATTENTION il n'ya pas de diode à l'entrée du régulateur ! si on branche l'alim à l'envers, il brule !
Liste des composants
identifiant | composant | quantité |
---|---|---|
D1,D2,D3 | Leds rouge 1206 cms | 3 |
R1 | Résistance 1206 cms 10Ko | 1 |
R2,R3,R4 | Résistance 1206 cms 100 Ohms | 3 |
C1 | condensateur 1206 cms 1uF | 1 |
IC1 | ATtiny44SSU | 1 |
IC2 | régulateur 5V/100mA LM3480IM3-5.0 | 1 |
T1,T2,T3 | Mosfets N 30V 1.7A | 3 |
J1 | Connecteur ISP 6 broches | 1 |
J2,J3,J4,J5 | borniers à vis pas de 3.5mm | 4 |
Fabrication
Lors de la gravure, comme j'étais incertain de l'horizontalité du plan de travail, j'ai réglé dans fabmodules une profondeur légèrement plus importante que la normale : 0.12mm au lieu de 0.1
On voit la différence car les inter-pistes sont beaucoup plus creux, alors les pistes et les motifs fins sont plus fragiles : c'est notamment flagrant pour le texte, mais il faudra se méfier lors de la soudure, car les pistes fines pourront avoir tendance à se décoller.
Bien que je m'améliore à chaque fois, je pense que j'ai encore quelques progrès à faire en soudure ;)
Les borniers à vis, traversants, sont soudés au dos du circuit.
J'ai utilisé le petit code ci-dessous pour tester le circuit : j'ai dut m'y reprendre à plusieurs fois pour corriger toutes les petites erreurs de soudure.
Code
Je vais coder en C, en partant des exemples du cours du jour
fonctionnement désiré
en entrée
3 interrupteurs sont câblés avec le connecteur ISP aux entrées PA4, PA5 et PA6 reglées en pullup
1 bouton poussoir (PA4) : à chaque relâchement du bouton on change de mode pour les phares :
code > phares > éteint
pendant l'appui, on est en plein phares (pour faire des appels de phares)
2 interrrupteurs monostables (PA5 et PA6) : les clignotants
si on déclenche un clignotant alors que le bouton des phares est allumé, on passe en warnings.
en sortie
Les pins PA0 PA1 PA2 sont câblé sur les mosfets
Premier test
Pour valider le circuit
j'ai fait un code simple qui fait clignoter les sorties
J'avais commencé avec une alimentation à découpage de récupération, mais le microcontroleur ne répondait pas bien. Il semble que l'alimentation chutait beaucoup en tension sous la charge, pourtant pas si énorme...
Finalement, j'ai mis une pile 9V et ça fonctionne bien
interruptions
Les clignotants...clignoteront, donc, ça serai judicieux d'utiliser des interruptions pour détecter les changements des boutons même pendant le delay de clignotement.
quelques ressources à propos des interruptions sur le tiny :
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=105493
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
dans le datasheet, on voit que les trois entrées des boutons sont sur le même port d'interruption
J'ai pour l'instant pas implémenté la fonction warning.
Pour mettre en action les interruptions, j'ai renseigné la fonction ISR(PCINT0_vect) qui est appelée à chaque interruption sur les pins concernés.
Il faut donc écrire dans cette fonction les tests et les actions à effectuer en cas d'actionnement d'un des pins surveillés
ISR(PCINT0_vect) // interrupt service routine
{ // called when PCINT0 changes state
/////////////BLINKERS if((!(button_pins & LeftBton_pin)) && blink_mode==0 ){ blink_mode=1; } if((!(button_pins & RightBton_pin)) && blink_mode==0 ){ blink_mode=2; } if((button_pins & RightBton_pin) && blink_mode==2){ blink_mode=0; } if((button_pins & LeftBton_pin) && blink_mode==1){ blink_mode=0; } /////////////////LIGHT if(!(button_pins & LightBton_pin) && btonLightState==0){ //LightBton_pin rise up // btonLightState=1; } if((button_pins & LightBton_pin) && btonLightState==1){
//LightBton_pin rise down btonLightState=0; //change light mode if(light_mode<2) { light_mode+=1; }else{ light_mode=0; } } return;
}
Ensuite, dans le début du programme, j'ai activé le port d'interruption lié aux pins 0 à 7, soit PCIE0
Puis réglé le masque de surveillance sur les pins qui m'interressent (pour ne pas que la routine se déclanche lorsque les sorties sont activées
enfin, j'ai activé le mode interrupt :
GIMSK |= (1<<PCIE0); // enable PCIE0 interrupt PCMSK0 = (1<<PCINT4)|(1<<PCINT5)|(1<<PCINT6); // pin change mask: listen to portA 4, 5 and 6 sei(); //Enable Global Interrupt
pwm
pour régler l'intensité des lumières je compte utiliser du PWM
hélas, les sorties que j'ai utilisées n'on pas la fonction hardware
heureusement, on peut fabriquer un pwm en soft :
http://www.kobakant.at/DIY/?p=3393
La difficulté est de faire du PWM sur les phares sans perdre la temporisation des clignotants
le principe est le suivant :
Blink_delay correspond à la durée de clignotement des clignotants
- on allume les clignotants si besoin
- pendant 10 cycles d'une durée de (Blink_delay/10) on allume (et on étient si besoin) les phares
- on étiend les clignotants
- pendant 10 cycles d'une durée de (Blink_delay/10) on allume (et on étient si besoin) les phares
le code de ce pwm du pauvre est :
void poormanPWM(){//for lights
int i;
for (i=0; i<10; i++) { if(light_mode!=0){ set(Lights_port,Light_pin); // Turn light on if necessary }else{ clear(Lights_port,Light_pin);//else shut it } long_delay_ms(blink_delay/20); if(light_mode==1) clear(Lights_port,Light_pin); // Turn light off half time in low mode long_delay_ms(blink_delay/20); }
}
Lensemble du code final est téléchargeable ici : Fichier:Light.control.44.c.zip
Essais
on programme le tiny en tapant
make -f Light.control.44.make program-usbtiny
à vide
Comme j'ai mis des leds témoin sur le circuit, j'ai put coder tout le programme sans mettre de charge sur les mosfets.
j'avais également monté un petit tableau de bord de fortune pour câbler des interrupteurs.
Le comportement est complètement conforme à mes attentes :
- chaque appui sur le bouton poussoir des phares change de mode d'éclairage : OFF / LOW / HIGH
- Les clignotants s'allument et s'éteignent sans (pratiquement) interférer avec le phare
en charge
j'ai câblé un petit ruban de led 12V pour tester. Il est un peu sous alimenté, mais ça fera l'affaire pour le moment.
Le mosfet des phares fonctionne bien
Hélas, lorsque j'active un des clignotants, cela ne fonctionne plus.
En testant les mosfets des clignotants, je m'aperçoi qu'ils ne fonctionnent pas. Il doit y avoir un problème de soudure mais je ne suis pas au lab. Je devrais corriger ça plus tard.
Diagnostic (temporaire)
- les mosfets des clignotants sont à revoir
- peut-être que la charge cumulée des leds indicateurs fait chuter la tension du régulateur qui est un peu limite : il serait bien
- de changer le régulateur par un plus puissant
- de mettre des résistances plus fortes sur les leds indicateurs
ou bien mon circuit d'indication perturbe le déclenchement du mosfet, il faudrait alors mettre les leds indicateurs en aval du mosfet (avec des résistances dimensionnées pour la tension d'alimentation)
Version 2
je modifie le circuit pour trois raisons :
- installer un régulateur plus puissant
- élargir les pistes de puissance
- ajouter un capteur de lumière pour piloter les phares
régulateur de tension
Le nouveau régulateur peut fournir jusqu'à 1 Ampère : http://fr.rs-online.com/web/p/regulateurs-de-tension-a-faible-chute-ldo/7615618/ datasheet:LM2940IMP
Tension d'entrée maxi : 24V protection contre les cablages inversés
vu la puissance, je peux envisager d'alimenter les lampes avec
Par contre, il apparait qu'il faut un condensateur de lissage d'au moins 22uF : absent du fabinventory
J'ai heureusement trouvé des condensateurs 47uF dans l'atelier...
J'ai du créer un objet dans fabModules :
class C_5mm(part):
class C_5mm(part):
# # 5mm capacitor # # def __init__(self,value=): self.value = value self.labels = [] self.pad = [point(0,0,0)] #self.shape = rectangle(-.02,.02,-.11,-.019) self.shape = cube(-.02,.02,-.11,-.019, 0,0) self.pad.append(point(0,0.05,0)) self.labels.append(self.text(self.pad[1].x,self.pad[1].y,self.pad[1].z,'-')) self.shape = add(self.shape,cube(-.02,.02,.019,.11,0,0)) self.pad.append(point(.0,-.05,0)) self.labels.append(self.text(self.pad[2].x,self.pad[2].y,self.pad[2].z,'+'))
à noter que j'ai découvert une particularité du code : pour faire des traces qui ne dessinent pas aussi des trous, il faut utiliser des primitives de volume (cube, cylinder...), les formes plates (square,circle) provoquant des trous.
Le circuit principal
j'ai repris le même schéma en élargissant les pistes de puissance.
J'ai créé une dérivation pour avoir le choix d'alimenter les lampes soit en 5V régulé, soit avec l'alimentation principale (6 à 12V)
les fichiers sont en 72pixels/mm
- R2,R3,R4 = 100k
Le capteur de lumière
en alternative au bouton, j'ai produit un détecteur de lumière pour actionner les phares directement quand la lumière ambiante baisse.
le capteur est un Optek OP580 (phototransistor)
Work in progress : Media:Lumvelo.zip
Fabrication
Fraisage
Le circuit est réalisé en fraisage avec la Modela MDX20
Soudure des composants
Cablage
Le circuit a deux ou trois options de cablage :
- on peut choisir la tension d'alimentation des lumières
- on peut éventuellement cabler le capteur de lumière avec les interupteurs (du code doit être écrit)
Tests
sans charge, ça fonctionne bien
mais lorsqu'on câble des leds derrière les mosfets, ça fait des trucs bizarres
Avec Laurent, j'ai découvert que même sans charge, l'alim perd 1 V quand on actionne les inter de clignotants : ça fait beaucoup alors je check mon code
Je pense que les entrées en pullup fonctionnent bizarrement.
Je vérifie la mise en oeuvre des résistances pullup http://www.micahcarrick.com/avr-tutorial-switch-debounce.html
Debuggage
Avec l'aide de Laurent, j'ai réussi à isoler le problème :
En voulant configurer mes entrées numériques en "pullup", je les ai configurées en sortie, donc lorsqu'on actionnai un interrupteur, elles tentaient de fournir un maximum de courant (car étant reliées à la masse, elle provoquaient un court circuit).
J'ai donc changé le code :
// initialise button pins pullup
// set(button_port,LeftBton_pin); set(button_port,RightBton_pin) ; set(button_port,LightBton_pin); //initialise inputs set(Lights_direction,LeftBton_pin); set(Lights_direction,RightBton_pin); set(Lights_direction,LightBton_pin) ;
par
// initialise button pins pullup
button_port |= _BV(PA4); button_port |= _BV(PA5); button_port |= _BV(PA6);
Finalement le code fonctionne !
Fichiers finaux
Je publie d'hors et déjà les fichiers de fabrication finaux, avant d'implanter le circuit dans mon vélomobile