Table des matières Python

Source de courant commandée en tension

1. Introduction

Ce document étudie une source de courant commandée par une tension. Une simulation SPICE est effectuée puis le circuit réel est testé.

2. Circuit

Le circuit ci-dessous est extrait de [1]

figureA.svgFigure pleine page

Les tensions d'alimentation des ampli-op sont Vp=+15 V et Vm=0 V (alimentation simple). La tension d'entrée Ve est positive.

Le courant d'émetteur du transistor NPN Q1 est contrôlé par la tension d'entrée :

Si on néglige le courant de base, ce courant est pratiquement égal à celui du collecteur, qui traverse la résistance R2. La tension du nœud 4 (entrée non-inverseuse de A2) est donc :

Cette tension se retrouve sur l'émetteur du transistor PNP Q2. Le courant circulant dans son émetteur est donc :

Si on néglige le courant de base, ce courant se retrouve pratiquement dans le collecteur, si bien que le courant de sortie Is traversant la résistance de charge est :

Cette relation a été obtenue en négligeant le courant de base des transistors devant leur courant d'émetteur. Avec un gain en courant d'environ 100, l'erreur commise est donc de l'ordre de 1 %.

On obtient donc un courant de sortie commandé par la tension d'entrée. La tension d'entrée est positive, donc cette source est à polarité fixe. Pour que la linéarité soit valable lorsque la tension d'entrée s'approche de zéro, il faut que V4 puisse s'approcher de Vp=15 V. Il faut donc que les ampli-op puissent fournir une tension de sortie très proche des tensions d'alimentation (ampli-op "rail to rail"). On utilise pour cela l'ampli-op double TLV2372. Les transistors choisis sont 2N2222 pour Q1 et 2N2907 pour Q2.

On choisit R1=R2=47 kΩ (résistances à 1%) et on choisit R2 en fonction du courant de sortie maximal souhaité.

Par exemple, on peut obtenir un courant de 50 mA pour Ve=5 V avec R3=100 Ω. En supposant que Rc=0 (le pire des cas), la tension collecteur-émetteur de Q2 est Vce=15-5=10 V. Pour le courant considéré, la puissance dissipée dans Q2 est donc de 0.5 watt, ce qui est à peu près la limite supportable par le 2N2907. Pour les plus forts courants, un transistor de puissance devra être utilisé pour Q2.

3. Simulation SPICE

Le fichier suivant définit les modèles pour les deux transistors utilisés et pour l'ampli-op :

Voici la description SPICE du circuit. Une source de tension Vis=0 qui sert à mesurer le courant de sortie est placée en série avec la résistance de charge Rc.

La résistance de charge est de 10 Ω. On effectue un balayage de la tension d'entrée (commande DC) de 0 à 5 volts.

sourceCourant.cir
.INCLUDE modeles.cir
Vp 5 0 +15
Ve 1 0 DC 1
R1 2 0 47K
XA1 1 2 5 0 3 TLV2372
Q1 4 3 2 2n222a
R2 5 4 47K
XA2 4 6 5 0 7 TLV2372
Q2 8 7 6 Q2n2907a
R3 5 6 1K
Rc 8 10 10
Vis 10 0 0
.control
dc Ve 0 5 0.1
print i(Vis) > export-1.txt
.endc
.end
             
from lectureSpicePrint import lectureSpicePrint
from matplotlib.pyplot import *

data = lectureSpicePrint("export-1.txt")
ve = data["v-sweep"]
Is = data["i(vis)"]*1000
figure(figsize=(6,6))
plot(ve,Is)
xlabel("ve (V)")
ylabel("Is (mA)")
grid()
             
figA.svgFigure pleine page

On refait la simulation avec une résistance de charge différente (1 Ω):

sourceCourant.cir
.INCLUDE modeles.cir
Vp 5 0 +15
Ve 1 0 DC 1
R1 2 0 47K
XA1 1 2 5 0 3 TLV2372
Q1 4 3 2 2n222a
R2 5 4 47K
XA2 4 6 5 0 7 TLV2372
Q2 8 7 6 Q2n2907a
R3 5 6 1K
Rc 8 10 1
Vis 10 0 0
.control
dc Ve 0 5 0.1
print i(Vis) > export-2.txt
.endc
.end
             
from lectureSpicePrint import lectureSpicePrint
from matplotlib.pyplot import *

data_2 = lectureSpicePrint("export-2.txt")
ve_2 = data["v-sweep"]
Is_2 = data["i(vis)"]*1000
figure(figsize=(6,6))
plot(ve_2,Is_2)
xlabel("ve (V)")
ylabel("Is (mA)")
grid()
             
figB.svgFigure pleine page

Comme prévu, le courant ne dépend que de la tension de commande et pas de la résistance de charge. Le courant obtenu est toutefois légèrement inférieur à celui donné par la relation (1). Voyons l'écart relatif :

R3 = 1.0e3
Vmax = 5.0
ecart = (Is[Is.size-1]-Vmax/R3*1000)/(Vmax/R3*1000)
             
print(ecart)
--> -0.014424200000000021

L'écart est d'environ 2 %. En pratique, il faudra donc étalonner cette source de courant. Une autre solution est d'utiliser des paires de transistors Darlington de manière à augmenter leur gain en courant.

4. Test du circuit réel

La résistance de charge est Rc=0.998 kΩ (obtenue avec un ohmmètre de précision 0.9 % +1). La commande en tension et la mesure de la tension en sortie (aux bornes de Rc) sont faites avec le boitier LabJack U6.

import u6
import time
import numpy as np

sys = u6.U6()
n = 10
ve_array = np.zeros(n)
vs_array = np.zeros(n)
dve = 5.0/(n-1)
for k in range(n):
    ve = k*dve
    sys.writeRegister(5000,ve) # DAC0
    time.sleep(0.1)
    vs = sys.getAIN(0)
    ve_array[k] = ve
    vs_array[k] = vs
sys.writeRegister(5000,0.0)
sys.close()
Rc = 0.998 #kOhm
is_array = vs_array/Rc
figure(figsize=(6,6))
plot(ve_array,is_array)
xlabel("ve (V)")
ylabel("Is (mA)")
grid()
            
figC.svgFigure pleine page

L'écart avec la formule (1) est bien du même ordre que celui obtenu par la simulation.

L'étalonnage consiste à déterminer la pente (en mA par volt) avec le dernier point :

            
pente = is_array[n-1]/ve_array[n-1]
            

5. Application

La source de courant est utilisée pour tracer la caractéristique d'une diode. Le courant i=Is commandée par la tension Ve traverse la diode et on mesure la tension à ses bornes.

sys = u6.U6()
n = 40
i_array = np.zeros(n)
u_array = np.zeros(n)
dve = 5.0/(n-1)
for k in range(n):
    ve = k*dve
    sys.writeRegister(5000,ve) # DAC0
    time.sleep(0.1)
    u = sys.getAIN(0)
    i_array[k] = ve*pente
    u_array[k] = u
sys.writeRegister(5000,0.0)
sys.close()
figure(figsize=(6,6))
plot(u_array,i_array,".")
xlabel("u (V)")
ylabel("i (mA)")
grid()
            
figD.svgFigure pleine page
Références
[1]  P. Horowitz, W. Hill,  Traité de l'électronique,  (Elektor, 1996)
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.