Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Bepaling van warmtecapaciteit van een onbekend materiaal

#import necessary libraries
import matplotlib.pyplot as plt
import numpy as np
import math
from scipy.optimize import curve_fit 

Introductie

Onbekende materialen kunnen geïdentificeerd worden door hun eigenschappen te meten. Een van deze eigenschappen is de warmtecapaciteit. In dit practicum gaan we de warmtecapaciteit van een onbekend materiaal bepalen door middel van een calorimeter experiment. Daarbij wordt een bepaalde massa van het materiaal naar een bekende temperatuur gebracht waarna het in een bekende hoeveelheid water met bekende temperatuur wordt geplaatst. Door de temperatuur van het water te meten na het mengen kan de warmtecapaciteit van het onbekende materiaal worden berekend.

Theorie

De soortelijke warmte cc van een materiaal is gedefinieerd als de hoeveelheid warmte QQ die nodig is om de temperatuur TT van een kilogram van het materiaal met één graad Celsius (of één Kelvin) te verhogen:

c=QmΔTc = \frac{Q}{m \Delta T}

Waarbij QQ de hoeveelheid warmte in Joules is, mm de massa in kilogram is en ΔT\Delta T de verandering in temperatuur is. Gegeven de wet van Black, die stelt dat de totale hoeveelheid warmte in een geïsoleerd systeem constant blijft, kunnen we de warmte die het onbekende materiaal verliest gelijkstellen aan de warmte die het water opneemt:

Qmateriaal=QwaterQ_{materiaal} = -Q_{water}

wanneer we de massa’s en de begintemperaturen van beide systemen kennen, maar slechts een van de twee soortelijke warmtes, kunnen we de onbekende soortelijke warmte berekenen. We combineren vergelijkingen (1) en (2) om de volgende vergelijking te krijgen:

Te=cwmwTw,b+cmmmTm,bcwmw+cmmmT_e = \frac{c_w m_w T_{w,b}+c_m m_m T_{m,b}}{c_w m_w + c_m m_m}

Waarbij de subscripts bb en ee respectievelijk staan voor begintoestand en eindtoestand, ww voor water en mm voor het onbekende materiaal.

Bij metingen aan verschillende massa’s van het onbekende materiaal en vervolgens een least square fit aan bovenstaande vergelijking kunnen we een precieze waarde voor de soortelijke warmte van het onbekende materiaal bepalen. Dat is, wanneer de warmtecapaciteit van bijvoorbeeld de beker te verwaarlozen is.

Methode en materialen

Ontwerp

De bovenstaande theorie wordt gebruikt om de soortelijke warmte van een onbekend materiaal te bepalen. Het experiment bestaat uit het verwarmen van verschillende massa’s van het onbekende materiaal tot een bekende temperatuur, waarna het in een bekende hoeveelheid water met bekende temperatuur wordt geplaats. Door de temperatuur van het water te meten na het mengen kan de warmtecapaciteit van het onbekende materiaal worden berekend. Om de tijd voor het meten van meerdere materialen te reduceren, worden de data van de verschillende groepen in het lokaal samengevoegd. Van tevoren is afgesproken welke massa’s door welke groep worden gemeten, en hoeveel water er gebruikt wordt.

Materialen

Hieronder staat de lijst van benodigde materialen bij deze proef:

  • Calorimeter

  • Thermometer of temperatuursensor (±0.1K)

  • Verwarmingsbron

  • Diverse massablokjes van onbekend materiaal

  • Weegschaal (+/- 0.1 g)

  • Water

  • Maatcilinder (250mL250 \, \text{mL}) of maatbeker (400mL400 \, \text{mL})

  • Keukenpapier

  • Lange steel

  • Roerstaaf

Een schematische weergave van de opstelling

Figure 1:Een schematische weergave van de opstelling

Procedure

Bespreek wie welke massa’s van het onbekende materiaal gaat meten. Bespreek ook hoeveel water er gebruikt gaat worden. Bepaal de begintemperaturen. Hevel het aantal afgesproken massa’s in de maatbeker. Roer voorzicht zodat de temperatuur homogeen is. Noteer de hoogste gemeten temperatuur, dit is TeT_e. Wissel de metingen uit met de andere groepen en voer de data-analyse uit.

