Bon, j’espère que mon précédent billet vous aura permis de comprendre un peu comment fonctionnait la programmation avr.Il reste néanmoins encore de nombreux points qui pourraient êtres abordés, je voulais vous en présenter encore au moins 2 : les timers et les interruptions. Une fois ces deux points maîtrisés, vous serez capable déjà pas mal de petites choses avec vos microcontrolleurs.

Aujourd’hui : Les timers

Comme son nom peut vous laisser le deviner, un timer sert à comptabiliser le temps écoulé. Son principal intéret réside dans le fait que son exécution se déroule en parallèle du programme principal. Votre timer ne sera donc pas affecté par le nombre de d’instructions de votre programme.
Il est bien sur possible pour le programme principal d’interroger le timer, mais il est également possible de configurer le timer pour renvoyer une valeur directement sur une pin matérielle.
Avant d’aller plus loin sur la mise en place d’un timer, il nous faut aborder la notion de pré-scaller. En effet, si notre timer fonctionnait uniquement à la vitesse de l’horloge, nous serions assez rapidement embêté : à 1MHz, par exemple, un signal de 1mS correspondrait à 1000 cycles d’horloge, et pour un timer 8 bit tel que celui de notre ATTiny85, correspondrait à plus de 3 débordements de valeur. Autant dire que ce n’est pas très pratique.
C’est là qu’intervient le prescaler : il permet de faire fonctionner le timer à un sous-multiple de la fréquence d’origine, en divisant la fréquence par 8, 64, 256, 1024. Bien sur, en utilisant le préscaler, on diminue la résolution, il faut donc l’utiliser à bon escient.

Voyons maintenant ça en pratique : faire clignoter une led, mais sans utiliser les fonctions _delay_ms. La led est connectée sur le port PB1 (pin 6 de l’Attiny85). On veut faire changer l’état de notre Led dix fois par seconde. A 1MHz, il faudrait compter jusqu’à…. 100000, ce qui n’est pas directement possible avec notre registre 8 bits. Nous allons donc utiliser le prescaler, en divisant l’horloge par 1024 : 100000/1024 = 97.65, donc ça rentre.

# include <avr/io.h>
int main ( void )
{
DDRB |= (1 << PORTB1) ; //On configure PB1 en tant que sortie
//Todo : Configuration du timer avec prescaler de 1024
    for(;;)
    [
      if()//On vérifie si le timer a atteint un dixieme de seconde
      {
       PORTB ^= (1 << 0) ;//On inverse l'état de la led
       //on réinitialise le timer
       }
    }
}
TCCR0B
Clksrc

La datasheet nous indique que les bits permettant de régler le timer sont les bits CS00 à CS02, le tableau suivant nous expliquant les valeurs à donner en fonction de la configuration voulue.

Dans notre cas, nous voulons un prescaler de 1/64, il faut donc passer les bits CS00 et CS01 à 1, ce qui nous donne :

#include <avr/io.h>
int main ( void )
{
DDRB |= (1 << PORTB1) ; //On configure PB1 en tant que sortie
TCCR0B |= (1 << CS00) | (1<<CS02); //Set up timer1 with prescaler 1/1024
    for(;;)
    [
      if()//On vérifie si le timer a atteint un dixieme de seconde
      {
       PORTB ^= (1 << 0) ;//On inverse l'état de la led
       //on réinitialise le timer
       }
    }
}

Il ne nous reste plus qu’à lire notre timer, pour savoir s’il dépasse 97, et, si c’est le cas, inverser l’état de notre led, et réinitialiser le timer. Ces opérations se font via le Time Counter Register, à savoit TCNT0 sur notre ATTiny85 (il peut y en avoir plus d’un selon votre microcontrolleur). Selon la datasheet toujours, ce registre est accessible en lecture/écriture, ce qui nous permettra la lecture, mais aussi sa remise à Zero. Voici ce que nous donne le code :

#include <avr/io.h>

int main ( void )
{
DDRB |= (1 << PORTB1) ; //On configure PB1 en tant que sortie
TCCR0B |= (1 << CS00) | (1<<CS01); //Set up timer1 with prescaler 1/1024
    for(;;)
    [
      if(TCNT0>=97)//On vérifie si le timer a atteint un dixieme de seconde
      {
       PORTB ^= (1 << 0) ;//On inverse l'état de la led
       TCNT0 = 0;//on réinitialise le timer
       }
    }
}




A bientôt pour la dernière session : les interruptions.

–edit–
L’article a été mis à jour suite à des erreurs qui m’avaient été signalé. N’hésitez pas si vous en trouvez d’autres 😉

Ok, trois articles sur le sujet ça peut paraître court, mais ça constitue déjà une bonne introduction, qui devrais vous permettre d’envisager la suite par vous-même. Nous allons aujourd’hui nous pencher sur un autre élément essentiel de la programmation avr :

