Mot-clé - électronique

Fil des billets - Fil des commentaires

Vendredi, octobre 17 2014

Régulation PID, faire de jolis graphiques 2/2

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 :)

Dimanche, septembre 14 2014

Régulation PID, comment la régler 1/2

Étant donné que je n’ai pas encore tout le matériel nécessaire pour avancer mes autres projets, j’en profite pour approfondir un peu mes connaissances théoriques et vous en fait donc profiter. Mon projet ici est simple : Réguler une température à l’aide d’un microcontrolleur, mais surtout bien comprendre les tenants et aboutissements des différents réglages et algorithmes. L’objectif ici n’est pas tant d’expliquer ce qu’est un PID, ni comment il fonctionne dans le detail, mais plutôt de donner une méthode permettant d’approximer les coefficients du régulateur.

Je profiterais de cette expérience pour faire 2 articles :
– celui-ci concernant le PID a proprement parler
– Un second article concernant ma méthode pour obtenir des courbes « lives » a partir d’un arduino et d’un PC.

Qu’es-ce qu’un PID

Pour simplifier, on parlera dans la suite de régulation de température, vu que ce sera notre application ici. Mais bien entendu, une régulation peut se faire sur tout type de process (vitesse, débit, etc…)

Lorsqu’on veut réguler la température (d’une pièce par exemple), l’idée la plus simple qui nous vient à l’esprit est de faire une régulation tout-ou-rien : on est en dessous d’un premier seuil, on allume la chauffe, on passe au dessus d’un second seuil on coupe la chauffe. Cette façon de procéder, bien que très simple à implémenter n’est pas exempte de défauts. Par exemple, la température ne sera jamais vraiment constante, même si elle l’est « en moyenne ». Selon le process, on peut arriver à fortement dépasser les consignes (dans un sens ou dans l’autre), en fonction de l’inertie du système, ce qui peut s’avérer nuisible selon ce qu’on veut faire. Enfin, la puissance du chauffage oscillera entre 0 et 100%, ce qui engendre une surconsommation non négligeable.

La régulation PID permet de coller « au plus juste » à la consigne, en évitant les dépassement (en fonction du réglage comme on le verra plus loin), et en n’utilisant que la puissance nécessaire à aller à la consigne et à la maintenir. Concrètement, dans PID, on a P pour Proportionnelle, D pour Dérivée, et I pour Intégrale. Si comme moi vous avez tendance à être un peu allergique aux maths, vous commencez déjà à vous sauver, mais en fait c’est moins compliqué que ça n’en a l’air.

Proportionnelle : c’est ni plus ni moins que la différence entre votre consigne et la valeur actuelle, multiplié par un coefficient de proportionnalité (Que vous définissez, cf la suite). Dans la suite, nous l’écrirons Kc.e(t)

Intégrale : A chaque mesure, vous allez avoir une différence avec la consigne (en plus ou en moins). Prenez cette erreur à chaque pas de temps, multipliez la par un (autre) coefficient de proportionnalité, et additionnez le résultat de tous les pas de temps depuis le début, et vous avez la fameuse composante Intégrale. Dans la suite, l’intégrale sera notée de la façon suivante :

I

 

Dérivée : Son rôle est de « freiner » l’augmentation de puissance calculée en fonction de P et de I, de manière à ne pas dépasser la consigne. C’est une façon de prendre en compte la vitesse d’évolution de notre process. Pour le calculer, vous faites erreur actuelle – erreur précédente, multiplié par un troisième coefficient de proportionnalité

La formule globale de notre régulateur PID peut donc s’écrire de la manière suivante (plus d’explications plus bas):

Formule PID, source ControlGuru

Formule PID, source ControlGuru

 

Description du materiel

Le montage utilisé pour ces essais est très simple : un arduino, un bouton 2 positions, 1 capteur de température (DS18B20), un mosfet (IRF540), une résistance 10Ω 5W, et une alimentation 12V. Le mosfet est piloté par une sortie PWM de l’arduino, et gère le courant (puissance) transitant dans la résistance. Cette dernière chauffe donc plus ou moins en fonction du ratio PWM (la tension change) envoyé par l’arduino. Le bouton 2 positions sert à passer d’une première consigne (valeur PWM 5 sur 255) à une seconde (valeur PWM 30 sur 255) Un petit programme python enregistre les valeurs dans un fichier texte sur le pc (via connection série), et j’utilise GnuPlot pour avoir une jolie courbe et pouvoir lire les valeurs des graphiques plus facilement que directement sur l’image. Par la suite, j’ai ameliore mon script python, de maniere a pouvoir saisir une consigne via le port serie, tout en continuant de logguer.

