Ce document montre comment utiliser un convertisseur analogique-numérique pour tracer les courbes intensité-tension caractéristiques d'un transistor bipolaire. La partie logicielle, en python, peut être utilisée avec différents convertisseurs.
On s'intéresse à un transistor bipolaire NPN. Le circuit suivant permet d'obtenir ses caractéristiques.
Figure pleine pageLes tensions S0 et S1 sont fournies par deux sorties de conversion numérique-analogique. Un suiveur à amplificateur opérationnel (non représenté) est placé entre chaque sortie et le circuit. Les 4 entrées de conversion analogique-numériques E0,E1,E2,E3 sont branchées comme indiqué sur la figure. On obtient ainsi le courant de base, la tension base-émetteur, le courant de collecteur et la tension collecteur-émetteur :
Les tensions S0 et S1 varient entre 0 et respectivement S0max et S1max. La résistance RB sert à polariser la jonction base-émetteur. Elle doit être choisie en fonction de S0max et du courant ibmax souhaité (typiquement une centaine de micro-ampères). La résistance RC doit être choisie en fonction de S1max et du courant icmax souhaité.
La première courbe à obtenir est ib=f(Vbe), qui dépend de la tension collecteur-émetteur Vce. Lorsque Vce est assez grande (typiquement quelques dizaines de volts), cette courbe ne dépend plus de Vce : c'est la zone de fonctionnement linéaire du transistor. En fixant le courant de base ib (dans la zone linéaire), on obtient une courbe ic=g(Vce). Il s'agit donc d'obtenir plusieurs courbes pour différents courants de base.
Le programme de commande est écrit en python. Il permet d'utiliser différents convertisseurs analogique-numérique.
Il se présente sous la forme d'une classe comportant des fonctions d'entrée-sortie génériques, qu'il faudra implémenter en fonction du convertisseur utilisé.
La classe est dans le fichier CaracteristiqueTransistor.py.
import time import numpy as np from matplotlib.pyplot import * class CaracteristiqueTransistor: def __init__(self,Rb,Rc,S0_max,S1_max): self.Rb = Rb self.Rc = Rc self.S0_max = S0_max self.S1_max = S1_max self.delai = 0.01 def sortie_s0(self,S0): pass def sortie_s1(self,S1): pass def entree_e0(self): return 0.0 def entree_e1(self): return 0.0 def entree_e2(self): return 0.0 def entree_e3(self): return 0.0
La fonction suivante permet d'obtenir le courant de base (en micro-ampères) pour une tension S0 donnée :
def i_base(self,s0): self.sortie_s0(s0) time.sleep(self.delai) e0 = self.entree_e0() e1 = self.entree_e1() ib = (e1-e0)/self.Rb*1e6 return ib
La fonction suivante ajuste la tension S0 pour obtenir un courant de base donné. Elle effectue une recherche de racine avec une tolérance epsilon, en utilisant la méthode de bissection (ou méthode de dichotomie).
def reglage_ib(self,ib,umin,umax,epsilon): u1 = umin u2 = umax u = (u1+u2)/2 y = self.i_base(u)-ib y2 = 1.0 y1 = -1.0 while abs(y) > epsilon: if y1*y < 0: u2 = u y2 = y else: u1 = u y1 = y u = (u1+u2)/2 y = self.i_base(u)-ib return [u,y+ib]
La fonction suivante effectue le tracé de la caractéristique ib=f(Vbe). La tension S1 est réglée à sa valeur maximale de manière à être dans la zone de fonctionnement linéaire. Le nombre de points n0 est fourni en argument.
def base_emetteur(self,n0): delta_S0 = self.S0_max/(n0-1) ib_array = np.zeros(n0) Vbe_array = np.zeros(n0) self.sortie_s1(self.S1_max) for k in range(n0): S0 = k*delta_S0 self.sortie_s0(S0) time.sleep(self.delai) e0 = self.entree_e0() e1 = self.entree_e1() Vbe = e0 ib = (e1-e0)/self.Rb*1e6 ib_array[k] = ib Vbe_array[k] = Vbe xlabel("Vbe (V)") ylabel("ib (muA)") plot(Vbe_array,ib_array)
La fonction suivante trace les courbes ic=f(Vce) pour différentes valeurs du courant de base. Comme le montage ne contrôle pas directement le courant de base, on se contente d'ajuster la tension S0 pour que le courant de base ait la valeur voulue dans la zone de fonctionnement linéaire. La caractéristique obtenue n'est donc à courant de base constant dans la zone de saturation. delta_ib est l'incrément du courant de base, n1 le nombre de points des courbes. Le courant de base est ajusté avec S1=S1max, ce qui assure d'être dans la zone de fonctionnement linéaire.
def collecteur_emetteur(self,delta_ib,n1): ib_max = self.i_base(self.S0_max) ib_max = int(ib_max/10)*10 nb = int(ib_max/delta_ib) Vce_array = np.zeros(n1) ic_array = np.zeros(n1) delta_S1 = self.S1_max/(n1-1) xlabel("Vce (V)") ylabel("ic (mA)") for j in range(nb): ib = j*delta_ib epsilon = 0.01 self.sortie_s1(self.S1_max) [s0,ib]=self.reglage_ib(ib,0.0,self.S0_max,epsilon) print("ib = %f"%ib) for k in range(n1): S1 = k*delta_S1 self.sortie_s1(S1) time.sleep(self.delai) e2 = self.entree_e2() e3 = self.entree_e3() Vce = e2 ic = (e3-e2)/self.Rc*1e3 Vce_array[k] = Vce ic_array[k] = ic plot(Vce_array,ic_array,label="ib = "+str(round(ib))+" muA")
Les boitiers de mesure LabJack peuvent être pilotés avec python, aussi bien sur MS Windows que sur Linux. La classe suivante hérite de la classe CaracteristiqueTransistor et définit les fonctions d'entrée-sortie pour le LabJack U6. Les tensions maximales pour les sorties sont de 5 volts.
from CaracteristiqueTransistor import CaracteristiqueTransistor import u6 class TransistorLabjack(CaracteristiqueTransistor): def __init__(self,Rb,Rc): CaracteristiqueTransistor.__init__(self,Rb,Rc,5.0,5.0) self.u6 = u6.U6() def fermer(self): self.u6.close() def sortie_s0(self,S0): self.u6.writeRegister(5000,S0) def sortie_s1(self,S1): self.u6.writeRegister(5002,S1) def entree_e0(self): return self.u6.getAIN(0) def entree_e1(self): return self.u6.getAIN(1) def entree_e2(self): return self.u6.getAIN(2) def entree_e3(self): return self.u6.getAIN(3)
Le boitier de conversion Eurosmart SysamSP5 comporte deux sorties de convertisseur numérique-analogique, qui délivrent des tensions entre -10 et +10 volts. L'interface pour python est présentée dans CAN Eurosmart : interface pour python..
La classe suivante est dans le fichier caracteristiqueTransistorSP5.py.
from CaracteristiqueTransistor import CaracteristiqueTransistor import pycan.main as pycan class CaracteristiqueTransistorSP5(CaracteristiqueTransistor): def __init__(self,Rb,Rc): CaracteristiqueTransistor.__init__(self,Rb,Rc,10.0,10.0) self.sp5 = pycan.Sysam("SP5") self.sp5.config_entrees([0,1,2,3],[10.0,10.0,10.0,10.0]) self.sp5.activer_lecture([0,1,2,3]) def fermer(self): self.sp5.fermer() def sortie_s0(self,S0): self.sp5.ecrire(1,S0,0,0) def sortie_s1(self,S1): self.sp5.ecrire(0,0,1,S1) def entree_e0(self): x = self.sp5.lire() return x[0] def entree_e1(self): x = self.sp5.lire() return x[1] def entree_e2(self): x = self.sp5.lire() return x[2] def entree_e3(self): x = self.sp5.lire() return x[3]
Le boitier Labjack U6 est utilisé. Les résistances sont RB=47 kΩ et RC=100 Ω.
Le premier transistor étudié est un BC548, transistor de faible puissance pour l'amplification.
from matplotlib.pyplot import * transistor = TransistorLabjack(47000,100) figure(figsize=(10,6)) transistor.base_emetteur(100) axis([0,1.0,-10,100]) title("BC548") grid()figA.pdf
Lorsque la jonction base-émetteur est passante (Vbe>0.6 V), la tension base-émetteur varie très peu (une fraction de volt). Le courant de base
est donc à peu près fixé par la tension S0 lorsque celle-ci est de l'ordre de plusieurs volts.
figure(figsize=(10,6)) transistor.collecteur_emetteur(10,100) axis([0,8,-5,25]) legend(loc="upper right") title("BC548") grid()figB.pdf
La zone de fonctionnement pour Vce<0.25 V présente une forte augmentation du courant de collecteur : c'est la zone de saturation. Pour Vce>0.25 V, on est dans la zone de fonctionnement linéaire. Le courant de base qui légende les courbes est le courant de base dans la zone de fonctionnement linéaire. Dans la zone de saturation, le courant de base n'est pas tout à fait constant lorsque S0 est constante.
Pour balayer des valeurs de tension plus grandes, il faut augmenter la valeur maximale S1max. Cela peut se faire en plaçant un amplificateur de tension non inverseur en sortie du convertisseur (au lieu d'un simple suiveur).
transistor.fermer()
Le second exemple est un 2N2222, transistor utilisé plutôt pour la commutation.
from matplotlib.pyplot import * transistor = TransistorLabjack(47000,100) figure(figsize=(10,6)) transistor.base_emetteur(100) axis([0,1.0,-10,100]) title("2N2222") grid()figC.pdf
figure(figsize=(10,6)) transistor.collecteur_emetteur(10,100) axis([0,8,-5,25]) legend(loc="upper right") title("2N2222") grid()figD.pdf
transistor.fermer()