Skip to content

Basisscript voor het experiment

Het experiment wat je gaat uitvoeren is het bepalen van de $I,U$-karakteristiek van een LED. Omdat de Arduino alleen getallen tussen 0 en 1023 kan sturen en ontvangen moet je nadenken over de analoog-digitaalconversie voordat je een zinnige $I,U$-karakteristiek kunt maken.

Analoog-digitaalconversie (ADC)

De Arduino kan getallen tussen 0 en 1023 sturen en ontvangen. Wat is precies de betekenis van deze getallen? Daarvoor moeten we dieper ingaan op hoe de Arduino — en computers in het algemeen — getallen omzet in een spanning en hoe spanningen door de Arduino worden gemeten.

Een analoog signaal is continu in zowel de tijd als de waardes die het signaal aan kan nemen.1 Een digitaal signaal is echter discreet: op vaste tijdstippen is er een waarde bekend en het signaal kan maar een beperkt aantal verschillende waardes aannemen.3

Bemonsteren of sampling is het proces waarbij een analoog signaal wordt uitgelezen en wordt omgezet in een digitaal signaal. Zo wordt een audiosignaal al sinds eind jaren '70 van de vorige eeuw gewoonlijk bemonsterd met een frequentie van 44.1 kHz en een resolutie van 16 bits. Dus 44100 keer per seconde wordt er gekeken wat de waarde van het geluidssignaal is en dat wordt opgeslagen als een getal van 16 bits en kan dus $2^{16} = 65536$ verschillende waardes aannemen. Dit is nauwkeuriger dan het menselijk gehoor kan onderscheiden.


03.3 V
0


ADC resolutie

De schuifjes hierboven zijn aan elkaar gekoppeld, zij laten de koppeling zien tussen analoge voltages en digitale waardes en visa versa. Het bovenste schuifje laat het analoge voltage zien. Het onderste schuifje is de bijbehorende digitale waarde.

  1. Zet het digitale signaal op een resolutie van 4-bit (16 stapjes). Stel je meet een digitale waarde van 6, wat zijn dan de mogelijke voltages die daarbij horen? Wat is dan de nauwkeurigheid?
  2. Zet het digitale signaal op een resolutie van 6-bit (64 stapjes). Stel je meet een digitale waarde van 28, wat zijn dan de mogelijke voltages die daarbij horen? Wat is dan de nauwkeurigheid?
  3. Zet het digitale signaal op een resolutie van 10-bit (1024 stapjes). Stel je meet een digitale waarde van 768, wat zijn dan de mogelijke voltages die daarbij horen? Wat is dan de nauwkeurigheid?

Je ziet dat naarmate het aantal bits omhoog gaat de resolutie beter wordt en daarmee ook de nauwkeurigheid.

Projecttraject

  • ADC resolutie
  • ADC conversie

De conversie van een analoog signaal naar een digitaal signaal (en andersom!) is de reden dat de spanningen die je kiest en de metingen die je doet niet alle mogelijke waardes kunnen aannemen, maar stapjes maken.

Omzetting van analoog naar digitaal signaal

De omzetting van een analoog signaal naar een digitaal signaal gebeurt als volgt. De ADC (analog-to-digital converter) in dit voorbeeld ondersteunt 16 niveaus (4-bits) in een bereik van 0 V tot 3.3 V (groen gearceerd). Lagere of hogere spanningen kunnen niet gemeten worden (rood gearceerd). Op gezette tijden wordt een meting gedaan (rode punten), waarbij de uitkomst van de meting het discrete niveau is dat het dichtst bij de analoge waarde ligt. Als het signaal te groot wordt kan de ADC als het ware vastlopen op het hoogste niveau. In de rechterflank is waar te nemen dat als het analoge signaal langzaam verandert, het digitale signaal duidelijk sprongsgewijs verandert. Hoe meer niveau's een ADC heeft en hoe vaker het signaal bemonsterd kan worden, hoe nauwkeuriger het digitale signaal het analoge signaal benadert.

Het digitale signaal

De digitale metingen die je programma krijgt van de ADC is hierboven weergegeven. De onzekerheid is gelijk aan de halve afstand tot het volgende niveau. In lichtgrijs zie je het oorspronkelijke analoge signaal. De meting benadert het signaal dus maar gedeeltelijk.