Montage régulation de température

Montage régulation de température. Attention, utiliser une résistance 5W mini !

Méthode de réglage

Je vous présente une méthode « graphique » directement tirée du site Control Guru, appliquée à mon montage de test. Ce site étant en anglais et très dense en informations, j’ai essayé de résumer les points essentiels ici. J’invite ceux qui voudraient approfondir le sujet à consulter ce site qui est une véritable mine d’information sur la régulation.

Définitions

  • PV : Process Variable, cela correspond à la grandeur mesurée que l’on veut influencer (la température dans cet exemple)
  • CO : Controller Output , la sortie de notre contrôleur en %. (Correspond à l’ouverture de la vanne par exemple)
  • Kp : Gain du process
  • Kc : Gain du contrôleur

Introduction

Une fois modélisé notre boucle de contrôle, nous allons pouvoir en déterminer les trois paramètres principaux par expérimentation, mesure et calcul (et oui…)

Les paramètres à déterminer sont :

  • Kp : la Gain du process, ou, dit autrement, le sens et la grandeur de la variation de la sortie
  • Tp : Constante de temps du process, ou la vitesse de variation quand le process a commencé à répondre
  • θp : (Prononcer Thêta P) Temps mort du process, ou le délai écoulé avant que le process commence à réagir
Boucle de contrôle

Boucle de contrôle

Afin de pouvoir déterminer nos trois paramètres, il va nous falloir mesurer la façon dont réagis notre système. La première étape consiste donc à fixer une première valeur de sortie à notre contrôleur (CO) et attendre que la variable de sortie (PV, ici la température) soit bien stabilisée.

Une fois cette dernière stable, nous allons modifier la valeur de sortie du contrôleur (CO), et mesurer le changement obtenu sur la variable de sortie (PV). On logue bien sûr tout ça dans un fichier, avec les pas de temps, de manière à pouvoir également déterminer le temps mort du process (θp) et la vitesse de variation (Tp).

On se sert ensuite de ces mesures pour tracer un joli graphique, qui nous servira à déterminer nos différentes valeurs.

La formule permettant de déterminer notre premier paramètre Kc, qui est à la base du calcul de nos 3 paramètres (cf. formule) est la suivante :

source : controlguru

source : controlguru

pour déterminer Kc, nous devons donc commencer par déterminer différentes variables intermédiaires.

Calcul de Kp

Kp décrit le sens et de combien va évoluer PV, en fonction d’un changement de consigne (CO) Le cacul de Kp est assez simple : Kp=ΔPV/ΔCO ou en d’autre termes Kp = (différence en PV initial et PV final)/(différence entre consigne initiale et finale)

Sur mon prototype, j’ai modifié la consigne initiale (1,96%) pour une nouvelle consigne à 11.76%, voici la courbe obtenue:

Graphique test du système.

Graphique test du système.

En appliquant la formule ci-dessus, on a donc Kp = (79-40)/(11,76-1,96) = 39/9.8 = 3.98°C/%

Détermination de la constante de temps Tp