Les interruptions

Imaginez que vous êtes en train de souder un circuit quand tout à coups la sonnette de votre porte d’entrée résonne. Vous pouvez arrêter ce que vous étiez en train de faire (mais rien ne vous y oblige), aller répondre, et revenir à vos soudures. Et c’est exactement comme ça que se passe une interruption dans le monde informatique, ici représentée par la sonnette.

Les interruptions peuvent être matérielles (changement d’état d’une broche, timer qui arrive à une certaine valeur), ou logicielles, et le nombre d’interruption disponibles dépend du modèle d’avr.
Les différentes interruptions disponibles sur votre microcontrolleur sont visibles sur la table des vecteurs d’interruptions de la datasheet (ici, je suis toujours sur l’Attiny85)

Vecteurs d’interruption

Lorsqu’une interruption se produit, l’avr stoppe ce qu’il était en train de faire pour exécuter  la fonction que vous souhaitiez rattacher à cette interruption. Pour ce faire, il utilise une table des vecteurs d’interruption, positionnée au début de sa mémoire flash, afin de faire la correspondance Interruption <–> fonction.

Afin d’utiliser une interruption sur notre avr, nous avons besoin de faire 3 choses :

  • Positionner le bit Enable Interrupt (en général avec la fonction sei(), set global interrupt, mais peut aussi être positionné à la main)
  • Positionner les bits de chaque interruption.
  • et enfin remplir la condition de l’interruption.

Comme d’habitude, nous allons voir ensemble un petit exemple. Ce programme servira à compter les impulsions reçues sur la pin 5 de l’Attiny85. Lorsqu’il arrivera à 200 ou plus, il allumera une led sur la pin 6. Les impulsions pourront être crées avec un bouton poussoir (attention au debounce) ou un générateur de signal.

#include <avr/io.h>
#include <avr/interrupt.h>

//	   ___
//  PB5  *|+  |*  VCC
//  PB3  *|   |*  PB2
//  PB4  *|   |*  PB1   --> sortie led
//  GND  *|___|*  PB0   --> entrée surveillée
//

volatile int count = 0; //compte des interrupts


int main(void)
{
	//configuration de la pin de sortie
	//configuration des interruptions
		//Positionnement du Global Interrupt MaSK register
		//Positionnement du Pin Change Mask Register
		//mise en place des interrupts (set global interrupts)

	for(;;)
	{
		
		
		//Si on a eu 200 impulsions ou plus
		{
			//on alume la led
		}
		//sinon
		{
			//On éteind la led
		}
	}
}


ISR (PCINT0_vect) { //vecteur d'interruption
	// detection de front montant
	{  
		//on ajoute 1 au décompte
	}
	//detection de front descendant
	{
		//ici on ne fais rien, juste pour l'exemple...
	}
} 

Voilà, déjà, on peut remarquer en fin de code la façon dont est définie le vecteur d’interruption. Un autre détail à remarquer est la déclaration de ma variable count. Cette variable étant utilisée à la fois par mon programme principal et par ma fonction, il est impératif de la déclarer en volatil, sous peine de ne jamais la voir s’incrémenter.
Voyons voir maintenant comment déclarer nos interruptions (encore une fois, les valeurs des bits sont tirés de la datasheet, cf page 53, chapitre 9.3.2) :

#include <avr/io.h>
#include <avr/interrupt.h>

//	   ___
//  PB5  *|+  |*  VCC
//  PB3  *|   |*  PB2
//  PB4  *|   |*  PB1   --> sortie led
//  GND  *|___|*  PB0   --> entrée surveillée
//

volatile int count = 0; //compte des interrupts


int main(void)
{
	//configuration de la pin de sortie
	//configuration des interruptions
		//Positionnement du Global Interrupt MaSK register
                GIMSK |= (1 << PCIE); 	//Enable pin change interrupt for PORTB 
		    		        //GIMSK = General Interrupt Mask Register
				        //PCIE = Pin Change Interrupt Enable
		//Positionnement du Pin Change Mask Register
                PCMSK = (1 << PB0);  	//Enable pin change interrupt for PB0 (pcint0)
		  		        //PCMSK = Pin Change Mask Register
		//mise en place des interrupts (set global interrupts)
                sei();

	for(;;)
	{
		
		
		//Si on a eu 200 impulsions ou plus
		{
			//on alume la led
		}
		//sinon
		{
			//On éteind la led
		}
	}
}


ISR (PCINT0_vect) { //vecteur d'interruption
	// detection de front montant
	{  
		//on ajoute 1 au décompte
	}
	//detection de front descendant
	{
		//ici on ne fais rien, juste pour l'exemple...
	}
} 