De Arduino die je gebruikt heeft een bereik van 0 V tot 3.3 V en — in tegenstelling tot het voorbeeld hierboven — een resolutie van 10 bits, dus $2^{10} = 1024$ niveaus. Als je een experiment ontwerpt is het van belang te weten dat je nooit kunt meten met een nauwkeurigheid kleiner dan de stapgrootte. Voor het experiment dat je gaat uitvoeren is deze resolutie prima.

ADC conversie

Je hebt gezien dat de Arduino werkt met getallen van 0 tot en met 1023 én dat de Arduino een bereik heeft van 0 V tot 3.3 V. Je schrijft de formule op om een ADC waarde naar een spanning in Volt om te rekenen en omgekeerd. Je controleert of je formules logische antwoorden geven door de spanning te berekenen die hoort bij een ADC waarde van 700. Ook bereken je de ADC waarde behorende bij 2.28 V.

Pseudo-code

# raw_value to voltage
# voltage = something with raw_value

# voltage to raw_value
# raw_value = something with voltage

Checkpunten

  • Een ADC waarde van 0 geeft een spanning van 0 V en omgekeerd.
  • Een ADC waarde van 1023 geeft een spanning van 3.3 V en omgekeerd.
  • Een ADC waarde van 700 is ongeveer tweederde van 1023, dus dat moet een spanning geven in de buurt van 2.2 V.
  • Een spanning van 2.28 V is ongeveer 70% van 3.3 V, dus dat moet een ADC waarde geven in de buurt van 720.

Projecttraject:

  • ADC resolutie
  • ADC conversie
Binair Talstelsel

Binair Talstelsel

Wij schrijven onze getallen op in een decimaal (tientallig) talstelsel. We hebben tien verschillende cijfers (0 t/m 9) en plakken bij grotere getallen de tientallen, honderdtallen, etcetera aan elkaar. Computers werken met binaire getallen — een tweetallig talstelsel. Dat betekent dat computers het getal 0 en 1 zonder problemen kunnen opslaan, maar bij het getal 2 wordt het al lastig. Zij moeten dan al met tientallen werken en schrijven het getal 2 op als 10. Het getal 3 is dan 11. Voor het getal 4 zijn de cijfers alweer op en moet je overschakelen naar honderdtallen, dus 4 is 100, 5 is 101, enzovoorts. Zie onderstaande tabel voor nog een paar voorbeelden.

De cijfers noem je bits en het getal 5 (101 binair) bestaat dus uit 3 bits. Als je maar 3 bits tot je beschikking hebt, kun je $2^3 = 8$ verschillende getallen opslaan, dus 0 t/m 7. Een groepje van 8 bits (256 mogelijkheden) bleek een handige hoeveelheid en kun je op computers individueel opslaan. Zo'n groepje noem je een byte. Bestanden bestaan uit bytes, kilobytes (duizend bytes), megabytes (miljoen bytes) of gigabytes (miljard bytes). Wanneer je een signaal nauwkeurig wilt verwerken met een computer dan is het belangrijk om zoveel mogelijk bits tot je beschikking te hebben. Hoe meer bits, hoe meer verschillende waardes je kunt opslaan en hoe nauwkeuriger je signaal wordt bewaard.

Voorbeelden van het binair talstelsel:

decimaal getal binair getal
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
205 11001101

De $I,U$-karakteristiek van een LED

Je hebt op de middelbare school ongetwijfeld de $I,U$-karakteristiek van een ohmse weerstand onderzocht. Je neemt een gewone weerstand en zet daar een steeds hogere spanning op. Je meet de stroomsterkte en ook die neemt toe — rechtevenredig zelfs! Door $I$ tegen $U$ uit te zetten in een grafiek en de beste lijn door je metingen te trekken vind je met de richtingscoëfficiënt de inverse van de weerstand, $R^{-1}$, zie onderstaand figuur.

I,U-curve van een weerstand

Een LED is een lichtgevende diode — en een diode gedraagt zich heel anders. Met de schakeling die je hebt gebouwd in de opdracht Schakeling bouwen, kun je de $I,U$-karakteristiek van een LED bepalen. Voor meer informatie over de fysica achter diodes, zie de appendix Diodes.

$I,U$-karakteristiek van een LED

Maak een schets van hoe je denkt dat de grafiek van de stroom $I$ tegen de spanning $U$ van een LED eruit zal zien.

Projecttraject

  • $I,U$-karakteristiek van een LED
  • Arduino heeft geen stroommeter
  • Arduino pinnetjes
  • Arduino op breadboard
  • Kanalen van de Arduino