Weeg vijf verschillende massa’s van de onbekende stof nauwkeurig af en noteer deze (m1m_{1} tot m5m_{5} met onzekerheid +/- 0.0001 kg). Zorg voor een zo breed mogelijk bereik in massa’s. Weeg het bekerglas voordat het water wordt toegevoegd. Meet 250.0mL250.0 \, \text{mL} water af met de maatcilinder en giet dit in het bekerglas. De hoeveelheid water in de maatcilinder moet niet te klein zijn, omdat er anders een grote systematsche fout wordt gemaakt door warmteverlies aan de lucht. De hoeveelheid water moet ook niet te groot zijn, omdat er anders geen homogene temperatuursverandering meetbaar is. Voor elke meting wordt vers 250.0mL250.0 \, \text{mL} kraanwater gebruikt. Weeg telkens het bekerglas met water om de massa van het water te bepalen. Laat de onbekende stof lang genoeg, circa 5 minuten, in het verwarmingselement/ in de calorimeter zodat deze een stabiele, bekende temperatuur bereikt. Je meet de begintemperatuur van het water met een thermometer en de begintemperatuur van de onbekende stof lees je af op het verwarmingselement (aanname: T_onbekende stof = T_water in verwarmingselement). Meet de temperatuur van de 250.0mL250.0 \, \text{mL} water in het bekerglas vlak voor toevoeging en noteer deze, inclusief de onzekerheid van 0.1 K. Voeg, met een lange steel, de afgewogen massa van de onbekende stof zo snel en beheerst mogelijk toe aan het bekerglas om warmteverlies aan de omgeving tijdens deze stap te minimaliseren. Vervolgens roer je met een roerstaaf om gelijkmatige warmte-uitwisseling te garanderen. Zorg er hierbij voor dat de sensor vrij en stil in het water zweeft en dat de thermometer de massa of de bodem/wand niet raakt, om onjuiste lokale temperatuurmetingen te voorkomen. Blijf de temperatuur noteren totdat deze begint af te nemen na het bereiken van het maximum, of totdat de temperatuur stabiel is. De maximale temperatuur is TeindT_{\text{eind}}. Noteer de onzekerheid van ±0.01K\pm 0.01 \, \text{K}. Nadat de eindtemperatuur is afgelezen, wordt de thermometer telkens gedroogd. Dit voorkomt dat waterresten van een eerdere meting de volgende meting beïnvloeden. De meetresultaten vormen een dataset van massa’s (mm) en de bijbehorende eindtemperaturen (TeindT_{\text{eind}}). Deze data worden geplot in de (m,Teind)(m, T_{\text{eind}})-grafiek om de soortelijke warmte van de onbekende stof te bepalen door middel van curve-fitting.

Resultaten

# eerste 3 metingen met 250 ml water
# Constanten en Onzekerheden
u_massa = 0.0001  # kg
u_T = 0.1         # K
T_stof_start = 69.9
c_water = 4186

# Data: [m_beker, m_beker_water, T_start, m_stof, T_eind]
metingen = [
    [0.1456, 0.3919, 20.6, 0.0388, 21.4],
    [0.1899, 0.4290, 20.5, 0.0391, 21.4],
    [0.1456, 0.3869, 19.2, 0.0260, 20.1]
]

# 3 metingen overzichtelijk printen
print(f"{'Nr':<4} | {'m_water (kg)':<15} | {'m_stof (kg)':<12} | {'dT (K)':<10} | {'c_stof (J/kgK)':<15}")
print("-" * 75)
# Loop door de metingen en bereken de benodigde waarden
for i, m in enumerate(metingen, 1):
    m_w = m[1] - m[0]
    m_s = m[3]
    dT = m[4] - m[2]
    
    # Berekening per punt
    # c_s = (c_w * m_w * dT) / (m_s * (T_start_m - T_eind))
    c_s = (c_water * m_w * dT) / (m_s * (T_stof_start - m[4]))
    
    # Foutberekening (Propagatie van fouten)
    u_c_s = c_s * np.sqrt((u_massa / m_w)**2 + (u_massa / m_s)**2 + (2 * u_T / dT)**2)
    u_m_water = np.sqrt(u_massa**2 + u_massa**2)
    
    print(f"{i:<4} | {m_w:>7.4f} ±{u_m_water:.4f} kg | {m_s:>7.4f} ±{u_massa:.4f} kg | {dT:>4.1f} ±{u_T*2:.1f} K | {c_s:>8.1f} ± {u_c_s:>6.1f} J/kgK")