Tp représente le « en combien de temps » le système va réagir. En partant du même graphique, on va déterminer quand l’état de sortie vaut 63% de δPV, à partir du moment où le système à déjà commencé à réagir (et pas à partir du moment où on a modifié la consigne. Pour ceux qui se demandent d’où sort les 63%, vous trouverez toutes les explications (attention, maths !) dans ce pdf Fichier:Derive63rule.pdf On regarde donc le nombre de secondes écoulées lorsqu’on arrive à 63% de δPV (ici 39*0.63 + 40 = 64.6°C), et le nombre de secondes écoulées au moment où le système commence à réagir (très rapide ici)

Détermination de la constante de temps TP

Détermination de la constante de temps Tp

On obtiens donc Tp = 172 secondes.

Le cas de θp

θp représente le temps mort avant réaction. Dans une boucle de contrôle, il n’est jamais très bon d’avoir du temps mort, et il sera nécessaire d’avoir cette valeur la plus faible possible. Du fait de mon montage de test, le temps mort est ici très réduit. Ceci s’explique facilement par la position du capteur (sur la résistance), et par le faible volume à chauffer (uniquement la résistance. De manière assez intuitive, on imagine très bien que plus le volume à chauffer sera important, plus le temps mort sera long, pour une même puissance de chauffe.

Si on reprend le graphique ci-dessus, on vois que la consigne a été modifié à T1=195s, et j’ai décider de compter le début de la réaction à T2=198s. On a donc θp = T2 – T1 = 198 – 195 = 3s.

Il est intéressant de noter ici que mon échantillonnage étant d’une seconde, la valeur de θp peut être sensiblement erronée, du fait de sa faible durée dans ce cas.

Application à un modèle PID

Formule PID, source ControlGuru

Formule PID, source ControlGuru

Avec:

  • CO = Sortie du contrôleur (Controller Output)
  • CObias = biais du contrôleur, ou valeur nulle.
  • e(T) = Erreur actuelle, définie par SP – PV
  • SP = consigne (Set Point)
  • PV = valeur actuelle du process (Process Value)
  • Kc = Gain du controlleur, un paramètre de réglage
  • Ti = reset time, un paramètre de réglage
  • Td = derivative time, un paramètre de réglage

Calcul du gain et du reset time

Il faut tout d’abord se demander si notre process accepte un dépassement de consigne ou pas, ainsi que la vitesse à laquelle ce process doit réagir.

  • Si on accepte un dépassement, on peut choisir un réglage agressif, et donc un faible temps de réponse (petit Tc). Dans ce cas, Tc est le plus grand de 0.1Tp ou 0.8θp
  • Modéré, le contrôleur produira peu ou pas de dépassement. Dans ce cas, Tc est le plus grand de 1.Tp ou 8.θP
  • Conservateur, le contrôleur ne produira pas de dépassement, mais ira doucement, Tc sera le plus grand de 10.Tp ou 80.θP

Une fois décidé du comportement de notre contrôleur, et calculé Tc, on peut calculer le gain du contrôleur et le reset time grâce à la formule suivante :

source : controlguru

source : controlguru

Pour mon application, je vais choisir un comportement modéré. Tc sera donc la plus grande valeur de 1.Tp ou 8.θP (1×172 ou 8*3=24). On retiendra donc Tc = 172.

J’obtiens donc Kc = (1/3.98)*(172/(3+172)) = 0.25%/°C et Ti = 172

Je peux maintenant calculer mes deux principaux paramètres P et I :
P = Kc = 0.25
I=Kc/Ti. = 0.25/172 = 0.00145
Reste à déterminer D. la formule permettant de déterminer D est Kc.Td, avec Td = (Tp.θP)/(2Tp+θP) = (172*3)/(344+3) = 1.487. D vaut donc 0.25*1.487=0.372
D = 0.372

Mise en application

Reste maintenant à confronter les calculs à la réalité. Voici le code Arduino que j’ai utilisé pour effectuer mes tests :

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;

unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int sampleTime = 1000; //1 sec
double outMin, outMax;
String cmd = String("");
double tfirst = 0;

float printTemperature(DeviceAddress deviceAddress)
{
  sensors.getAddress(insideThermometer, 0);
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(tempC);
  Serial.print(" ");
  Serial.print(Output);
  Serial.print(" ");
  Serial.println(Setpoint);
  return(tempC);
}

void compute()
{
  unsigned long now = millis();
  int timeChange = (now-lastTime);
  if(timeChange>=sampleTime)
    {
      //get the new input value
      Input = getInput();
      //compute all working error variables
      double error = Setpoint - Input;
      ITerm+=(ki * error);
      if(ITerm>outMax) ITerm = outMax;
      else if(ITerm < outMin) ITerm = outMin;
      double dInput = (Input - lastInput);
      
      //compute PID output
      Output = kp * error + ITerm - kd * dInput;
      if(Output > outMax) Output = outMax;
      else if(Output < outMin) Output = outMin;
      
      //remember some variables for next round
      lastInput = Input;
      lastTime = now;
    }
}

void setTunings(double Kp, double Ki, double Kd)
{
  double sampleTimeInSec = ((double)sampleTime)/1000;
  kp = Kp;
  ki = Ki * sampleTimeInSec;
  kd = Kd / sampleTimeInSec;
}

void setSampleTime(int NewSampleTime)
{
  if (NewSampleTime>0)
  {
    double ratio = (double)NewSampleTime / (double)sampleTime;
    
    ki *= ratio;
    kd /= ratio;
    sampleTime = (unsigned long)NewSampleTime;
  }
}

void setOutputLimits(double Min, double Max)
{
  if(Min > Max) return;
  outMin = Min;
  outMax = Max;
  
  if(Output > outMax) Output = outMax;
  else if (Output < outMin) Output = outMin;
  
  if(ITerm>outMax) ITerm = outMax;
  else if(ITerm<outMin) ITerm = outMin;
}

double getInput(void)
{
  sensors.setResolution(insideThermometer, 9);
  sensors.requestTemperatures(); // Send the command to get temperatures
  return printTemperature(insideThermometer);
}

void setup()
{
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  Setpoint = 0; //on fixe 0 de consigne
  double P, I, D;
  P = 0.25;
  I = 0.00145;
  D = 0.372;
  int STime = 1000;
  setTunings(P,I,D);
  setSampleTime(STime);
  setOutputLimits(0, 255);
}

void loop(){
compute();
analogWrite(3,Output);
if (Serial.available() > 0) {
      char SerialInByte;
      SerialInByte = Serial.read();
      
      if(SerialInByte==13){
        Setpoint = cmd.toInt();
        cmd = String("");
      }
      else
      {
        cmd += String(SerialInByte);
      }
  }
}

et voici le résultat :

Test des paramètres PID calculés

Test des paramètres PID calculés

Conclusion :

J’ai utilisé des paramètres « conservateurs » afin d’éviter de dépasser la consigne. On peut voir qu’effectivement la consigne n’est jamais dépassée, au prix d’une montée en charge un peu lente. En partant sur cette bonne base, il est maintenant facile d’affiner si l’on souhaite quelque chose d’un peu plus réactif, il reste de la marge de manœuvre.

Sources :

La régulation étant un vaste domaine, j’ai trouvé beaucoup d’informations pertinentes sur les deux sites suivants. Si vous n’êtes pas anglophobe, et désirez approfondir le sujet, je vous les recommandes chaudement !
ControlGuru
brettbeauregard.com, auteur d’osPID

Dimanche, avril 20 2014

Thermomètre Nixie Steampunk

Fan de ce style depuis pas mal de temps déjà, c’est ma première réalisation concrète. L’idée était de réaliser un (joli) thermomètre d’ambiance, histoire de savoir quelle température il fait dans la pièce. J’avais déjà réalisé un thermomètre à tubes Nixies, mais ce dernier avait deux défauts : les tubes n’étaient pas centrés sur le pcb, et il consommait un peu trop pour avoir envie de le laisser allumé en permanence (et en plus, il n’était pas « habillé »…).

Du coups, la première étape de cette réalisation a été de refaire un pcb complet. Pas simplement déplacer les tubes, j’en ai profité pour alléger le tout, histoire de supprimer les composants qui n’étaient pas nécessaires. En effet, sur la version précédente, j’utilisais un NE555 pour générer les impulsions nécessaires à la haute tension. Désormais cette tâche est réalisée par le microcontrolleur lui-même.

Schéma thermomètre Nixie

Schéma thermomètre Nixie

Quitte a devoir reprogrammer le microcontrolleur pour rajouter la génération de la haute tension, j’en ai profité pour tout ré-écrire en avrc. Ca me permet d’avoir un timing très précis, autant sur la génération du signal HT que sur le multiplexage des tubes. (La fréquence est importante pour la génération de la haute tension car elle joue pour beaucoup dans le rendement). Mon code aurais pu être grandement optimisé si j’avais un peu mieux réfléchi à mes branchements, mais sur ma version, je m’étais trompé sur certaines liaisons (ce qui expliquera les fils visibles sur les photos). Le schéma proposé corrige ces erreurs.

tarthermomètre nixie (AVRC)

 

Thermomètre à tube Nixie Steampunk

Thermomètre à tube Nixie Steampunk

Pour l’habillage, je me suis fait un peu plaisir. Les deux « chapeaux » sont en laiton, que j’ai tourné, moitié façon meca, c’est à dire en utilisant le tour de manière traditionnelle, moitié à main levée à l’aide d’une lime (pour les arrondis notamment). Le reste de l’accastillage est composé de différents tubes de laitons, diamètre 5 et 3mm, que l’on trouve facilement en magasin de modélisme.
Le tube est quand a lui un tube de plexyglass acheté pour l’occasion.

Socle vu de dessous

Socle vu de dessous

Le socle a été tourné dans un beau morceau de chêne, par un ami car je ne disposais pas de tour à bois, et le tour à metal n’est vraiment pas adapté à ce genre d’opérations. Le plot du milieu est assez profond pour que le tube laiton soit bien maintenu, mais ne va pas jusqu’en bas pour pouvoir laisser passer les fils. J’ai repris ensuite le socle tourné pour le fraiser afin de fixer le connecteur d’alimentation, et fait les 4 perçages nécessaires (2 pour les tubes verticaux, un pour le capteur de température, et un pour le connecteur d’alim).

Détail du capteur de température

Détail du capteur de température

Le capteur de température utilisé est un LM35. Pas particulièrement esthétique donc. Pour le masquer, je l’ai donc glissé à l’intérieur d’une douille de 22lr qu’un ami tireur m’a gentiment fourni. Le capteur est fixé à l’intérieur à la colle à chaud.

En fonctionnement

En fonctionnement

Dimanche, janvier 19 2014

DIY – shield PWM

Bon, petit montage pas bien compliqué à la demande d’un client : pouvoir utiliser tous les canaux PWM d’un arduino Uno, avec de la puissance.
Vous l’aurez deviné, un petit mosfet piloté par le PWM et le tour est (presque) joué. On y ajoute une diode de flyback (si on veut pouvoir y connecter par la suite des charges inductives), et des connecteurs, le tour est joué.

Shield PWM Arduino

Shield PWM Arduino

Bien sûr, il ne faut pas oublier l’alimentation de l’arduino (on utilisera un 7805 tout bête pour ça, accompagné d’un condensateur pour le lissage), ainsi qu’une petite diode signalant que le montage est en fonctionnement.
La charge que vous pourrez connecter à ce montage dépendra directement des mosfets choisis : 100v jusqu’à 9A dans mon cas, avec des IRF520. (Bon, en vrai les pistes du PCB ne devraient tenir que jusqu’à 4 ampères environ)
L’intérêt de ce montage, outre le fait de pouvoir piloter des moteurs CC, est de piloter les guirlandes de led RGB. En effet, en utilisant 3 cannaux, vous pilotez chaque composante de votre ruban de led, et la puissance disponible permet d’alimenter des rubans de grande longueur.

 

Shield PWM avec led RGB

Shield PWM avec led RGB

Vendredi, décembre 27 2013

DIY – Générateur de Marx

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

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

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

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

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 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)

Samedi, septembre 14 2013

DIY – BOB le bipède

L’autre jour en surfant, je suis tombé sur ce petit projet sympa : BoB. Un petit robot bipède, avec une bouille tellement mimi que j’étais sûr que mon fiston l’adorerais. Comme en plus j’avais tout ce qu’il fallait sous la main pour en construire un, je me suis lancé :)