Arduino heeft geen stroommeter

Schrijf op hoe je de spanning $U$ over de LED en de stroom $I$ door de LED berekent in termen van de spanningsmeters $U_1$ en $U_2$ en de bekende weerstand $R$.

Projecttraject

  • $I,U$-karakteristiek van een LED
  • Arduino heeft geen stroommeter
  • Arduino pinnetjes
  • Arduino op breadboard
  • Kanalen van de Arduino

Arduino pinnetjes

Kijk aan de onderkant van de Arduino of je de pinnetjes A0, A1, A2 en GND kan vinden.

Klik hier als je geen Arduino5 bij de hand hebt

Projecttraject

  • $I,U$-karakteristiek van een LED
  • Arduino heeft geen stroommeter
  • Arduino pinnetjes
  • Arduino op breadboard
  • Kanalen van de Arduino

Arduino op breadboard

Vergelijk de schakeling op het breadboard met de theoretische schakeling. Welke lijnen in de theoretische schakeling komen overeen met de vier draadjes (rood, blauw, groen, oranje) op het breadboard?

Projecttraject

  • $I,U$-karakteristiek van een LED
  • Arduino heeft geen stroommeter
  • Arduino pinnetjes
  • Arduino op breadboard
  • Kanalen van de Arduino

Kanalen van de Arduino

Bekijk de documentatie van de firmware en schrijf het commando op om de maximale uitvoerspanning op kanaal 0 te zetten. Schrijf ook de commando's op om de waardes van $U_1$ en $U_2$ uit te lezen.

Projecttraject

  • $I,U$-karakteristiek van een LED
  • Arduino heeft geen stroommeter
  • Arduino pinnetjes
  • Arduino op breadboard
  • Kanalen van de Arduino

Pythondaq: repository

Omdat je met een belangrijk project aan de slag gaat, namelijk een inleveropdracht, ga je gelijk goed beginnen door een repository aan te maken.

  1. Open Github Desktop en ga naar het dropdownmenu File. Kies hier voor New repository .... Geef de repository de naam pythondaq en zet de repository in de map ECPC. De mappenstructuur ziet er dan als volgt uit:
    ECPC
    ├── oefenopdrachten
    ├── pythondaq
               └── •••
    └── •••
  2. Vink Initialize this repository with a README aan.
  3. Kies bij Git ignore voor Python.
  4. Open de repository pythondaq via GitHub Desktop. Ga hiervoor naar het dropdownmenu Repository en kies voor Open in Visual Studio Code.
  5. Nu kun je aan de slag. Vergeet tijdens het werken niet regelmatig te committen!

Checkpunten

  • De repository pythondaq zit in de map ECPC.
  • In de repository pythondaq bevinden zich de bestanden README.md, .gitattributes en .gitignore.
  • De repository pythondaq is geopend in Visual Studio Code.

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Klik hier

Pythondaq: start script

Je maakt een bestand diode_experiment.py aan in de nieuwe repository pythondaq, waarin je de spanning over de LED laat oplopen van nul tot de maximale waarde. Je moet hiervoor ook weer opnieuw een virtual environment aanmaken (zie opdracht Virtual environment aanmaken). Tijdens het oplopen van de spanning over de LED lees je de verschillende spanningen uit. Je print steeds een regel met: ruwe waarde spanning over LED, voltage over LED, ruwe waarde spanning over weerstand, voltage over weerstand.
ECPC
├── oefenopdrachten
└── pythondaq
           ├── diode_experiment.py
           └── •••

Pseudo-code

diode_experiment.py
# connect to Arduino
#
# set output voltage from 0 to max
#   measure voltages
#   calculate voltage LED 
#   calculate voltage resistor
#   print LED: raw_voltage_LED (voltage_LED V) Resistor: raw_voltage_resistor (voltage_resistor V)

Checkpunten

  • Je hebt een virtual environment aangemaakt en die is goed geactiveerd (er staat (pythondaq) aan het begin van de prompt).
  • Je hebt alle benodigde packages geïnstalleerd in je virtual environment.
  • Je laat de spanning oplopen van nul tot de maximale waarde.
  • De LED licht vertraagd op en gaat dus steeds feller branden.
  • Commit!
  • De ruwe waardes over de LED en de weerstand zijn zoals verwacht.
  • Commit!
  • De omrekening van ruwe waardes naar voltages levert uitkomsten op die je kunt verwachten.
  • Commit!

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Je kunt de geprinte meetgegevens kopiëren en plakken naar een tekstbestand, spreadsheetprogramma, Python notebook of iets dergelijks. Maar dat is wel veel werk, zeker als je metingen wilt herhalen. Op dit moment heb je ook alleen nog maar ruwe metingen. En je gaat nog voorbij aan het feit dat je graag de stroomsterkte $I$ door de LED wilt uitzetten tegen de spanning $U$ over de LED.