Quelques petites explications complémentaires s’imposent ici. J’ai décidé de dédier une pin de mon Attiny85 à la surveillance du signal d’entrée, j’ai donc utilisé les Pin Change Interrupt. Mais si j’avais voulu utiliser ma broche pour d’autres choses en parallèle, j’aurais du utiliser les External Interrupt Request (donc positionner le bit INT0 au lieu de PCIE). Il faut également noter que par défaut, une interruption ne peut en interrompre une autre (comprendre : les interruptions sont désactivées le temps du traitement du vecteur d’interruption actuel). Il est cependant possible (mais pas franchement recommandé) de les réactiver en réutilisant sei() à l’intérieur de la déclaration du vecteur d’interruption. De la même manière, si vous souhaitez qu’une portion de votre code ne soit interrompue sous aucun prétexte, vous pouvez utiliser la fonction cei().
Voici maintenant le code complet :

#include <avr/io.h>
#include <avr/interrupt.h>

//	   ___
//  PB5  *|+  |*  VCC
//  PB3  *|   |*  PB2
//  PB4  *|   |*  PB1 
//  GND  *|___|*  PB0   --> entrée surveillée
//

volatile int count = 0; //compte des interrupts


int main(void)
{
	//configuration de la pin de sortie
	DDRB |= (1 << PORTB1); 	//on configure PB1 en tant que sortie
				//DDRB = Port B Data Direction Register

	//configuration des interruptions
	GIMSK |= (1 << PCIE); 	//Enable pin change interrupt for PORTB 
				//GIMSK = General Interrupt Mask Register
				//PCIE = Pin Change Interrupt Enable

	PCMSK = (1 << PB0);  	//Enable pin change interrupt for PB0 (pcint0)
				//PCMSK = Pin Change Mask Register

	sei(); //mise en place des interrupts (set global interrupts)

	for(;;)
	{
		
		
		if(count>=200) //Si on a eu 200 impulsions ou plus
		{
			PORTB |= (1 << PB1);
		}
		else
		{
			PORTB &= ~(1<<PB1);
		}
	}
}


ISR (PCINT0_vect) { //vecteur d'interruption
	if (PINB & (1<<PB0)) // detection de front montant
	{  
		count = count++;
	}
	else //detection de front descendant
	{
		//ici on ne fais rien, juste pour l'exemple...
	}
} 

Bon, passons sur les modifications d’état de la led, déjà abordées auparavant. Il est ici intéressant de noter comment se fait la détection d’un front montant ou descendant : à la suite d’un changement d’état, on lit l’état de la pin PB0, si elle est à l’état haut c’était un front montant, sinon, un front descendant.
Voilà, c’était le dernier article de cette série, qui sera suivi très bientôt d’une application concrète 🙂

Dans la série montage à toujours avoir sous la main, je voudrais le régulateur de tension PWM !
Concrètement, ce montage permet de régler l’intensité lumineuse d’une ampoule ou d’une led, ou encore de régler la vitesse de rotation d’un moteur CC, en jouant sur la largeur des impulsions. Concrètement, la tension appliquée aux bornes de la charge ne change pas, mais on la laisse passer plus ou moins longtemps. Principal avantage, le rendement. Par exemple, si la charge que vous souhaitez piloter consomme beaucoup de courant, une régulation classique dissipera beaucoup de chaleur, ce qui ne sera pas le cas avec ce type de montage. Quelques explications.

modulation PWM

Prenons une tension d’entrée (Vin) de 5v. Si la durée de la pulsation Ton est de 10ms, et Toff est de 10ms, alors la tension équivalente de sortie sera de Vin*(Ton/(Ton+Toff)), en l’occurrence 5*10/(10+10) =  2.5V. Comme je le disais au dessus, je parle bien de tension équivalente, car si vous mesurez la sortie avec un oscilloscope, vous verriez des créneaux 0-5v tels que présentés dans le dessin ci-dessus.
Maintenant qu’on a vu le fonctionnement, voyons le montage à proprement parlé :

Régulateur PWM

Le coeur du montage est un NE555, qui génère des impulsions avec un rapport cyclique (rapport cyclique = Ton/Ton+Toff) variable. L’inconvénient de ce montage est que la fréquence varie légèrement lorsque l’on change le rapport cyclique. Ce n’est pas gênant pour contrôler l’intensité  d’une led ou la vitesse d’un moteur, mais si c’est pour faire des mesures d’efficacité par exemple, il faut en tenir compte.

La diode 1N4004 permet de brancher une charge inductive (moteur CC), en filtrant les retours de tensions. Le modèle de la diode peut être à adapter en fonction de la puissance moteur.

Le montage est prévu à la base pour une charge fonctionnant en 12v, avec une tension d’alimentation inférieure à 20 volts. Il est cependant tout à fait possible  d’utiliser des charges de 24v, avec des tensions d’alimentations supérieures (max 37v), en prenant soin de mettre une résistance bobinée de 220 ohms en R5, afin d’éviter que le LM317 n’ai trop de chaleur à dissiper (ceci dit, il n’alimente que le NE555, donc la consommation est assez réduite). Dans le cas standard, cette résistance est inutile.

