#import necessary libraries
import matplotlib.pyplot as plt
import numpy as np
import math
from scipy.optimize import curve_fit
Metingen & constanten
# Measurements:
R = 9962.9 #waarde gebruikte weerstand in Ohm
#Dit is ongeveer gelijk aan 1% van de interne weerstand van de Voltmeter.
#De weerstand had als label 10kohm, een meting met multimeter leverde deze waarde
q = -1.602*10**-19 #elementaire lading in Coulomb
T = 12+273 #temperatuur van diode tijdens experiment in Kelvin
n = 2 #idealiteits factor, voor de door ons gebruikte halfgeleider gelijk aan 2
#gemeten data Ve is de voltspanning, en Vr is de gemeten spanning over de weerstand.
#Beide spanningen gemeten in Volt
Ve = np.array([0.01,0.02, 0.013,0.22,0.31,0.53,0.71,1.31,1.66,2.72,3.04,4.24,5.44,6,6.52,
0.07,0.09,0.13,0.19,0.26,0.33,0.39,0.45,0.49,0.53
])
Vr = np.array([0.006*10**-3,0.01*10**-3,0.308*10**-3,2.187*10**-3, 11.334*10**-3,114.015*10**-3,0.2572,0.8040,1.137,2.1715,2.4756,
3.657,4.8403,5.4026,5.9201, 0.077*10**-3, 0.148*10**-3,0.355*10**-3,1.604*10**-3, 5.113*10**-3, 16.116*10**-3,
35.429*10**-3,67.542*10**-3,91.558*10**-3,121.50*10**-3
])
Outliers & data management
#In de arrays met metingen staan de metingen met verschillende onzekerheden door elkaar heen.
#Om de arrays op te delen in twee arrays moeten de metingen met dezelfde onzekerheid achter elkaar staan.
#onderstaande code verwijderd een sectie van beide arrays en plaatst dezelfde sectie achter aan de array
#zodat de arrays ge-sliced kunnen worden op een manier zodat
#alle datapunten met dezelfde meetonzekerheid in hetzelfde resulterende array zitten.
begin = 6 #begin en eind punt van verplaatste sectie
end = 15
plt.scatter(Ve,Vr) #zie laatste comment van deze cell.
Vrinj = Vr[begin:end] #selecteer gekozen sectie en verwijder het, plaats het vervolgens weer achteraan de array.
Vr = np.delete(Vr,np.s_[begin:end])
Vr = np.append(Vr,Vrinj)
Veinj = Ve[begin:end] #herhaal voor andere array met metingen.
Ve = np.delete(Ve,np.s_[begin:end])
Ve = np.append(Ve,Veinj)
plt.yscale('log')
plt.scatter(Ve,Vr) #deze scatter plot is om na te gaan of alle datapunten nog op dezelfde positie liggen,
#Te zien is dat alle data punten over elkaar liggen. Dit is de bedoeling.
#Er zijn geen datapunten verschoven tijdens de herindeling van de arrays.
plt.show()
#We hebben besloten de derde meting te verwijderen, dit was een duidelijke outlier, veroorzaakt door een foute aflezing van de meet apparatuur.
#We konden hiervoor geen gebruik maken van het chauvents criterium omdat er slechts 1 meting van Vr is per Ve en er dus geen gausische verdeling is.
Ve = np.delete(Ve,2)
Vr = np.delete(Vr,2)
#De metingen moeten opgedeeld worden in twee delen omdat vanaf datapunt 15 de onzekerheid in Vr veranderd.
#Het display van de multimeter gaat op dat moment automatisch over van mV naar dV.
#De arrays geassocieerd met mV worden 1 genoemd en geassocieerd met dV worden 2 genoemd.
print(len(Vr))
Vr1 = Vr[:15]
Vr2 = Vr[15:]
Ve1 = Ve[:15]
Ve2 = Ve[15:]
print(Vr1,Vr2)
24
[6.00000e-06 1.00000e-05 2.18700e-03 1.13340e-02 1.14015e-01 7.70000e-05
1.48000e-04 3.55000e-04 1.60400e-03 5.11300e-03 1.61160e-02 3.54290e-02
6.75420e-02 9.15580e-02 1.21500e-01] [0.2572 0.804 1.137 2.1715 2.4756 3.657 4.8403 5.4026 5.9201]
print(Ve,Vr)
#Data processing and analysis:
Vd = Ve-Vr #naar de wetten van kirchoff wordt met deze formule de spanning over de diode berekend
Id = Vr/R #aan de hand van de wet van Ohm wordt de stroom door de diode berekend.
Ir = Id
#voor de error bars wordt hetzelfde uitgevoerd maar dan per apart array:
Vd1 = Ve1-Vr1
Id1 = Vr1/R
Ir1 = Id1
Vd2 = Ve2-Vr2
Id2 = Vr2/R
Ir2 = Id2
[0.01 0.02 0.22 0.31 0.53 0.07 0.09 0.13 0.19 0.26 0.33 0.39 0.45 0.49
0.53 0.71 1.31 1.66 2.72 3.04 4.24 5.44 6. 6.52] [6.00000e-06 1.00000e-05 2.18700e-03 1.13340e-02 1.14015e-01 7.70000e-05
1.48000e-04 3.55000e-04 1.60400e-03 5.11300e-03 1.61160e-02 3.54290e-02
6.75420e-02 9.15580e-02 1.21500e-01 2.57200e-01 8.04000e-01 1.13700e+00
2.17150e+00 2.47560e+00 3.65700e+00 4.84030e+00 5.40260e+00 5.92010e+00]
Onzekerheden
#onzekerheid in gemeten weerstand:
u_R = (0.002/100)*R+0.005 #gegeven door datasheet van de agilent multi meter. Deze is altijd constant omdat het slechts een meting is.
#onzekerheid in bronspanning Ve, deze is altijd hetzelfde
#maar om de error bars goed weer te geven moet ook deze array opgesplitst worden.
#de onzekerheden zijn verkregen uit de datasheet van de handheld multimeter
u_Ve1 = Ve1*7*10**(-3)+0.01
u_Ve2 = Ve2*7*10**(-3)+0.01
#De onzekerheid in de spanning over de weerstand verschilt voor array 1 en 2.
#deze onzekerheden zijn verkregen uit de datasheet van de agilent multi meter.
u_Vr1 = Vr1*3*10**(-5)+4*10**(-6)
u_Vr2 = Vr2*1.5*10**(-5)+10**(-4)+4*10**(-5)
#Met deze basis onzekerheden kunnen de onzekerheden in berekende waarden Id en Vd, de stroom en spanning over de diode berekend worden.
#Zie onderstaande cell voor de formule van deze grootheden
#Ook deze onzekerheden worden opgedeeld in twee arrays.
u_Vd1 = np.sqrt(((u_Ve1)**2)+(u_Vr1)**2)
u_Vd2 = np.sqrt(((u_Ve2)**2)+(u_Vr2)**2) #gegeven door standaard formule uit het dictaat te gebruiken van optellen meerdere variabelen.
u_Id1 = Id1*np.sqrt(((u_Vr1/Vr1)**2)+(u_R/R)**2)
u_Id2 = Id2*np.sqrt(((u_Vr2/Vr2)**2)+(u_R/R)**2) #gegeven door kwadratisch optellen van de relatieve onzekerheden.
print(u_Id1,Id1,u_Vd1,Vd1)
[4.01507593e-10 4.01519638e-10 4.08099774e-10 4.36242072e-10
7.80888594e-10 4.01721418e-10 4.01935295e-10 4.02559155e-10
4.06332852e-10 4.17018401e-10 4.51237907e-10 5.13375563e-10
6.20633412e-10 7.02908014e-10 8.07052543e-10] [6.02234289e-10 1.00372382e-09 2.19514398e-07 1.13762057e-06
1.14439571e-05 7.72867338e-09 1.48551125e-08 3.56321954e-08
1.60997300e-07 5.13203987e-07 1.61760130e-06 3.55609311e-06
6.77935139e-06 9.18989451e-06 1.21952444e-05] [0.01007 0.01014 0.01154 0.01217 0.01371 0.01049 0.01063 0.01091 0.01133
0.01182 0.01231 0.01273 0.01315 0.01343 0.01371] [0.009994 0.01999 0.217813 0.298666 0.415985 0.069923 0.089852 0.129645
0.188396 0.254887 0.313884 0.354571 0.382458 0.398442 0.4085 ]
#om een onzekerheid van de volledige array te krijgen worden de onzekerheids array1 en 2 achter elkaar gevoegd.
u_Id = np.append(u_Id1,u_Id2)
u_Vd = np.append(u_Vd1,u_Vd2)
def f(V,a,b):
return a*(np.exp(b*V)-1)
popt, pcov = curve_fit(f,Vd,Id,p0=[2.6643716530399914e-09,20.387516506496972],sigma=u_Id) # curve fit om de constante van stefan boltzmann te berekenen.
a = popt[0] #sperstroom
b = popt[1] #deze variabele b is gelijk aan -q*V_d / n*k_B*T met K_b de constante van Boltzmann
perr = np.sqrt(np.diag(pcov))
u_a = perr[0]
u_b = perr[0]
V = np.linspace(0,0.601,1000)
print('fit waarde a:',a,'onzekerheid in fit waarde a:',u_a)
print('fit waarde b:',b,'onzekerheid in fit waarde b',u_b)
fit waarde a: 2.7090450552962877e-09 onzekerheid in fit waarde a: 2.980307017066249e-10
fit waarde b: 20.347057071363384 onzekerheid in fit waarde b 2.980307017066249e-10
#Data processing and analysis:
#vormgeving van een dataplot met fit functie.
plt.yscale('log') #voor deze plot wordt gebruik gemaakt van een logaritmische schaal.
plt.ylabel('$Id (A)$')
plt.xlabel('$Vd (V)$')
plt.plot(Vd1,Id1, 'k.',linestyle='',label='Vr gemeten in mV')
plt.plot(Vd2,Id2, 'k.',linestyle='',label='Vr gemeten in dV')
plt.plot(V,f(V,a,b),'r',label='fit: a=%.2E, b=%.2E' % tuple(popt))
plt.errorbar(Vd1,Id1,u_Id1,u_Vd1,linestyle='',fmt='g')
plt.errorbar(Vd2,Id2,u_Id2,u_Vd2,linestyle='',fmt='g')
plt.legend()
plt.show()
#een tweede curve fit funtie om de richtingscoefficient te bepalen van de asymptoot van de datapunten.
def f1(V,a,b):
return a*(np.exp(b*V))
popt, pcov = curve_fit(f,Vd,Id) # curve fit om de constante van stefan boltzmann te berekenen.
a1 = popt[0] #sperstroom
b1 = popt[1] #deze variabele b is gelijk aan -q*V_d / n*k_B*T met K_b de constante van Boltzmann
perr1 = np.sqrt(np.diag(pcov))
u_a1 = perr[0]
u_b1 = perr[0]
V = np.linspace(-0.0001,0.601,1000)
#Data processing and analysis:
#vormgeving van een dataplot met fit functie.
plt.yscale('log') #voor deze plot wordt gebruik gemaakt van een logaritmische schaal.
plt.ylabel('$Id (A)$')
plt.xlabel('$Vd (V)$')
plt.plot(Vd1,Id1, 'k.',linestyle='',label='Vr gemeten in mV')
plt.plot(Vd2,Id2, 'k.',linestyle='',label='Vr gemeten in dV')
plt.plot(V,f1(V,a1,b1),'k-',color = 'grey',label='fit: a=%.2E, b=%.2E' % tuple(popt))
plt.errorbar(Vd1,Id1,u_Id1,u_Vd1,linestyle='',fmt='g')
plt.errorbar(Vd2,Id2,u_Id2,u_Vd2,linestyle='',fmt='g')
plt.plot(V,f(V,a,b),'r',label='fit: a=%.2E, b=%.2E' % tuple(popt))
plt.legend()
plt.savefig('plot kB.pdf')
plt.show()
/shared-libs/python3.7/py-core/lib/python3.7/site-packages/ipykernel_launcher.py:8: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "k-" (-> color='k'). The keyword argument will take precedence.
kB = -q/(n*b*T) #berekening constante van boltzmann uit waarde van b.
#onzekerheid in kB wordt gegeven door de onzekerheid in b te vermenigvuldigen met de partieel afgeleide naar b van de formule voor kB
u_kB = abs(u_b*q*(1/(n*T*b**(-2))))
print('constante van Boltzmann:',kB,'onzekerheid in de meting van de constante:',u_kB)
constante van Boltzmann: 1.3812937693800602e-23 onzekerheid in de meting van de constante: 3.467782637832341e-29
#Data processing and analysis:
plt.yscale('log') #voor deze plot wordt gebruik gemaakt van een logaritmische schaal.
plt.ylabel('$Id (A)$')
plt.xlabel('$Vd (V)$')
plt.plot(Vd1,Id1, 'k.',linestyle='',label='Vr gemeten in mV')
plt.plot(Vd2,Id2, 'k.',linestyle='',label='Vr gemeten in dV')
plt.plot(V,f1(V,a1,b1),'r',label='fit: a=%.2E, b=%.2E' % tuple(popt))
plt.errorbar(Vd1,Id1,u_Id1,u_Vd1,linestyle='',fmt='g')
plt.errorbar(Vd2,Id2,u_Id2,u_Vd2,linestyle='',fmt='g')
plt.legend()
plt.show()
#Calculations of e.a. measurement uncertainties, and providing final answers.
#strijdigheidsanalyse, het verschil tussen de twee waarden dient niet groter te zijn dan twee maal de onzekerheid kwadratisch opgeteld.
#literatuur waarde van kB: 1.380649·10**{−23}
kB_lit = 1.38064852*10**(-23)
u_kB_lit = 0.00000079*10**(-23) #de constante van boltzman is sinds 2019 een exacte waarde gedefineerd als bovenstaande
delta_kB = abs(kB-kB_lit) #het verschil tussen de gevonden waarde en literatuur waarde
u_double = 2*np.sqrt(u_kB**2+u_kB_lit**2)
if delta_kB>u_double:
print('de waarden komen niet overeen')
else:
print('wel')
proc = (1.38064852-1.38129)/1.38064*100
print(proc,'%')
de waarden komen niet overeen
-0.046462510140214755 %