Tout d’abord, une petite liste de ce qu’il vous faudra :

  • Les pièces plastiques, imprimées
  • 4 servo-moteurs 9g
  • Un arduino micro, ou équivalent
  • un connecteur de pile 9v, ou mieux, une lipo 7.4v (2s)
  • Un lm7805
  • un capteur de distance à ultrason, de préférence avec 2 modules (pour faire les yeux)
  • quelques vis à plastique (récupérées sur de vieux portables par exemple).

Les pièces plastiques sont téléchargeables ici : http://www.thingiverse.com/thing:43708

Le montage ne pose pas de soucis particulier. Il faut fixer un servo sur chaque pied, et deux autres servos sur la base.

Le montage de la base

Le montage de la base

Pour ceux à qui l’assemblage ne paraîtrait pas logique, vous trouverez un guide d’assemblage détaillé ici : http://www.instructables.com/id/BoB-the-BiPed/

Contrairement à ce qui est indiqué dans cet instructable, en utilisant un arduino micro et une pile 9v (ou une petite lipo), tout rentre dans le boitier, à l’exception d’un interrupteur que j’ai fait ressortir pour pouvoir allumer/éteindre la bête.

Voici une petite présentation de la tête de notre nouvel ami, juste avant de passer à l’alésoir,  afin de faciliter le passage des yeux capteurs ultra-son.