Voici le résultat une fois monté sur un joli PCB :

Le résultat final

Bon, si je me suis embêté à vous pondre une série d’articles sur la programmation AVR, c’est que j’avais une petite idée derrière la tête. En l’occurrence, j’avais besoin de pouvoir couper une alimentation embarquée dans un avion RC, bien sûr à distance.
L’idée était donc de réaliser un petit périphérique qui se connecte comme un servo-moteur standard de modélisme, mais qui active un relais en fonction de la valeur.

Déjà, il est important de savoir à quoi ressemble les signaux transmis par le récepteur RC aux servos :

Credit : http://nononux.free.fr

Bon, il s’agit d’une sorte de PWM, mais avec un champs très limité car allant de 5 à 10% de la valeur. Dans mon cas, je ne suis intéressé que par 2 cas : On ou Off. Je décide donc de couper à 50%, de manière à pouvoir utiliser le manche des gaz en guise d’interrupteur : de 0 à 50% je suis Off, de 50% à 100% je suis On.
A partir de là, il y a plusieurs façons de voir les choses : il est possible de régler ça en analogique pur, mais j’avais peur que ce soit trop sensible aux éventuelles perturbations. (Et dans mon cas, je préférerais que ce ne soit pas sensible 😉 ). Je suis donc partis sur la solution numérique pour traiter les impulsions.
Comme c’est pour embarquer dans un avion RC, il ne faut pas que ce soit lourd, donc j’ai choisi le micro-controlleur le plus petit possible, à savoir l’AtTiny85, que vous devez bien connaître désormais (voir ici, ici et ici), et qui plus est dans sa version CMS.

Le sch

Comme vous pouvez le constater sur le schéma ci-dessus, la partie électronique est réduite au strict minimum : Un régulateur de tension, pour fournir le 5v nécessaire à tout l’appareillage (servos, récepteur, etc…) dans le cas où l’on ne dispose pas de BEC (par exemple s’il n’y a pas de moteur). L’AtTiny85 dans sa configuration la plus simple (oscillateur interne), un mosfet pour piloter le relais, et le relais en lui même, petit relais 5v, capable de couper 175W quand même.
Le circuit a été réalisé sur un PCB de 0.8mm d’épaisseur, de manière, là encore à gagner du poids.

Vous l’aurez donc compris, dans ce montage, c’est le code qui fait tout le travail :

#include <avr/io.h>
#include <avr/interrupt.h>

//	   ___
//  PB5  *|+  |*  VCC
//  PB3  *|   |*  PB2
//  PB4  *|   |*  PB1   --> declenchement relais
//  GND  *|___|*  PB0   --> entrée PWM
//

volatile int count = 0; //le rapport cyclique
volatile int toff = 0;  //durée du signal à 0
volatile int ton = 0;	//durée du signal haut

int main(void)
{
	//configuration de la pin de sortie
	DDRB |= (1 << PORTB1); 	//on configure PB1 en tant que sortie
				//DDRB = Port B Data Direction Register

	//configuration du timer1 (Ton)
	TCCR0B |= (1 << CS00) | (1<<CS02); 	//Set up timer1 with prescaler 1/1024

	//configuration des interruptions
	GIMSK |= (1 << PCIE); 	//Enable pin change interrupt for PORTB 
				//GIMSK = General Interrupt Mask Register
				//PCIE = Pin Change Interrupt Enable

	PCMSK = (1 << PB0);  	//Enable pin change interrupt for PB0 (pcint0)
				//PCMSK = Pin Change Mask Register

	sei(); //mise en place des interrupts (set global interrupts)

	for(;;)
	{

		if(count>=7.5) //Si le rapport cyclique est > à 7 (Ton ~1.5ms)
		{
			PORTB |= (1 << PB1);
		}
		else
		{
			PORTB &= ~(1<<PB1);
		}
	}
}

ISR (PCINT0_vect) { //vecteur d'interruption
	if (PINB & (1<<PB0)) // detection de front montant
	{  

		toff = TCNT0; 	//Enregistrement de la valeur du timer Toff
		TCNT0 = 0;	//Réinitialisation du timer
	}
	else //detection de front descendant
	{
		ton = TCNT0;	//Enregistrement de la valeur du timer Ton
		TCNT0 = 0;	//Réinitialisation du timer
		if(toff)	//si on a déjà une valeur pour Toff
		{
			count = (ton*100L)/(ton+toff); //Le rapport cyclique = ton/(Ton+toff)
		}		
	}
}
Voilà, il ne reste donc plus qu’à assembler tout ça, et à tester :

Le montage avec une led pour tester.

La chaîne complète, avec le récepteur

Et histoire de vérifier que tout fonctionne, une petite vidéo :