# Voor curve_fit
m_w_array = np.array([m[1]-m[0] for m in metingen])
m_s_array = np.array([m[3] for m in metingen])
T_e_array = np.array([m[4] for m in metingen])
T_b_array = np.array([m[2] for m in metingen])
Nr   | m_water (kg)    | m_stof (kg)  | dT (K)     | c_stof (J/kgK) 
---------------------------------------------------------------------------
1    |  0.2463 ±0.0001 kg |  0.0388 ±0.0001 kg |  0.8 ±0.2 K |    438.3 ±  109.6 J/kgK
2    |  0.2391 ±0.0001 kg |  0.0391 ±0.0001 kg |  0.9 ±0.2 K |    475.0 ±  105.6 J/kgK
3    |  0.2413 ±0.0001 kg |  0.0260 ±0.0001 kg |  0.9 ±0.2 K |    702.1 ±  156.0 J/kgK
# eerste 3 metingen met circa 250 mL water
# berekening gemiddelde watermassa en begintemperatuur
m_w_gem = (m_w_array[0] + m_w_array[1] + m_w_array[2]) / 3
u_m_w_gem = u_massa / np.sqrt(3)
print(f"m_water_gem: {m_w_gem:.4f} ± {u_m_w_gem:.4f} kg")
T_w_b_gem = (20.6 + 20.5 + 19.2) /3
u_T_w_b_gem = u_T / np.sqrt(3)
print(f"T_water_begin_gem: {T_w_b_gem:.2f} ± {u_T_w_b_gem:.2f} °C")

m_w_gem = 0.24223333333333333  # Massa water in kg
T_w_b_gem = 20.099999999999998  # Begintemperatuur water in graden

# DATA
m_onbekende_stof1 = m_s_array
T_eind1 = np.array([21.4, 21.4, 20.1])
soortelijke_warmte_water = 4186 # J/(kg * K)

# De functie neemt alleen de onafhankelijke variabele (m_m) en de fitte parameter (c_m) als argumenten
def function_fit(m_m, c_m):
    # Evenwichtstemperatuur: T_eind = (c_w * m_w * T_w_b + c_m * m_m * T_start_m) / (c_w * m_w + c_m * m_m)
    teller = soortelijke_warmte_water * m_w_gem * T_w_b_gem + c_m * m_m * T_onbekende_stof_start
    noemer = soortelijke_warmte_water * m_w_gem + c_m * m_m
    return teller / noemer

# c_m is nu de enige parameter, dus p0=[500] als initiële gok. Koper heeft bijv. c_m ~ 385 J/(kg*K)
values, pcov = curve_fit(function_fit, m_onbekende_stof1, T_eind1, p0=[500])        
c_m_fit = values[0] # c_m is nu de eerste gefitte parameter
print(f"soortelijke warmte onbekende stof: {c_m_fit:.1f} ± {np.sqrt(pcov[0,0]):.1f} J/(kg * K)")

x_test = np.linspace(min(m_onbekende_stof1)* 0.8, max(m_onbekende_stof1)*1.1, 500)

plt.figure(figsize=(8, 6), dpi=450)
plt.xlabel('$m_{m}$ (kg) - Massa onbekende stof')
plt.ylabel('$T_{eind}$ ($\\,^\circ\\text{C}$) - Evenwichtstemperatuur', rotation=0, labelpad=100, va='center')
plt.title('Eindtemperatuur versus massa onbekende stof (met watermassa ~ 0.25 kg)')
plt.ylim(19, 22)
plt.errorbar(m_onbekende_stof1, T_eind1, 
             xerr=u_massa,          # Foutbalk op de x-as (massa)
             yerr=u_T,              # Foutbalk op de y-as (temperatuur)
             fmt='+',               # Markeringstype (het kruisje)
             color='black',         # Kleur van de punten en balkjes
             capsize=3,             # De breedte van de 'hoedjes' op de balkjes
             label='Meetpunten met onzekerheid')