P1020169

Lors de l’assemblage, je vous recommande vivement de noter la correspondance entre les servos et les pins de l’arduino, vous serez amené à les configurer dans le programme, et une erreur empêchera notre ami de se déplacer.

Une fois tout assemblé, il faut centrer les servos, à l’aide d’un petit programme arduino les positionnant à 90°. lorsque les servos sont à 90°, les pieds doivent être à plat, et les jambes bien centrées. Si ce n’est pas le cas, modifiez l’angle du servo jusqu’à tomber au plus juste, et notez la valeur correspondante (vous devrez la modifier dans le programme). Faîtes bien cette manip pour chaque servo.

Exemple de programme de centrage :

#include <Servo.h>
Servo servo;
void setup()
{
servo.attach(9);  //changez cette valeur pour chacun des servos à centrer
}

void loop()
{
servo.write(90);
}

Une fois ceci fait, téléchargez le code source ici : http://letsmakerobots.com/node/35877

Il vous faudra modifier au moins deux partie du code :
- La première partie se situe en en-tête du fichier, et correspond aux pins rattachées à vos servos. Notez que Hip sont les cuisses et Ankle les pieds.
- La seconde se situe en fin de fichier, dans les fonctions NormalWalk et ShortWalk. C’est ici que vous pourrez modifier le centrage de vos servos (selon les relevés que vous aviez fait précédemment), ainsi que les angles max (souvent limités par le plastique qui arrive en butée)