Info

In de volgende opdracht ga je een grafiek maken. Installeer Matplotlib in de virtual environment.

Terminal
uv pip install matplotlib

Pythondaq: quick 'n dirty meting

Je code berekent de spanning over en de stroomsterkte door de LED terwijl de spanning over het circuit oploopt van nul tot de maximale waarde. De resultaten worden geprint én in een grafiek weergegeven. Aan het einde van alle metingen wordt de LED uitgezet.

Pseudo-code

diode_experiment.py
# connect to Arduino
#
# set output voltage from 0 to max
#   measure voltages
#   calculate voltage LED
#   calculate current LED
#   print voltage: voltage_LED V (raw_voltage_LED) current: current_LED A
#
# turn LED off
# plot current_LED vs voltage_LED

Checkpunten

  • Je laat de spanning oplopen van nul tot de maximale waarde.
  • De spanning $U$ over de LED wordt berekend.
  • De stroom $I$ door de LED wordt berekend.
  • De spanning $U$ en de stroom $I$ worden geprint in de terminal.
  • De waardes zijn fysisch correct.
  • De verschillende waardes voor de spanning worden in een lijst gezet.
  • De verschillende waardes voor de stroom worden in een lijst gezet.
  • De stroomsterkte $I$ wordt tegen de spanning $U$ uitgezet in een grafiek.
  • Je vergelijkt het resultaat met een buurmens. Je bespreekt of de verkregen grafiek fysisch correct is.
  • De LED wordt uitgezet na de meting.
  • Tussendoor heb je gecommit!

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Omdat je never nooit niet je conclusies gaat baseren op een enkele meetserie ga je de meting herhalen en foutenvlaggen toevoegen. Je moet misschien wel weer even hard nadenken over hoe je deze foutenvlaggen bepaald. Pak daarom eerst pen en papier (voordat je verder code gaat toevoegen), stoot je buurmens aan en ga samen nadenken over hoe jullie in dit experiment de onzekerheid kunnen bepalen.

Pythondaq: onzekerheid

Bekijk bovenstaande video, eventueel een paar keer. In deze video wordt een meting van de spanning $x_n$ keer herhaald. De groene rechthoek geeft de onzekerheid op een individuele meting weer. Het gemiddelde van alle metingen wordt weergegeven met een roze lijn. De roze rechthoek geeft de onzekerheid op het gemiddelde weer.

  1. Wat gebeurt er met de onzekerheid op een individuele meting als je de meting vaker herhaalt?
  2. Wat gebeurt er met de onzekerheid op het gemiddelde als je een meting vaker herhaalt?
  3. Heb je voor jouw experiment straks de onzekerheid op een individuele meting nodig? Of de onzekerheid op het gemiddelde? Hoe bepaal je deze onzekerheid?

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Pythondaq: schildpad of raket?

In het experiment ga je straks de metingen een aantal keer herhalen. Je kunt dan op twee manieren het gemiddelde van de benodigde grootheden bepalen en de bijbehorende onzekerheden.

  1. Je kunt dit stap voor stap doen, als een schildpad. Bij elke waarde van $U_0$ meet je een aantal keer de waardes van $U_1$ en $U_2$, waarna je een gemiddelde en de bijbehorende onzekerheid berekent. Daarna doe je hetzelfde voor de volgende waarde van $U_0$.
  2. Je kunt ook eerst voor het hele bereik van $U_0$ de waardes van $U_1$ en $U_2$ bepalen, als een raket. Dit herhaal je daarna een aantal keer. Pas nadat je álle metingen gedaan hebt, ga je een gemiddelde en de bijbehorende onderzekerheid berekenen.

Bespreek met je buurmens de voor- en nadelen van beide manieren. Maak hierin onderscheid tussen het experimentele gebied en het programmeergebied.

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Pythondaq: herhaalmetingen