Voilà, un nouvel article prochainement pour vous faire voir l’utilisation réelle du bidule 😉
Ps : c’est un kit que vous retrouverez sur la boutique

Le premier test m’avais bien plu, et j’avais trouvé l’opération amusante. Vu les quantités que j’avais fait la dernière fois, mes savonnettes sont passées assez vite. J’ai donc décidé de remettre ça, mais cette fois “pour de vrai”, avec des ingrédients sympa, en plus grosse quantité, et au passage, en impliquant Madame 😉

Premièrement, la recette

Lors de ma précédente tentative, je n’avais utilisé que de l’huile d’olive, et la première huile essentielle qui me tombais sous la main, à savoir du clou de girofle. Bon, ça marchait bien, ça allais bien pour se laver les mains, mais c’était quand même pas le savon le plus appétissant que je connaisse…
Cette fois-ci, on va s’ouvrir un peu plus l’appétit avec du savon à l’huile de coco et à la vanille.

Les ingrédients

Voici la liste des courses :
200g d’huile de coco (plus du beurre en fait, mais ça s’appelle huile quand même)
400g d’huile d’olive
85g de soude caustique
200ml d’eau

Première étape, peser les ingrédients

La soude

Comme le nom de l’étape le laisse deviner, on pèse chacun des ingrédients dans des récipients séparés. Pour la soude, j’ai préféré bricoler un récipient en papier plutôt que d’utiliser de la vaisselle de cuisine ou un récipient en plastique dont la tenue à la soude n’était pas garantie.

L’huile de coco

Bon, alors l’huile de coco, ça a deux caractéristiques : Ca ressemble à du saindoux, mais ça sent sacrément bon ! (a tel point que ça donne envie de la goûter tel quel)

Seconde étape, mélanger

Alors là, pas question de faire n’importe quoi, la soude est un produit dangereux. Blouse, lunettes (de chimie) obligatoires (gants vivement conseillés au passage).
Il faut tout d’abord dissoudre les cristaux de soude dans l’eau. La réaction est exothermique, et peut dégager des fumées, il est donc recommandé de faire ça sur le balcon. Donc, dans le saladier, verser l’eau, puis, petit à petit (cuillère à cuillère), verser les cristaux de soude dans l’eau, et remuant (avec un autre instrument que celui qui vous sert à prendre les cristaux de soude!). Je le rappelle, pour ceux qui sont pas habitués, pas d’eau dans la soude, toujours la soude dans l’eau, sinon il y a risque de projections.

Une fois cette étape réalisée, il faut mélanger les corps gras à la soude, de la même manière, en procédant petit à petit au début, puis plus franchement.

Vu comme ça c’est pas appétissant, mais ça sent bon !

Après avoir un peu touillé à la cuillère, je vous conseille de passer au mixer, car il va falloir mélanger longtemps…
Il faut donc mélanger jusqu’à la trace, qui prend entre 15 et 30 min en fonction en la température entre autre. Pour pas tuer votre mixer, je vous conseille de faire ça par tranche de 5 min, avec des poses pour le laisser refroidir entre chaque.
Au bout d’un moment, le mélange commence à épaissir, et le filet qui coule du mixer laisse une marque en surface. C’est la “trace”.

La trace

A ce moment là, vous pouvez ajouter les huiles essentielles (de vanille donc, dans mon cas).

Troisième étape, le moulage et le séchage

Bon, là, faites pas comme moi, et prévoyez suffisammentde moules pour vos savons ! J’avais prévu de jolis moules à madeleines, mais une fois ceux-ci remplis, il me restait encore les 3/4 de la préparation ! Résultat des courses, j’ai mis le reste dans un bac de glace, pour les découper en tranches de 2cm d’épaisseur une fois durcis.

Les savons moulés

Là encore, l’odeur est très appétissante, combinée à la forme de madeleine, on en mangerais 🙂
Au bout de 2/3 jours, il faut les démouler. Il est possible de les entourer de film alimentaire pour qu’ils ne blanchissent pas.

Reste maintenant la partie la plus difficile : attendre ! J’avais testé mes précédents savons au bout d’un mois, et ils étaient encore un peu irritants. Au bout de 2 mois en revanche, ils étaient parfaits ! Je pense donc ne pas utiliser ceux-là avant le mois de Juillet, mais promis, je vous ferais un retour à ce moment là !

C’est pas encore l’heure des bonnes résolutions, mais je renoue ici avec une de mes passion premières, un peu délaissée ces derniers temps : la haute tension.
Le montage auquel je me suis attaqué aujourd’hui est assez simple dans son fonctionnement, il s’agit d’un générateur de Marx, qui permet de multiplier une tension. L’avantage de ce montage, est qu’outre sa simplicité, la tension de sortie est directement proportionnelle au nombre d’étages mis en jeux (aux pertes près).

Générateur de Marx