plt.plot(x_test, function_fit(x_test, c_m_fit), '-', label=f'Fit ($c_{{m}} \\approx {c_m_fit:.1f}\\, \\text{{J/(kg·K)}}$)')
plt.grid(True, linestyle='--', alpha=0.6)
plt.axhline(0, color='black', linewidth=0.8)
plt.axvline(0, color='black', linewidth=0.8)
plt.legend()
plt.tight_layout()
plt.savefig("fitting_result.png")
plt.show()
m_water_gem: 0.2422 ± 0.0001 kg
T_water_begin_gem: 20.10 ± 0.06 °C
soortelijke warmte onbekende stof: 565.6 ± 194.3 J/(kg * K)
<Figure size 3600x2700 with 1 Axes>
# laatste 4 metingen met circa 50 mL water
# Data serie 2: [m_beker, m_beker_water, T_start, m_stof, T_eind]
metingen_50ml = [
    [0.0502, 0.0990, 19.9, 0.0133, 21.5], # Meting 4
    [0.0326, 0.0777, 19.1, 0.0262, 21.9], # Meting 5
    [0.0502, 0.0945, 19.6, 0.0131, 20.5], # Meting 6
    [0.0326, 0.0854, 19.0, 0.0654, 25.1]  # Meting 7
]

print(f"\n{'Nr':<4} | {'m_water (kg)':<15} | {'m_stof (kg)':<12} | {'dT (K)':<10} | {'c_stof (J/kgK)':<15}")
print("-" * 75)

for i, m in enumerate(metingen_50ml, 4):
    m_w = m[1] - m[0]
    m_s = m[3]
    dT = m[4] - m[2]
    
    # Berekening c_s en onzekerheden
    c_s = (c_water * m_w * dT) / (m_s * (T_stof_start - m[4]))
    u_c_s = c_s * np.sqrt((u_massa / m_w)**2 + (u_massa / m_s)**2 + (2 * u_T / dT)**2)
    u_m_water = np.sqrt(u_massa**2 + u_massa**2)
    print(f"{i:<4} | {m_w:>7.4f} ±{u_m_water:.4f} kg | {m_s:>7.4f} ±{u_massa:.4f} kg | {dT:>4.1f} ±{u_T*2:.1f} K | {c_s:>8.1f} ± {u_c_s:>6.1f} J/kgK")
    
# Voor je curve_fit later:
m_w_array_50ml = np.array([m[1]-m[0] for m in metingen_50ml])
m_s_array_50ml = np.array([m[3] for m in metingen_50ml])
T_e_array_50ml = np.array([m[4] for m in metingen_50ml])
T_b_array_50ml = np.array([m[2] for m in metingen_50ml])

Nr   | m_water (kg)    | m_stof (kg)  | dT (K)     | c_stof (J/kgK) 
---------------------------------------------------------------------------
4    |  0.0488 ±0.0001 kg |  0.0133 ±0.0001 kg |  1.6 ±0.2 K |    507.7 ±   63.6 J/kgK
5    |  0.0451 ±0.0001 kg |  0.0262 ±0.0001 kg |  2.8 ±0.2 K |    420.3 ±   30.1 J/kgK
6    |  0.0443 ±0.0001 kg |  0.0131 ±0.0001 kg |  0.9 ±0.2 K |    257.9 ±   57.3 J/kgK
7    |  0.0528 ±0.0001 kg |  0.0654 ±0.0001 kg |  6.1 ±0.2 K |    460.2 ±   15.1 J/kgK
# laatste 4 metingen met circa 50 mL water
# berekening gemiddelde watermassa en begintemperatuur
m_w_gem = (0.0488 + 0.04510000000000001 + 0.0443 + 0.05280000000000001) / 4
u_m_w_gem = u_massa / np.sqrt(4)
print(f"m_w_gem: {m_w_gem:.5f} ± {u_m_w_gem:.5f} kg")
T_w_b_gem = (19.9 + 19.1 + 19.6 + 19.0) /4
u_T_w_b_gem = u_T / np.sqrt(4)
print(f"T_w_b_gem: {T_w_b_gem:.2f} ± {u_T_w_b_gem:.2f} graden")

m_w_gem = 0.04775  # Massa water in kg
T_w_b_gem = 19.4  # Begintemperatuur water in graden

# DATA
m_onbekende_stof2 = m_s_array_50ml
T_eind2 = np.array([21.5, 21.9, 20.5, 25.1])

# c_m is nu de enige parameter, dus p0=[500] als initiële gok
values, pcov = curve_fit(function_fit, m_onbekende_stof2, T_eind2, p0=[500])
c_m_fit = values[0] # c_m is nu de eerste (en enige) gefitte parameter (index 0)
u_c_m_fit = np.sqrt(pcov[0,0])
print(f"soortelijke warmte onbekende stof: {c_m_fit:.0f} ± {u_c_m_fit:.0f} J/(kg * K)")