Je gaat nu de code zo aanpassen dat je daadwerkelijk iets kunt zeggen over de onzekerheid op de spanning over de LED en de stroom door de LED. Dit doe je door een meting meerdere keren te herhalen. Je kijkt eerst naar de opbouw van de code en maakt aantekeningen over wat er waar en hoe in de code aangepast moet worden. Daarna kijk je naar je repository pythondaq en controleer je dat de nu-nog-werkende-code gecommit is. Vervolgens ga je stap voor stap — en commit na commit — de code aanpassen. Als je klaar bent, run je diode_experiment.py met het aantal herhaalmetingen op 3 en zie je in de grafiek foutenvlaggen op de metingen voor de stroom en de spanning staan. Je kijkt op het beeldscherm van je buurmens en ziet daar ook foutenvlaggen verschijnen. Met een grijs kijken jullie elkaar aan en geven jullie elkaar een high five

Pseudo-code

diode_experiment.py
# connect to Arduino
#
# set output voltage from 0 to max 
#   set number of repeated measurements
#       measure voltages
#       calculate voltage LED
#       calculate current LED       
#   calculate average voltage LED and uncertainty
#   calculate average current LED and uncertainty
#   print average voltage: average_voltage_LED +/- err_average_voltage_LED V  average current: average_current_LED +/- err_average_current_LED A
#
# turn LED off
# plot average_current_LED vs average_voltage_LED

Checkpunten

  • Er worden herhaalmetingen gedaan.
  • De gemiddelde spanning $U_{avg}$ over de LED wordt berekend.
  • De bijbehorende onzekerheid wordt correct bepaald.
  • De gemiddelde stroom $I_{avg}$ door de LED wordt berekend.
  • De bijbehorende onzekerheid wordt correct bepaald.
  • De gemiddelde spanning $U_{avg}$ en de gemiddelde stroom $I_{avg}$ worden met de bijbehorende onzekerheden geprint in de terminal.
  • De gemiddelde stroom $I_{avg}$ wordt tegen de gemiddelde spanning $U_{avg}$ uitgezet in een grafiek.
  • Op de datapunten zijn foutenvlaggen zichtbaar.
  • De foutenvlaggen zijn gekoppeld aan de juiste grootheid.
  • De LED wordt uitgezet na de meting.
  • Tussendoor heb je gecommit!

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV

Bewaren van meetgegevens

Het is fijn dat je script de meetgegevens op het scherm kan printen en er een grafiek van maakt, maar als je echt bezig bent met een onderzoek is een grafiek alleen niet voldoende. Je wilt dat de data bewaard blijft, zodat je die later nog kunt gebruiken voor nieuwe analyses. Ook is het zo dat data steeds vaker beschikbaar moet zijn voor andere wetenschappers die jouw onderzoek willen controleren. Steeds meer wetenschappelijke tijdschriften vragen auteurs niet alleen hun grafieken, maar ook hun onderliggende data beschikbaar te maken en te publiceren. Op die manier is het veel moeilijker om fraude te plegen; iets dat in de wetenschap helaas soms nog voor komt.

Er zijn ontzettend veel verschillende bestandsformaten waarin je data kunt bewaren. Er zijn grofweg twee categorieën: tekstbestanden en binaire bestanden. De eerste zijn te lezen met ieder willekeurig programma. Sommige zijn heel eenvoudig (bijvoorbeeld CSV), andere kunnen complexe datastructuren en extra informatie opslaan (bijvoorbeeld JSON en XML). Binaire bestanden bevatten alle mogelijke karakters — niet alleen letters, cijfers, leestekens, maar ook stuurcodes zoals carriage return en de line feed, oorspronkelijk opdrachten voor bijvoorbeeld printers. Ze hebben vaak een strak formaat: zoveel bytes voor dit stukje informatie, zoveel bytes voor dat stukje, enzovoorts. Met binaire karakters hoef je je dus niet te beperken tot letters, cijfers en leestekens en kunnen de bestanden wat kleiner zijn. Ook zorgen de vaste afspraken ervoor dat de lees- en schrijfroutines eenvoudiger kunnen zijn. Getallen worden in het interne geheugen van de computers ook binair opgeslagen dus het is vaak copy/paste vanuit of naar het bestand. Wel leiden kleine fouten vaak tot onbruikbare bestanden. Voor grote databestanden wordt vrijwel altijd gekozen voor een binair formaat, of het nou gaat om audio/video, databases of klimaatmodellen. Het uitwisselen van kleinere bestanden gebeurt echter vaak in een tekstformaat.