Le concept consiste à charger X condensateurs en parallèles, et les décharger en série. Pour arriver à un pareil résultat, on va utiliser des éclateurs. En effet, tant que la tension  aux bornes du condensateur ne dépasse pas une certaine tension, rien ne se passe, les condensateurs se chargent tranquillement, et la tension à leurs bornes augmente peu à peu.

Charge

Mais lorsque cette tension est atteinte, un arc électrique se produit sur l’éclateur, qui deviens ainsi conducteur.

Décharge. En bleu ciel, les arcs électriques

(oui, désolé pour les couleurs un peu flashy, ça pique les yeux, je sais)
Pour que ça fonctionne (bien), il y a tout de même quelques paramètres importants à respecter. Déjà, il faut que la tension d’alimentation soit suffisamment élevée pour pouvoir produire un arc électrique, sinon les éclateurs ne fonctionneront pas. Ensuite, les résistances de charges. J’ai un peu galéré pour trouver des résistances correctes pour ce montage. Au début, j’étais partis avec des résistances couches carbone (les classiques), mais rapidement les arcs sont passés par le côté de la résistance, détruisant celles-ci. J’ai ensuite voulu utiliser des résistances de puissances en céramique. Mauvaise idée : elles ont été détruites en totalité sur un seul shoot. Je suspecte plus la déflagration d’avoir endommagé l’intérieur que la chauffe proprement dite car elles étaient sensées tenir plus que les couches carbone, ce qui n’aura pas été le cas ici. Finalement, j’ai utilisé des résistances bobinées de puissances, et après quelques dizaines de minutes de fonctionnement, tout à l’air en ordre de marche. Dernier point, la distance entre les éclateurs est relativement importante, c’est d’elle que dépendra la “tension de claquage”

Mon générateur de Marx

Comme on peut le voir sur la photo, mon générateur est constitué de 6 étages, ce qui multiplie donc par 6 la tension d’entrée… En théorie. En effet, mes éclateurs étant difficiles à régler, ma tension de claquage est assez loin du maximum débité par mon alimentation. Au final, je dois arriver à une tension de 10Kv par condensateur, soit 60Kv en sortie.
Les éclateurs sont de simples fils de cuivre recourbés, passés au papier de verre pour enlever l’émail.

Le générateur en action. Le père Noël fait 12cm

Petit détail pour ceux qui serais tentés par l’expérience, et qu’il est difficile de rendre sur une photo : C’est extrêmement bruyant !! (genre mitraillette dans le salon)

Ceux qui me connaissent bien vous le diront, je suis un gourmand :p C’est pourquoi quand Greg a proposé d’organiser un atelier chocolat au sein du log, j’ai saisi l’opportunité 🙂
L’objectif de l’atelier : nous apprendre à travailler le chocolat, et réaliser nos propres oeufs en chocolat, et autres “bonbons” fourrés. De mon côté, j’avais déjà assisté à un premier atelier la semaine précédente, pendant lequel j’en avais profité pour faire des sucettes au chocolat en forme de moustaches, fourrées à la ganache chartreuse. Cette fois-ci, je me suis donc concentré sur la réalisation d’un “gros” oeuf 🙂
Pour les gourmands qui voudraient s’y essayer, voici un petit récapitulatif de ce qu’il faut (si j’ai bien tout retenu ;)), et de la façon de procéder.

Matériel nécessaire :

  • Une grande casserole (pour le bain marie)
  • Un petit bol en inox (cul-de-poule)
  • Un thermomètre (pas “obligatoire”, mais pour débuter, c’est vraiment plus facile )
  • Un pinceau
  • Un moule demi-oeuf.
  • Une spatule métallique
  • Pistoles de chocolat (pour moi, c’était du chocolat au lait origine Ghana 40,5%)
  • Une bombe d’azote (réfrigérant rapide)

Contrairement à ce qu’on pourrais croire, le moule à œuf n’est pas en silicone, ou autre matériau souple, mais en polycarbonate bien rigide. En effet, le chocolat en refroidissant va se rétracter, et le demi-oeuf se démoulera tout seul.

Première étape : faire fondre le chocolat, au bain marie, en surveillant la température : il faut monter à 40-45° pour le chocolat au lait. Avec un thermomètre c’est facile, sans, ça correspond à un peu moins du seuil de douleur (précis comme indication, n’es-ce pas ;)). Attention à ne pas faire tomber d’eau dans le chocolat lors de cette étape (ni des suivantes), ce qui ferais coaguler ce dernier.

Ensuite, il va falloir tempérer le chocolat. Cette étape est nécessaire à la bonne cristallisation de votre chocolat, et vous permettra d’avoir un joli aspect brillant, exempt de traces blanches. Une fois votre chocolat à température (40-45°C), sortez le du bain marie et ajoutez un peu moins d’un tiers de pistoles à température ambiante (20%  de pistoles). Mélangez jusqu’à que tous les pistoles aient fondus. (S”ils disparaissent trop rapidement, rajoutez en un peu)