Une fois ceci fait, il ne vous reste plus qu’à compiler/uploader, et à admirer votre petit robot se dandiner sous vos yeux (et moi admirer mon fiston s’émerveiller :))

BoB le bipède

BoB le bipède

Vendredi, mai 17 2013

DIY – Thermomètre à tube Nixie

Ce projet, qui m’aura occupé quelques temps, est parti de trois points :

- Je n’avais pas de thermomètre chez moi, et ma femme et moi n’avons pas tout à fait la même sensibilité à la température, cela permet de donner une valeur objective et d’ajuster en conséquence (soit on met le chauffage, soit l’autre enfile un pull ;) )
- J’avais besoin de tester un circuit de commutation pour tubes Nixie (spoiler : dans le but de réaliser une horloge), mais sur un nombre limité de tube, car en cas d’erreur, c’est très pénible de dessouder le tube et de le ressouder
- J’avais envie de réaliser un montage CMS le plus compact possible, et de tester au passage la mise en oeuvre de CMS taille 0402.

Si si, il y a un composant sur C6. La LED est une 5mm, placée là pour donner l'echelle.

Si si, il y a un composant sur C6. La LED est une 5mm, placée là pour donner l’échelle.

Le montage se divise donc en 4 parties : la mesure de la température, effectuée par un vénérable LM35 (mais le montage permet aussi l’utilisation d’un LM73 plus précis) ; l’élévation de tension pour alimenter les tubes, le contrôle des tubes, et le pilotage de tout ça, réalisé par un Atmega328, version cms évidemment.

Le schéma d'ensemble

Le schéma d’ensemble

La partie mesure de température ne nécessite pas d’explications particulières. A noter simplement que le LM73 fonctionne en I2C, et que dans ce cas, il faut impérativement mettre les résistances de pullup R6 et R7. Dans le cas du lm35, elles ne sont plus nécessaires car ce dernier fonctionne en analogique, la sortie de celui-ci étant à connecter à la broche 4 de l’emplacement du lm73 (A5/SCL sur l’atmega).