Comma-separated values (CSV)

Het CSV-bestand is het werkpaard van de wetenschap. Als je data wilt overzetten van het ene naar het andere programma of wanneer je wetenschappelijke gegevens van een website wilt downloaden, dan is het CSV-bestand vaak de beste keuze. Het formaat bestaat uit kolommen met getallen, gescheiden door een komma. De eerste regels kunnen commentaar (bijvoorbeeld uitleg over de kolommen) en de namen van de kolommen bevatten. Een voorbeeld van een CSV-bestand is hieronder gegeven. In dit voorbeeld wordt de afstand $s$ van een vallend voorwerp gedurende 10 s opgeslagen, welke gegeven wordt door $s = \frac{1}{2} g t^2$. Het CSV-bestand heeft kolommen $t$ en $s$. De getallen hebben een punt als decimaal scheidingsteken en de komma wordt gebruikt om de kolommen te scheiden.

t,s
0.0,0.0
1.0,4.9
2.0,19.6
3.0,44.1
4.0,78.4
5.0,122.50000000000001
6.0,176.4
7.0,240.10000000000002
8.0,313.6
9.0,396.90000000000003
10.0,490.00000000000006

Je kunt CSV-bestanden schrijven en lezen met de modules csv, numpy of pandas. De eerste is altijd meegeleverd met Python en is speciaal geschreven voor het bestandsformaat,10 maar NumPy1112 en Pandas1314 bevatten veel meer functionaliteiten op het gebied van wiskunde en data-analyse. Als je deze modules toch al gebruikt, hoef je niet te kiezen voor de kale csv-module.

De functie zip()

Het viel je misschien op dat in bovenstaand CSV-bestand op iedere regel een waarde voor de tijd en voor de afstand staat. Als je een lijst met tijden en een lijst met afstanden hebt dan bevat de eerste regel het eerste element uit beide lijsten, de tweede regel het tweede element, etcetera. Je kunt een for-loop schrijven die Python's indexnotatie gebruikt om de twee lijsten om te zetten naar een CSV-formaat: t[i], s[i]. Het kan óók — makkelijker — met de zip()-functie. Hieronder vind je een voorbeeld waarin beide methodes gebruikt worden. In het voorbeeld wordt uitgegaan van een lijst A en een lijst B6.

with_zip.py
A = [1, 2, 3, 4]
B = [1, 4, 9, 16]

for a, b in zip(A, B):
    print(a, b)
(ECPC) > python with_zip.py

with_indexing.py
A = [1, 2, 3, 4]
B = [1, 4, 9, 16]

for i in range(len(A)):
    print(A[i], B[i])
(ECPC) > python with_indexing.py

Vergelijk beide methodes goed. In het geval van zip() hoef je niet de lengte van de lijst op te zoeken en krijg je meteen de losse elementen zonder dat je ze zelf uit de lijst hoeft te plukken met indexnotatie.

Oefenen met zip()

Je hebt een lijst met krachten en een lijst met afstanden, zie het tabblad code. Loop over de lijsten heen en print voor iedere iteratie de kracht $F$, de afstand $s$ en de arbeid $W$. Maak hierbij gebruik van de zip-functie.

Pseudo-code

F = [1.2, 1.8, 2.4, 2.7, 3.1] # N
s = [0.3, 0.4, 0.6, 0.8, 1.0] # m 

# repeat
#   print F, s, W

Checkpunten

  • De for-loop maakt gebruik van zip() om de elementen uit de lijst op te vragen.
  • De variabelen hebben logische namen (en dus niet a en b).
  • De gegeven arbeid is correct berekend.

Projecttraject

  • Oefenen met zip

Het gebruik van de csv-module

Wanneer je de csv-module wilt gebruiken moet je éérst een bestand openen om in te schrijven, daarna een writer object aanmaken en dat object daarna gebruiken om regels te schrijven. Als laatste moet het bestand netjes afgesloten worden, zodat het bestand ook echt naar de schijf weggeschreven wordt. Het openen en sluiten van een bestand kun je Python het beste laten doen met het with-statement:7

with open('metingen.csv', 'w', newline='') as csvfile:
    # csvfile is nu een bestandsobject
    ...
    # na dit blok sluit Python automatisch het bestand

Bij open() geef je eerst de naam van het bestand, dan 'w' om aan te geven dat het bestand writeable moet zijn (gebruik 'r' om te lezen) en newline='' om Python niet zelf regeleindes te laten schrijven — dat doet de csv-module. Op de volgende manier schrijf je dan de CSV-data weg:

import csv

with open('metingen.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['t', 's'])
    writer.writerow([0.0, 0.0])
    writer.writerow([1.0, 4.9])
    writer.writerow([2.0, 19.6])
    ...
Je kunt het wegschrijven van de regels natuurlijk vervangen door een for-loop.

Pythondaq: CSV

Je breidt je code verder uit. De metingen worden nu ook als CSV-bestand weggeschreven. In de code wordt hiervoor gebruik gemaakt van de zip-functie en de csv-module.

Pseudo-code

diode_experiment.py
# connect to Arduino
#
# set output voltage from 0 to max
#   set number of repeated measurements
#       measure voltages
#       calculate voltage LED
#       calculate current LED       
#   calculate average voltage LED and uncertainty
#   calculate average current LED and uncertainty
#   print average voltage: average_voltage_LED +/- err_average_voltage_LED V  average current: average_current_LED +/- err_average_current_LED A
#
# turn LED off
# create csv-file
# plot average_current_LED vs average_voltage_LED

Checkpunten

  • Je script heeft nog steeds dezelfde functionaliteiten als bij de opdrachten Pythondaq: quick 'n dirty meting en Pythondaq: herhaalmetingen.
  • Je loopt over de verschillende lijsten heen met behulp van de zip-functie.
  • Het CSV-bestand bevat alle belangrijke data.
  • De waardes in het CSV-bestand komen overeen met de verwachte waardes.
  • Het CSV-bestand heeft op de eerste regel informatie over de kolommen staan (denk aan: grootheid en eenheid).

Projecttraject

  • Pythondaq: repository
  • Pythondaq: start script
  • Pythondaq: quick 'n dirty meting
  • Pythondaq: onzekerheid
  • Pythondaq: schildpad of raket?
  • Pythondaq: herhaalmetingen
  • Pythondaq: CSV
Git ignore

Het kan wenselijk zijn om niet alle bestanden mee te nemen voor versiebeheer in je repository. Soms wil je een specifiek bestand uitsluiten en soms wil je een bepaald bestandstype uitsluiten. Om GitHub te laten weten welke bestanden niet gecommit hoeven te worden, is er een bestand .gitignore. Let op de punt voor de bestandsnaam: dit betekent dat het om een verborgen bestand gaat en mogelijk zie je het daarom niet in je repository staan.

CSV-bestanden uitsluiten van versiebeheer

Stel je wilt alle CSV-bestanden uitsluiten van versiebeheer, dan kun je dat als volgt doen:

  1. Ga naar GitHub Desktop.
  2. Ga naar het tabblad Changes.
  3. Rechtermuisklik op het bestand wat je wilt negeren (ervan uitgaande dat je dit bestand nog niet hebt gecommit).
  4. Maak een keuze tussen Ignore file of Ignore all .csv files.
  5. Commit.
CSV bestandsnaam

Pas de code zodanig aan dat een CSV-bestand nooit wordt overschreven. Je kunt bijvoorbeeld controleren of het bestand al bestaat en aan de bestandsnaam een oplopend getal toevoegen (data-001.csv, data-002.csv, etcetera), net zo lang totdat je uitkomt bij een bestandsnaam die nog niet bestaat. Wees er zeker van dat je programma ook echt geen data overschrijft.

HDF5, PyTables

HDF5, PyTables

Een populair binair formaat in de wetenschappelijke wereld is HDF5.8 15 Je kunt hiermee verschillende datasets bewaren in één bestand. Je kunt een soort boomstructuur aanbrengen en zo verschillende datasets groeperen. Daarnaast kun je er ook nog extra informatie (metadata) aanhangen, zoals de datum van de meting, een beschrijving van de condities, etcetera. Je kunt een meetserie opslaan als reeks die in één keer in en uit het bestand wordt geladen, maar ook als tabel. Die laatste biedt de mogelijkheid om — net als in een database — data te selecteren en alleen die data in te laden uit het bestand. Op die manier is het mogelijk om met datasets te werken die groter zijn dan het geheugen van je computer.9 Meer informatie lees je in de tutorial van PyTables.16

PyTables16 is een Python bibliotheek die het werken met HDF5-bestanden makkelijker maakt. Er zijn uiteraard functies om de bestanden aan te maken en uit te lezen, maar ook om queries uit te voeren. Pandas kan — via PyTables — ook werken met HDF5-bestanden.

HDF5 tutorial

Download de HDF5 tutorial. Open de tutorial in Visual Studio Code en bestudeer de stappen die daar staan beschreven nauwkeurig.

PyTables

Pas je script aan zodat de meetserie van de LED wordt opgeslagen in een HDF5-bestand. Vraag hulp als je uitleg wilt over wat een UInt16 voor een ding is. Gebruik één bestand en maak daarin een nieuwe dataset voor iedere meetserie. Bewaar ook wat metadata (bijvoorbeeld tijdstip van de meting). Iedere keer dat je je script runt wordt er aan hetzelfde databestand een nieuwe dataset toegevoegd.


  1. Een vallende bal is een continu proces. De bal heeft op elk willekeurig moment een positie. Je zou de positie kunnen meten op het tijdstip $t$ = 2.0 s, maar ook op $t$ = 2.1, 2.01, 2.001 of 2.0001 s. Ook kun je de positie net zo nauwkeurig bepalen als je wilt.2 

  2. Uiteraard afhankelijk van de nauwkeurigheid van je meetinstrument. 

  3. De natuur is analoog,4 maar moderne computers zijn digitaal en dus discreet. Als je een foto op je computer te ver inzoomt zie je blokjes. Je kunt verder inzoomen, maar je gaat niet meer detail zien. De hoeveelheid informatie is beperkt. 

  4. Totdat je het domein van de kwantummechanica betreedt, dan blijkt de natuur ook een discrete kant te hebben. 

  5. Dit model bevat een 3D model die is gecreëerd door AppliedSBC en is gedeeld onder CC-BY-SA licentie. Het originele model is te vinden via Arduino Nano 33 IoT. Het model is voorzien van een Arduino texture. Dit 3D model heeft een CC-BY-SA licentie. 

  6. Je kunt net zoveel lijsten in zip() gooien als je wilt: for a, b, c, d, e in zip(A, B, C, D, E) is bijvoorbeeld geen probleem. 

  7. Hier is open() een zogeheten context manager: een functie die je kunt gebruiken met een with-statement en dat bij de start iets doet — hier een bestand openen — en bij het eind iets doet — hier het bestand weer netjes afsluiten. Je kunt zelf ook context managers schrijven, als je wilt. 

  8. Hierarchical Data Format Version 5 is in gebruik bij bijvoorbeeld de LOFAR radiotelescoop, het IceCube neutrino-observatorium en de LIGO zwaartekrachtsgolvendetector. 

  9. Lees bijvoorbeeld deze korte blogpost over het gebruik van HDF5. 

  10. Python Software Foundation. Csv – csv file reading and writing. URL: https://docs.python.org/3/library/csv.html

  11. The NumPy Development Team. Numpy – the fundamental package for scientific computing with python. URL: https://numpy.org

  12. Charles R. Harris, K. Jarrod Millman, St'efan J. van der Walt, Ralf Gommers, Pauli Virtanen, David Cournapeau, Eric Wieser, Julian Taylor, Sebastian Berg, Nathaniel J. Smith, Robert Kern, Matti Picus, Stephan Hoyer, Marten H. van Kerkwijk, Matthew Brett, Allan Haldane, Jaime Fern'andez del R'ıo, Mark Wiebe, Pearu Peterson, Pierre G'erard-Marchant, Kevin Sheppard, Tyler Reddy, Warren Weckesser, Hameer Abbasi, Christoph Gohlke, and Travis E. Oliphant. Array programming with NumPy. Nature, 585(7825):357–362, September 2020. URL: https://doi.org/10.1038/s41586-020-2649-2, doi:10.1038/s41586-020-2649-2

  13. The pandas development team. Pandas-dev/pandas: pandas 1.0.5. June 2020. URL: https://doi.org/10.5281/zenodo.3898987, doi:10.5281/zenodo.3898987

  14. Wes McKinney. Data Structures for Statistical Computing in Python. In Stéfan van der Walt and Jarrod Millman, editors, Proceedings of the 9th Python in Science Conference, 56 – 61. 2010. doi:10.25080/Majora-92bf1922-00a

  15. The HDF Group. The hdf5 library and file format. URL: https://www.hdfgroup.org/solutions/hdf5/

  16. Ivan Vilata Francesc Alted and others. PyTables: hierarchical datasets in Python. URL: http://www.pytables.org/