A l’aide du pinceau, appliquez généreusement du chocolat sur votre moule, en n’hésitant pas à déborder, et en ne laissant aucun trou ou zone transparente. Cette étape assurera un beau fini extérieur et l’absence de bulles en surface. Laissez prendre légèrement, et versez du chocolat fondu (hauteur d’une phalange) dans votre oeuf. Répartissez de manière homogène et laissez reposer un peu. Répétez l’opération encore une fois ou deux, puis videz l’excédent dans le cul-de-poule. Raclez les bords avec une spatule métallique. Mettez au frais.

Au bout de quelques minutes, retirez votre oeuf du frigidaire, et laissez le finir de cristalliser dans un coin assez frais (genre bord de fenêtre à l’ombre). Lorsque vous verrez un petit espace entre le moule et le bord de votre oeuf, il est prêt à être démoulé. Placez vous au dessus d’une surface dure (genre table), mettez la main sur le moule et renversez. S’il tombe tout seul, votre main le retiendra, sinon, tapotez légèrement le moule dur la table (en laissant la main dessous, hein !). S’il ne tombe toujours pas, n’insistez pas, laissez le prendre encore un peu. Attention, ne mettez pas les doigts sur la surface de l’œuf, vous y laisseriez des traces. Prenez le par l’intérieur.

Voilà, c’est démoulé, vous avez un premier demi-oeuf. Vous pouvez répéter l’opération pour avoir l’autre moitié. Faite refondre votre chocolat, et re-tempérez le avant car il a pris pendant ce temps.

Une fois vos deux moitiés d’œuf démoulées, refaite fondre un peu de chocolat et retempérez. Avec le pinceau, appliquez du chocolat sur le bord intérieur de l’œuf, en débordant sur la tranche. Répétez sur l’autre moitié, et assemblez. Vous pouvez maintenant vous servir de la bombe d’azote pour accélérer la prise sur la jonction.

Atelier chocolat

Atelier chocolat

Mon neuneuf à moi :)

Mon neuneuf à moi 🙂

ps : pas beaucoup de photos de “pendant”, désolé, mais le chocolat, ça en met vraiment de partout 😉

Voilà, ça y est, mon tour est posé sur sa dalle, je peux enfin l’utiliser. Pour maximiser sa précision, il est vivement recommandé de le mettre de niveau. Pour se faire, point de niveau de maçonnerie, il faut utiliser un niveau de précision, précision de l’ordre de 0,01mm/m.

Sauf que c’est pas complètement donné, surtout pour un équipement qui servira 2 fois dans l’année maximum. En y réfléchissant un peu, il est possible d’obtenir une bonne précision avec un niveau laser. Alors d’accord, un niveau laser, c’est pas non plus donné (pour un correct j’entends), mais au moins ça peut servir pour tous les autres travaux, et c’est facile d’en trouver en prêt chez les copains.

L’idée, c’est de se servir d’un miroir (ou de plusieurs) comme d’amplificateurs d’erreurs. Un petit schéma étant plus parlant qu’un long discours, voici la procédure que j’ai suivi :

niveau_laser

Mesure de précision avec un niveau laser

Il faut partir du principe que le faisceau est parfaitement vertical (normalement vrai pour un niveau de bonne facture, et dans tous les cas, ça se vérifie facilement). Le faisceau sort du niveau avec un angle, de manière à tracer une ligne verticale sur le mur d’en face. Il se reflète sur le miroir qui est posé sur la surface à régler. Si la surface n’est pas parfaitement de niveau, le faisceau réfléchi aura un décalage, et une seconde ligne apparaîtra sur le mur d’en face. Quand les deux lignes superposées sont confondues, c’est que l’on est de niveau… pour une direction. Reste ensuite à faire de même pour l’autre direction, et revérifier que tout n’a pas bougé.

Et niveau précision du coups ? Et bien, le faisceau fait environ 1mm de large, la précision escomptée est donc de 1mm/2h, h étant la distance entre l’origine du faisceau et l’endroit le plus éloigné où vous pouvez voir les 2 faisceaux. Dans mon cas, j’étais à 3m, ce qui me donne une précision de l’ordre de 0,1mm/m. Pas aussi bon qu’un niveau de mécanicien, mais définitivement meilleur qu’un niveau de maçon. Pour améliorer encore la chose, il aurais suffi de mettre un second miroir, pour augmenter “virtuellement” la distance.

Mais j’ai fait ça en pleine journée, et le faisceau devenais difficile à lire à cause de la luminosité. Je m’en contenterais pour le moment !

Merci à Fred pour le coups de main et le laser !