x_test = np.linspace(min(m_onbekende_stof2)* 0.8, max(m_onbekende_stof2)*1.1, 500)

plt.figure(figsize=(8, 6), dpi=450)
plt.xlabel('$m_{m}$ (kg) - Massa onbekende stof')
plt.ylabel('$T_{eind}$ ($\\,^\circ\\text{C}$) - Evenwichtstemperatuur', rotation=0, labelpad=100, va='center')
plt.title('Eindtemperatuur versus Massa Onbekende Stof (met watermassa ~ 0.05 kg)')
plt.ylim(20, 26)
plt.errorbar(m_onbekende_stof2, T_eind2, 
             xerr=u_massa,          # Foutbalkje horizontaal
             yerr=u_T,              # Foutbalkje verticaal
             fmt='+',               # Markering is een plusje
             color='black',         # Kleur van de punten en balkjes
             capsize=3,             # Horizontale streepjes op de balkjes
             label='Meetpunten (incl. onzekerheid)')
plt.plot(x_test, function_fit(x_test, c_m_fit), '-', label=f'Fit ($c_{{m}} \\approx {c_m_fit:.1f}\\, \\text{{J/(kg·K)}}$)')
plt.grid(True, linestyle='--', alpha=0.6)
plt.axhline(0, color='black', linewidth=0.8)
plt.axvline(0, color='black', linewidth=0.8)
plt.legend()
plt.tight_layout()
plt.savefig("fitting_result.png")
plt.show()
m_w_gem: 0.04775 ± 0.00005 kg
T_w_b_gem: 19.40 ± 0.05 graden
soortelijke warmte onbekende stof: 400 ± 32 J/(kg * K)
<Figure size 3600x2700 with 1 Axes>
Source
# Sla figuren op met  
# plt.savefig("Figuren/naam.png", dpi=450)
# waarbij naam vervangen wordt door de bestandsnaam. 
# Onderstaande voorbeeld code en output grafiek 
# Gemiddelde begintemperatuur en gemiddelde massa water berekening
Output
Hier is het onderschrift van de figuur.

Figure 2:Hier is het onderschrift van de figuur.

Discussie en conclusie

Op basis van de tweede meetserie is de soortelijke warmte van de onbekende stof bepaald op cm399.8J/(kgK)c_m \approx 399.8 \, \text{J}/(\text{kg}\cdot\text{K}). Dit resultaat, verkregen door het watervolume te verkleinen naar 50mL50 \, \text{mL} voor een beter meetbare temperatuurstijging, komt sterk overeen met de literatuurwaarde van messing (380-400J/(kgK)380\text{-}400 \, \text{J}/(\text{kg}\cdot\text{K})). De eerste meetserie met 250mL250 \, \text{mL} water bleek onvoldoende nauwkeurig door een te kleine ΔT\Delta T, wat resulteerde in een afwijkende waarde van 565.6J/(kgK)565.6 \, \text{J}/(\text{kg}\cdot\text{K}). Na uitvoering van de eerste drie metingen, is het meetplan daarom lichtelijk aangepast (250mL250 \, \text{mL} -> 50mL50 \, \text{mL}).

De betrouwbaarheid van het experiment wordt echter beperkt door diverse systematische fouten. De theoretische aanname van een volledig geïsoleerd systeem werd geschonden doordat warmte ontsnapte via geleiding naar de tafel en het glas, en via straling en verdamping naar de omgeving. Daarnaast introduceerde het overbrengen van het massablokje fouten: aanklevend heet water verstoorde zowel de eindtemperatuur als de totale watermassa. Ook de beperkte nauwkeurigheid van de weegschaal (±0.1g\pm 0.1 \, \text{g}) en de temperatuursensor (±0.1K\pm 0.1 \, \text{K}) droeg bij aan de onzekerheid, al was dit effect ondergeschikt aan het warmteverlies.

Voor vervolgonderzoek wordt aangeraden een geïsoleerde calorimeter te gebruiken om warmteverlies te minimaliseren. Daarnaast kan de homogeniteit van de watertemperatuur worden gewaarborgd door de inzet van een magnetische roerder en een roervlo, wat zorgt voor een constante roersnelheid en meer reproduceerbare resultaten. Concluderend is de huidige opstelling met een bekerglas onvoldoende om een valide en precieze bepaling van de soortelijke warmte te garanderen.