La partie élévateur de tension est désormais classique sur mon site, il s’agit de la même que pour mes compteurs geiger, à savoir NE555 + Mosfet + bobine. Un petit condensateur 400v sert à lisser la tension obtenue.

La mise en oeuvre de l’AtMega328 n’a rien de spécifique. Il faut en revanche noter deux connecteurs, un connecteur ISP, et un connecteur permettant de brancher un adaptateur série. Le premier devant servir à charger le bootloader Arduino sur l’Atmega, le second à charger le programme/débugger comme s’il s’agissait d’un simple Arduino. Pour une raison que j’ignore, bien que le bootloader soit correctement chargé, il n’a fonctionné que sur une seule de trois cartes que j’ai assemblé. Après tests, la communication série s’effectue correctement et dans les deux sens, mais impossible de flasher l’atmega par ce biais (si quelqu’un a une idée…). Du coups, la programmation se fait via ISP, et le debug par la connexion série.

La partie la plus intéressante de ce montage est la partie pilotage des tubes nixie. Un des objectifs était de réaliser le montage le plus compact possible, exit donc les drivers type 7441, tout sera fait ici à base de transistors.
Afin de ne pas trop consommer, l’affichage des 2 digits ne se fera pas simultanément, mais l’un après l’autre, de manière très rapide, la persistance rétinienne se chargeant de donner l’impression d’un affichage fixe.
Coté cathode, les transistors sont dans une configuration peu courante : la base est commune à tous les transistors, en permanence à +5v, ce qui permet de n’avoir qu’une seule résistance (mais qui impose de n’utiliser qu’un seul digit à la fois). La commutation se fait en ramenant l’émetteur du transistor voulu à  0v. Dans cette configuration, il faut autant d’entrées/sorties sur le microcontrolleur que de digits, mais en l’occurrence, l’Atmega nous en propose nettement plus que nécessaire dans notre cas.

Le driver coté anode

Le driver coté anode

Coté anode, il aurais été possible également de mettre un simple transistor NPN avec une résistance pour faire le travail. Cependant, la consommation « à vide » aurais été supérieure à la consommation lors de l’affichage sur un tube, ce qui n’est clairement pas le but recherché.
Le montage ci-dessus « coupe » le courant, en limitant les pertes à des valeurs infimes. La résistance R12 et le transistor NPN forment un driver de courant constant, réglé de manière à laisser passer juste le courant nécessaire au déblocage du transistor PNP.

Thermomètre Nixie

Le thermomètre Nixie assemblé

Le circuit complet tiens sur un PCB de 5x5cm double face. J’aurais probablement pu faire encore plus petit, mais ça me semblais déjà un bon début !

Le circuit vu du dessus

Le circuit vu du dessus

Concernant l’assemblage du PCB, rien de spécial à mentionner, celui-ci étant étonnamment plus facile à assembler que ce qu’il pourrais sembler au premier abord, et ce, malgré le fait que j’ai soudé des résistances 0805 sur des emplacements 0603 (donc un peu plus petits que les résistances). Ayant fait plusieurs essais, j’ai testé différentes techniques de soudure, je vous ferais un petit topo là-dessus dans un prochain article. Globalement, si on omet les 2 composants 0402 (taille qui n’était pas impérative du tout, mais pour faire des tests), ce n’est pas vraiment plus compliqué qu’avec du traversant, au contraire même.  Le circuit intégré demande un petit coups de main, mais ça se fais très bien, et très rapidement. Les 0402, pour le coups, sont assez délicat à placer, leur petite taille faisant qu’ils se collent à la pane du fer à souder par capillarité, et leur taille nécessite de bons yeux en plus d’une bonne loupe (idéalement, une bino)

Enfin, pour finir, le code source, qui n’a rien de très spécifique, il se contente de récupérer la valeur du lm35, et décomposer le résultat obtenu en deux digits, les unité et les dizaines.

thermometre

Jeudi, avril 25 2013

Capteur optique de vitesse et sens de rotation (2)

Deuxième partie : de l’idée à la mise en oeuvre.

Passons donc, comme promis, à la construction de ce capteur de vitesse ET sens de rotation.

D’abord, dessiner le patron. Je choisis de faire 3 largeurs de franges sur 24 degrés selon le dessin suivant (Fig 4).