Ce qui est bien quand on commence à être bien outillé, c’est qu’au lieu d’acheter les outils qui manquent, on peut se les fabriquer.
Je fais pas mal de fonderie en ce moment, et je dois donc réaliser les modèles en bois. Pour bien faire, il faut ajouter un peu de dépouille, de façon à bien démouler le modèle du sable. Mais faire quelque chose de régulier à la main, c’est loin d’être évident. L’idéal c’est une ponceuse avec un plateau inclinable, permettant de mettre l’angle de dépouille souhaité, et surtout de garder le même tout du long.C’est en voyant passer le lapidaire d’un amis que j’ai eu l’idée de m’en faire un. Après tout, ça correspondait exactement à mon besoin.

Read on »

La dernière fois, je vous ai présenté une méthode essentiellement graphique, permettant une bonne approximation des paramètres PID de votre régulateur. Encore faut-il savoir comment tracer les graphiques, c’est ce que je me propose de vous expliquer dans cet article. Il est bien sûr évident que cette méthode peut être utilisée pour tracer des graphiques à partir de tout type de données, du moment que les données arrivent via un port série.
La première étape va consister à récupérer les données du port série sur un PC. Comme souvent, il existe plusieurs façon de faire, je vous présenterais celle que j’ai utilisé ici : un petit script python.

import serial
import sys

serialport = serial.Serial("/dev/ttyACM0", 9600, timeout=1)
line = []

while True:
    for c in serialport.read():
        line.append(c)
        if c == '\n':
            for s in line:
                f=open('myfile','a')
                sys.stdout.write(s)
                f.write(s)
                f.close
            line = []
            break

serialport.close()

Ce petit script prend les caractères arrivant sur le port série, jusqu’au caractère marquant la fin de ligne, puis écrit la ligne dans un fichier. Ca peut éventuellement suffire pour tracer un graphique… Mais dans ce cas précis, on veut pouvoir également envoyer une consigne au régulateur, la modifier afin de suivre la réaction de ce dernier. Problème : comment envoyer des données sans perturber la lecture des données et ne pas sauter de mesure ?
Là encore, il y a plusieurs méthodes possibles, certaines plus complexes que d’autres. Celle que j’ai choisi permet de garder un programme simple, mais ne fonctionnera que sous linux. Ceux sous un autre système chercheront du côté du multithreading…

import serial
import sys
import select

serialport = serial.Serial("/dev/ttyACM0", 9600, timeout=1)
line = []

while True:
        while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
          ligne = sys.stdin.readline()
          if ligne:
            print(ligne)
            serialport.write(ligne+'\r\n')
          else: # an empty line means stdin has been closed
            print('eof')
            exit(0)
        else:
            for c in serialport.read():
                    line.append(c)
                    if c == '\n':
                        for s in line:
                                f=open('myfile','a')
                                sys.stdout.write(s)
                                f.write(s)
                                f.close
                                line = []
                    break

serialport.close()




Ah oui, j’ouvre et ferme le fichier a chaque écriture, de manière à pouvoir accéder aux données pendant l’exécution du programme. Ca permet de visualiser l’évolution du graphique en temps réel.
Les données sont envoyées par le microcontrolleur sous la forme . Je n’ai pas de mesure de temps, chaque échantillon étant pris à un intervalle d’une seconde, il suffit de compter les échantillons pour connaître le temps écoulé.

Passons maintenant au graphique lui-même. Pour cela, j’utilise le logiciel Gnuplot, outil très puissant de tracé de courbes dont nous n’utiliseront ici qu’une infime quantité de ses possibilités. Lorsque vous lancez gnuplot en ligne de commande, vous vous retrouvez avec un shell dans lequel vous pourrez lancer vos commandes gnuplot.

plot 'myfile' using 1 smooth bezier title 'temperature', 
'myfile' using 2  with line title 'CO', 
'myfile' using 3 with line title 'Setpoint'
 plot 'myfile' using 1 

Indique que l’on va tracer une courbe correspondant aux données de la première colonne du fichier

smooth bezier

Indique que l’on veut lisser les données. Il n’est pas toujours intéressant de lisser les données, par exemple, ici la colonne 3 correspondant à la consigne n’est pas lissée, ce qui permet de visualiser le moment exact du changement de consigne. Par contre, dans le cas des valeurs mesurées, cela permet de s’affranchir du bruit sur les mesures.

title 'temperature'

Légende de la courbe. Pratique dès qu’il y a plus d’une courbe.

Par défaut, gnuplot va afficher le résultat à l’écran. Pour pouvoir enregistrer le résultat dans un fichier il faut taper les instructions suivantes :

set terminal "png"
set output "monfichier.png"
replot

Nota : avec la commande replot (ou avec le bouton replot de la gui), vous pouvez rafraîchir les données affichées, de manière à visualiser en continu vos données…
Il y a certainement plein d’amélioration possibles à ma méthode, mais je vous la présente car elle a le mérite d’être simple et rapide à mettre en oeuvre, tout en fournissant de bons résultats