Patron du premier codeur

Fig. 4 : Patron du premier codeur

Les fronts « noirs » seront régulièrement répartis tous les 8° dans le sens trigo, cette répartition régulière pourra être la base de la mesure de vitesse, en se basant sur les fronts montants pour un sens de rotation, descendants pour l’autre sens. La première frange occultante aura 2° de large, la deuxième 4°, et la dernière 6°. Ceci répété 16 fois pour faire le tour. J’aurai donc une roue dentée à 48 créneaux par tour, ce qui suffit bien pour la précision dont j’ai besoin. Le premier prototype sera fait d’une roue dessinée sur l’ordinateur, imprimée sur un film transparent, découpée grâce aux petits ciseaux de couturière piqués à ma charmante épouse, et collée à nouveau sur un bouton de potentiomètre placé sur l’arbre moteur. Résultat nul : imprimante jet d’encre sur film transparent = pas du tout opaque, les variations de signal sont trop faibles. Je l’imprime sur du papier blanc, collé sur film plastique pour rigidifier, puis découpé aux ciseaux : c’est mieux au niveau du signal, mais mes découpes sont imprécises et les différences de largeurs de bandes sont trop irrégulières pour permettre une détection fiable du sens de rotation. C’est en plus très fragile. Néanmoins, le principe est validé : les créneaux obtenus à l’oscillo étant bien identifiables lorsque la fabrication des encoches est correcte (voir photo 5).

codeur-papier

Photo 5 : Codeur « papier »

Je construis un modèle STL, en réduisant un peu la résolution pour faciliter la fabrication (10 séries de 3 encoches sur 360° au lieu de 16)  et l’imprime sur une RepRap… mais le plastique est trop translucide et je ne peux pas augmenter l’épaisseur sinon elle ne passera plus dans la fourche !! De plus la précision de la Reprap est trop limite, et les bords pas nets car les fils de PLA (le plastique utilisé) bavent un peu… les durées différentes sont difficilement identifiables (illustration 6).

Mauvais signal avec la roue en PLA

Illustration 6 : Mauvais signal avec la roue en PLA

Tant pis, je passe à l’imprimante 3D Z-builder (flashage de résine UV par un vidéo projecteur) à laquelle j’ai aussi accès (merci Gi-Nova, et merci Christofer !) et obtiens enfin un modèle suffisamment précis, rigide, opaque… (illustration 7) qui va permettre de mesurer vitesse et sens de rotation de mes moteurs (vitesses variant de -120 à +120 tr/min).

Roue en résine photosensible

Illustration 7 : Roue en résine photosensible

Et voici la roue codeuse sur le système final en cours d’assemblage… (photo 8).

Roue codeuse en place

Photo 8 : Roue codeuse en place

Pour la partie logiciel :

Afin de compter de manière fiable les fronts, j’ai opté pour l’utilisation d’interruptions, une qui compte les fronts montants et enregistre leurs dates, une autre pour les fronts descendants. Sur l’Arduino, le plus simple et fiable que j’ai trouvé est d’utiliser 2 entrées différentes pour cela (et comme entre temps j’ai investi dans un MEGA, cela ne me pose plus de gros soucis ;-) ). Le programme principal calcule alors la largeur (durée) des créneaux par différence de dates, conserve toujours les 3 derniers créneaux, et fait les calculs lorsque le créneau détecté est plus grand que les 2 précédents.

Pour être précis, notons ces durées (délai entre front montant et front descendant) dt1, dt2, dt3 dans l’ordre d’apparition. Nous venons de dire que au moment où nous faisons le calcul de vitesse et de sens dt3 est supérieur à dt1 et dt2. Alors si dt1<dt2, le sens de rotation est direct, mais si dt1>dt2, le sens de rotation est indirect. Dans le sens direct, la fréquence des fronts montants est à peu près régulière et permet de calculer assez précisément la vitesse angulaire de la roue codeuse (nombre de fronts montants comptés, ramené au temps passé depuis le dernier calcul). Dans le sens indirect ce sont les fronts descendants qui sont réguliers.

Voili-voila. Si vous avez besoin d’un capteur de vitesse vous donnant le sens de rotation : Do It Yourself !

Phil.

 

- page 1 de 7