🚧 This page is still under construction – errors and incomplete content are possible. Feedback (bugs, content suggestions) welcome at info@sd20.org
Traumschreiber Tutorial

Get Started

Step by step through your first measurements

1
2
3
4
···

Overview

Level 1

Power on & read battery level

Learn the basics – power on/off, SD card, and battery status check.

⚡ 100 XP
You are holding a device that records biosignals – but right now it is sleeping. In this level you wake it up for the first time: you learn how to safely power it on and off, read the battery level, and charge it again. Sounds small – but it is the foundation for everything that follows. Master this and you will never lose data or time later.
⚡
Important Safety Rule

Never charge the Traumschreiber via USB and use it connected to the body at the same time. The rule is always: either charging or measuring – never both at once.

The Traumschreiber enforces this itself: when the USB cable is plugged in, the LED flashes red 5 times, a loud, low beep sounds, a running recording is saved and the device switches itself off. To continue, unplug the cable and switch the device off and on again. Easiest: set the switch to off before charging – it still charges.

💾 SD Card: The SD card may only be inserted or removed when the device is switched off. Otherwise the file system on the card may be corrupted.

Step by Step

  • 1
    Insert SD card

    Make sure the Traumschreiber is switched off. Slide the SD card into the slot – you should feel a soft click.

  • 2
    Switch on

    Slide the switch on the side of the housing to the on position. The Traumschreiber will now boot.

  • 3
    LED Demo & Start Tone

    Right after startup the LED fades in green. If an SD card is inserted, the start tone follows: a short chime and the spoken word "Traumschreiber". Then the LED flashes green twice and pulses blue until the app connects. Without an SD card it stays silent – the LED still shows the green sequence, just a few seconds later.

🎯 Quest
Press the Button Once
After startup, press the small round black button on the Traumschreiber once. The device will then show you the current battery level via the LED – in colour and number of flashes.

Reading the Battery Level

How does the display work?

The LED flashes 1 to 10 times. Each flash equals ~10 % battery capacity. The colour gives additional info: red means low, yellow is mid, green means full. Each flash lasts ~300 ms followed by 150 ms pause.

~10 %
1 flash · Red
~30 %
3 flashes · Orange
~50 %
5 flashes · Yellow
~70 %
7 flashes · Yellow-green
~100 %
10 flashes · Green
⏱ Note: After first power-on, the battery monitor needs about 30 seconds to deliver a stable and accurate reading. Please wait briefly before treating the value as reliable.
  • 4
    Switch off Traumschreiber

    Slide the switch back to the off position.

  • 5
    Remove the SD card safely

    Only when the device is fully switched off may the SD card be removed. Press briefly – the card springs out.

Charging the Battery

  • 6
    Connect USB-C cable

    Switch off the Traumschreiber and plug in a USB-C cable. The device will start charging immediately. Whether an SD card is inserted or not makes no difference for charging.

  • 7
    Read charge status from LED

    Solid red → charging.  ·  Solid green → fully charged. From empty to full takes about 2 hours. A full battery enables over 16 hours of continuous recording.

Level 2

First ECG Recording

Attach electrodes, record, open EDF file – your first biosignal.

⚡ 250 XP
Now it gets real: you stick electrodes on your skin and record your own heart for the first time. ECG is the most accessible biosignal there is – the heart beats loudly and regularly, every deflection clearly visible. What you see at the end of this level is not a sample image from the internet, but your own heart in real time, recorded by a device you are holding yourself.
⚡
Safety rule – here too!

Once electrodes are attached to the body, the USB charging cable must not be connected. Always: either charging or measuring – never both at the same time.

Attaching Electrodes

R L + −
Electrode 1 – right side, below collarbone

Attach the first electrode on the right side of your chest, directly below the right collarbone. The skin should be dry and clean.

Electrode 2 – left lower rib margin

Attach the second electrode at the left lower rib margin. This distance between the two points produces a good ECG lead (Einthoven position).

Tips for good contact
  • Rub the skin with a cloth beforehand
  • Use self-adhesive gel electrodes
  • Hair in the electrode area can reduce contact quality
  • Sit or lie as still as possible during recording

Making a Recording

  • 1
    Insert SD card (device off!)

    Make sure the Traumschreiber is switched off, then insert the SD card.

  • 2
    Switch on

    Slide the switch to the on position. The start tone plays (if SD card present) and the LED demo runs briefly.

  • 3
    Wait 60 seconds

    The Traumschreiber starts recording all channels immediately. Stay still – movement creates artefacts in the signal. After about 60 seconds you have an analysable ECG sequence.

  • 4
    Switch off

    Slide the switch back to the off position. The recording is automatically finalised and written to the SD card.

  • 5
    Remove SD card

    Only once the device is fully off: press the SD card briefly, it springs out. Never remove during operation!

📂 Where is the file? The recording is on the SD card in the folder ADC/ as a file with the extension .edf. Files are numbered sequentially (e.g. AD0001.EDF, AD0002.EDF, …).

What is the EDF Format?

📄 European Data Format (EDF) – detailed explanation

EDF stands for European Data Format and is an open, standardised file format for continuous biosignals such as EEG, ECG, EMG or respiration. It was developed in 1992 by Bob Kemp and José Varela and is today the most widely used format in clinical sleep and neurophysiology research.

EDF supports multiple parallel signal channels with different sample rates – ideal for storing ECG, EEG and other sensors simultaneously in a single file, as the Traumschreiber does.

Opening the File with EDFbrowser

Download EDFbrowser

EDFbrowser is a free, cross-platform programme (Windows, macOS, Linux) for viewing and analysing EDF files. Search the web for "EDFbrowser download" and download the current version for your operating system.

  1. Launch EDFbrowser.
  2. File → Open (or Ctrl+O) and navigate to your SD card.
  3. In the folder ADC/ select the .edf file and open it. The "Add signals" dialog appears.
  4. On the left you see all channels. Which channel contains the ECG depends on which inputs the electrodes are connected to: with 3–4 electrodes typically Channel 6 and 8 (EEG Ch6 / Ch8) are active, with 8 electrodes rather Channel 1 and 3 (EEG Ch1 / Ch3). You can also simply add all eight channels one by one and see which one shows heartbeats.
  5. Click "Add signal(s)" first – the channel appears on the right in the Signal Composition. Then click "Make derivation". The signal is loaded into the main window. Repeat for each additional channel you want to check.
  6. Close the dialog with "Close".
  7. Use the mouse wheel or zoom buttons to adjust the time axis – start with a window of about 5–10 seconds to see individual heartbeats.
  8. You should now see a rhythmic waveform with the typical ECG deflections.
Add signals
/ADC/AD0105.EDF
Subject: X X X X Recording: Startdate X X X X Duration: 0:01:29
Signals in file:
1 EEG Ch1 250 Hz ← ECG-Signal
2EEG Ch2250 Hz
3EEG Ch3250 Hz
4EEG Ch4250 Hz
5EEG Ch5250 Hz
6EEG Ch6250 Hz
7EEG Ch7250 Hz
8EEG Ch8250 Hz
9Battery1 Hz
10Light1 Hz
11Button1 Hz
Signal Composition
SignalLabelFactorSamplerate
1EEG Ch1×1.000250 Hz
① Select channel 1
② Add signal(s) → Make derivation → Close
Schematic ECG – this is what your waveform should look like
P QRS T ~ 1 heartbeat
What you should see
  • P wave: Small, rounded deflection – atrial depolarisation
  • QRS complex: Sharp, large deflection – ventricular depolarisation (the heartbeat itself)
  • T wave: Broad, flat deflection – ventricular repolarisation
  • At rest: typically 60–80 beats per minute
  • The distance between two QRS complexes equals the RR interval (heart rate)
Artefacts: All power cables and electrical devices nearby can disturb the signal – especially laptop chargers, monitors and power sockets create 50 Hz interference. If the signal is heavily noisy: move away from sockets and electrical devices, measure again, and check electrode contact (pressure, skin cleaning).
🗺️ Quest
50 Hz Apartment Mapping
Find out where in your home the 50 Hz noise is strongest – and where it almost disappears.
  • 1
    Start recording

    Attach electrodes, switch on the Traumschreiber and start recording. Make sure you can move freely – electrodes and cables must stay in place.

  • 2
    Visit different locations

    Move through your home with the Traumschreiber. Pause at several spots for about 20–30 seconds each and stand still. Interesting locations to test:

    • Right next to a plugged-in laptop charger or power adapter
    • Next to the running fridge or microwave
    • Directly at a power socket / extension lead
    • Near a switched-on monitor or TV
    • In the middle of a room, far from devices
    • Outside or on the balcony (if possible)
  • 3
    Use the button as a marker

    Press the button on the Traumschreiber every time you reach a new location. This lets you see exactly in EDFbrowser when you were where.

  • 4
    End recording & analyse

    Switch off Traumschreiber, remove SD card, open the EDF file in EDFbrowser. Add an ECG channel and zoom into the different sections. Where does the signal look quiet – and where is it overlaid by regular 50 Hz ripple?

What you should see: Near strong 50 Hz sources (power supplies, sockets, screens) a steady sine wave overlays the ECG signal – 50 cycles per second are clearly visible at 250 Hz sample rate. In quiet spots without electrical devices the signal stays noticeably cleaner. The button channel shows you the exact transition points.
Level 3

Explore Signals – Button, Light & Battery

Get to know the auxiliary signals and run your first controlled experiment.

⚡ 150 XP
Recording an ECG is a start – but the Traumschreiber records much more: it knows whether you pressed the button, how bright the room was, and how full the battery was. These auxiliary signals seem minor, but they are the key to controlled experimentation: if you know when you turned the light off, you can look at exactly that point in the signal afterwards – and observe what changed. This is the transition from "making a recording" to "running an experiment".

What do 1 Hz and 250 Hz mean?

Sample Rate

The sample rate specifies how many values are recorded per second. You can see it behind each channel in EDFbrowser. The unit is Hertz (Hz), i.e. "per second", named after the Hamburg physicist Heinrich Hertz. Fun fact: Hertz was the first to experimentally demonstrate electromagnetic waves. The Hamburg TV tower is named after him.

Rate Channels Why?
250 Hz EEG Ch1–Ch8 ECG and EEG signals change very quickly. To represent them correctly, you must sample at least twice as fast as the highest relevant frequency (Nyquist theorem). At 250 Hz, frequencies up to 125 Hz can be captured – ideal for heartbeats and brainwaves.
1 Hz Battery, Light, Button Battery level, brightness and button presses change much more slowly – one value per second is perfectly sufficient and saves storage space on the SD card.

The Three Auxiliary Signals

Button 1 Hz

The button signal is digital: it only has two values – 0 (not pressed) and 1 (pressed). In EDFbrowser it initially appears as a barely visible line near the zero line.

To make it readable, use the "Fit to pane" function:

  1. Add button signal: select channel (Button) → "Add signal(s)" → "Make derivation" → "Close".
  2. In the main window click on the signal name.
  3. Then select "Fit to pane" from the menu.
  4. The signal expands to full track height – the jump from 0 to 1 when pressing is now clearly visible.
Battery 1 Hz

The battery signal stores the raw battery voltage as an ADC raw value – not a percentage. The value range depends on the charging circuit; a higher value corresponds to a higher voltage and thus a fuller battery.

Light 1 Hz

The light sensor delivers an inverted signal: the higher the value, the darker it is. In complete darkness the value is at its maximum; in bright light it falls.

High value Dark
Medium value Dim
Low value Bright

Quest

🔬 Quest
The Lights-Off Experiment
Run a controlled sequence and check afterwards in EDFbrowser whether button and light sensor recorded correctly.
  • 1
    Start recording

    Switch on the Traumschreiber – recording starts automatically.

  • 2
    Turn off the lights

    Make the room completely dark. The light signal will now take a high value.

  • 3
    Wait 20 seconds

    Stay still – the dark phase must be clearly visible in the signal.

  • 4
    Press the button

    Press the button on the Traumschreiber once. The battery charge level (0–100%) is indicated by multiple flashes. Since the light sensor is directly next to the LED, these flashes should be detectable in the light signal. The button signal jumps to 1 for that second.

  • 5
    Wait 20 seconds

    Stay still for another 20 seconds.

  • 6
    Turn on the lights

    Turn the room light back on. The light signal will now drop to a low value.

  • 7
    Wait 20 seconds

    Wait another 20 seconds so the light-on phase is recorded.

  • 8
    End recording & analyse

    Switch off Traumschreiber. Remove SD card, open the EDF file in EDFbrowser. Add channels Button and Light and apply "Fit to pane" to each.

What you should see: In the button signal exactly one brief spike to 1 – in the light signal a clear drop from a high to a low value the moment the light turned on. Also, the blinking of the battery LED (red/yellow/green depending on charge level) should be visible in the light channel as a slight fluctuation – likely somewhat irregular due to the 1 Hz sample rate.
Level 4

Signal Analysis with Python

Create time-frequency plots, learn filter basics and detect 50 Hz mains noise.

⚡ 200 XP
Why Python – and not just EDFbrowser?

EDFbrowser is great for looking at a signal. But the moment you start asking real questions – "How does my heart rhythm change as I fall asleep?", "When exactly did the 50 Hz noise stop?", "Can I count all heartbeats automatically?" – every click-interface hits its limits. Python is the tool with which scientists and engineers worldwide answer exactly these questions. And you can too.

Common concern #1

"I am not a programmer."

The script is already written – you just need to run it. Not a single character of code to type yourself. The terminal is just a text input, no different from a search engine.

Common concern #2

"I might break something."

The script only reads – it writes nothing back to your SD card. The worst consequence of a wrong input: an error message, and you try again.

Common concern #3

"It will take hours to get it running."

From zero to first plot: about 10–15 minutes. Most of that time you are waiting for the Python installer.

What awaits you at the end of this level: You run a ready-made Python script and get a colourful time-frequency plot of your own ECG recording – an image showing which frequencies are present at which time in your signal. You see with your own eyes whether and where 50 Hz mains noise appears. This is exactly the kind of analysis used in sleep and neurophysiology labs.

Python & Terminal – First Steps

Open Terminal
🪟 Windows

Press Win + X, then choose "Windows PowerShell" or "Terminal".

🍎 macOS

⌘ Cmd + Space → type "Terminal" → Enter.

🐧 Linux

Ctrl + Alt + T – or search for "Terminal" in applications.

Install Python

🪟 Windows

Download the current version from python.org/downloads. In the installer be sure to tick "Add Python to PATH".

python --version
🍎 macOS

Via Homebrew (recommended) or python.org.

brew install python3 python3 --version
🐧 Linux

Via the package manager:

sudo apt install python3 python3-pip python3 --version

Install Libraries

The script needs three libraries. Run this command once in the terminal:

pip install numpy matplotlib scipy

On macOS/Linux you may need to use pip3 instead of pip.

Help with errors: Simply paste error messages into ChatGPT or Gemini. A good starting prompt:

"I am learning Python for signal analysis with the Traumschreiber device (EDF files). The script plot_edf_tutorial.py uses Python 3 with numpy, matplotlib and scipy. I am getting this error: [PASTE ERROR HERE]. What does this mean and how do I fix it?"

Run the Script

Download the Script

The script plot_edf_tutorial.py can be here. Save the file to a folder of your choice – ideally where your EDF files are located.

Navigating in the Terminal

The terminal usually starts in the home directory. Three commands get you anywhere:

📋 List contents

Shows all files and folders in the current directory:

ls # macOS / Linux dir # Windows
📂 Change folder

Change into a subfolder:

cd Downloads cd Traumschreiber
⬆ Go up one level

Change to the parent folder:

cd ..
Example: navigate from home folder to the script
ls # what is here? cd Downloads # go to Downloads ls # see script? python plot_edf_tutorial.py meine_aufnahme.EDF
Tip: In the terminal press the Tab key to auto-complete file and folder names. Saves typing and avoids typos.

Calling the Script

Basic call – plots the first 30 seconds of channel 0
python plot_edf_tutorial.py ADC/AD0041.EDF
Select channel and start time
python plot_edf_tutorial.py ADC/AD0041.EDF --channel 0 --start 30
Parameter:
  • --channel 0 selects EEG channel 1 (0–7 possible, corresponds to EEG Ch1–Ch8)
  • --start 30 starts analysis at second 30
  • Always plots exactly 30 seconds from the start point

What does the Time-Frequency Plot show?

The three dimensions
Axis / ColourMeaningExample
X-axis Time – same as the raw signal 0–30 seconds
Y-axis Frequency in Hz – how many times per second the signal goes up and down 12 Hz = 12× up and down per second
Colour Strength of the signal at that frequency at that point in time Warm (red/yellow) = strong · Cool (blue) = weak
How is the plot computed?
  1. The 30-second signal is cut into short, overlapping windows (e.g. 2 seconds each).
  2. For each window the Fourier Transform (FFT) is computed – it "decomposes" the signal into its frequency components, producing a spectrum.
  3. Each spectrum is represented as a vertical colour column: bottom = low, top = high frequencies.
  4. All columns side by side form the two-dimensional time-frequency image.

The longer the windows, the better the frequency resolution – but the worse the time resolution. This is the fundamental time-frequency trade-off.

Example Output

Example Output von plot_edf_tutorial.py
What is shown here?

Recording of channel 0 (EEG Ch1), seconds 10–40. The signal starts with a large artefact and then transitions into a clean ECG signal.

PanelObservation
Raw Signal Seconds 10–20: the signal clips – it hits the maximum ADC range (orange filled block). This happens with strong electrode or body movement. From ~second 22 a clear ECG signal begins: regular sharp QRS spikes, about 1 per second (~60 bpm).
Time-Frequency Plot In the artefact range (10–20 s) broad energy across all frequencies – everything lights up. Clearly visible: a bright horizontal line at 50 Hz across the entire recording – this is 50 Hz mains noise from power lines and chargers. In the quiet ECG region energy concentrates at low frequencies (heart rate ~1 Hz and its harmonics).
With 0.5 Hz high-pass filter The slow baseline drift is removed – the signal is vertically centred. The artefact block itself remains (it also contains higher frequencies), but in the ECG region the spikes are more readable.
With 30 Hz low-pass filter The signal is noticeably smoother. High-frequency noise (including the 50 Hz component) is removed. The QRS spikes are preserved but lose their sharp edges. The borders of the artefact block look softer.
Toolbar buttons (bottom left of the plot window)

Matplotlib shows a toolbar with interactive tools:

🏠
Home

Reset view to original zoom

◀ ▶
Back / Forward

Jump forward and back between zoom/pan states

✥
Pan

Click & drag to move the view

🔍
Zoom

Draw a rectangle to zoom into a region

⚙
Subplots

Interactively adjust spacing between panels

💾
Save

Save plot as PNG, PDF or SVG

Example – clean ECG signal

Second example: clean ECG signal with zoom
What is shown here?

The same recording – now without artefact. The panels were zoomed to different time windows using Pan and Zoom to better compare signal properties. Each panel can be scrolled independently.

PanelObservation
Raw Signal (~29–31.5 s) Zoomed in to a few seconds with the zoom tool: clear ECG rhythm with regular QRS spikes. Between heartbeats a faint high-frequency noise is visible – this is mainly 50 Hz mains noise.
Time-Frequency Plot (10–40 s) The TF plot still shows the full 30-second overview. The bright 50 Hz line is continuously visible. From ~22 s the energy concentrates at low frequencies: the heart rate (~1.2 Hz) and its harmonics (2.4 Hz, 3.6 Hz …) form faint horizontal stripes.
With 0.5 Hz high-pass filter (~25–34 s) Comparison in the mid ECG region: left (raw) shows slight baseline drift. Right (HP-filtered) the signal sits exactly at zero – the baseline is completely flat. The QRS spikes remain the same height.
With 30 Hz low-pass filter (~33–39 s) This is the most striking difference: on the left the 50 Hz mains noise is visible as rapid ripple on the signal (the line has a "jittery" edge). On the right the low-pass filter has removed this noise – the QRS spikes stand out clearly and sharply against an almost noise-free background. This panel gives the best ECG for analysis.
Tip – zoom panels independently: After activating the zoom tool (🔍) each panel can be zoomed separately. This lets you keep a macro overview in the TF plot while examining individual heartbeats at the second level in the waveform panels. The Home button (🏠) jumps back to the full view.

Filter

0.5 Hz high-pass filter Butterworth · 5th order · sosfilt

Passes all frequencies above 0.5 Hz – blocks everything below. This removes slow drift: the signal often wanders slowly up or down due to sweating, movement or changed electrode contact. The high-pass filter straightens the baseline again without affecting the actual heartbeats (1–25 Hz).

The effect is clearly visible in the "without / with" comparison (row 3 of the plot) when the raw signal drifts significantly.

30 Hz low-pass filter Butterworth · 5th order · sosfilt

Passes all frequencies below 30 Hz – blocks everything above. Particularly important is 50 Hz mains noise: power lines, chargers and screens radiate electromagnetically at exactly 50 Hz and overlay the biosignal. In the time-frequency plot this appears as a bright horizontal line at 50 Hz (marked with white dashes).

The ECG signal contains almost no relevant information above 25–30 Hz – this range is usually muscle or mains noise with body electrodes.

Butterworth was chosen because it is maximally flat in the pass band (no ripple). sosfilt (Second-Order Sections) makes the computation numerically more stable, especially at high filter orders.

Quest

🔬 Quest
Analyse your own EDF file
Open a recording from Level 3 and answer the questions based on the four plot panels.
  • 1
    Calling the Script

    Open your Level 3 recording with --channel 0 --start 0.

  • 2
    Look for the 50 Hz line

    Is there a bright horizontal line at 50 Hz in the time-frequency plot? That would be mains noise – typical when a laptop charger or monitor is nearby.

  • 3
    Find the button event

    Use --start to jump to the moment you pressed the button in Level 3. Do you see a change in the signal?

  • 4
    Observe filter effects

    Compare row 3 (high-pass) and row 4 (low-pass): what visible difference does each filter make in your data?

  • 5
    Different time windows

    Try --start 0, --start 30, --start 60 – does the noise change over time (e.g. when devices were nearby)?

Level 5

Measure Eye Movements – EOG

Electrooculography: horizontal and vertical, detecting blinks, understanding sleep staging.

⚡ 200 XP
The EOG (electrooculogram) measures the electrical activity around the eyes – and thereby indirectly the eye movements themselves. In sleep research it is indispensable: REM sleep (Rapid Eye Movement) is detected precisely via the EOG. Each eye movement produces a clear, slow deflection in the signal – much larger and calmer than an ECG spike. This makes EOG one of the easiest and most fascinating biosignals to start with.

The Two Measurement Directions

Horizontal EOG

Measures eye movements to the left and right. The electrodes are attached to the outer corners (canthi) of both eyes. Looking left raises the signal; looking right lowers it – or vice versa, depending on polarity.

Vertical EOG

Measures eye movements up and down – and captures blinking very clearly, since the cornea rotates upward when the lid closes. The electrodes go above and below one eye.

Attaching Electrodes

H H V V Front view
H – Horizontal electrodes (both outer eye corners)

One electrode at the outer corner (lateral canthus) of each eye. The skin there is thin and sensitive – press gently. This channel shows left-right movements.

V – Vertical electrodes (above and below one eye)

One electrode directly above the eyebrow arch (just above the brow end), one on the cheekbone directly below the left eye. This channel shows up-down movements and blinks.

Traumschreiber channel assignment

Connect the horizontal electrodes to Channel 1 and the vertical ones to Channel 2 (or other channel pairs depending on the connector). Load both channels separately in EDFbrowser or with the script.

Making a Recording

  • 1
    Attach electrodes

    Gently clean the skin around the eyes. No cream or make-up. Attach electrodes as described above. Route the cable so it does not pull when moving.

  • 2
    Insert SD card, switch on

    Device switched off. Insert SD card. Switch on – recording starts immediately.

  • 3
    Perform a controlled movement sequence

    Sit still, keep the body motionless. Only move the eyes – no head wobbling, as muscle artefacts disturb the signal.

  • 4
    Switch off, remove SD card

    After the experiment switch off the device, remove SD card.

  • 5
    Analyse

    Open the EDF file with plot_exg_timedomain.py --type eog. Call both channels separately.

Quest

👁️ Quest
Controlled Eye Movement Experiment
Run a fixed sequence and check afterwards whether all movements are clearly visible in the signal.
  • 1
    10 s look straight ahead calmly

    Baseline – the signal should be flat.

  • 2
    Fast RLRLRL movements – look left and right 10 times

    Briskly and rhythmically: left – right – left – right … hold each for about 0.5 seconds. A clear, regular square-wave pattern appears in the horizontal channel. No head turning!

  • 3
    10 s pause (straight ahead)
  • 4
    5× look slowly up–down (hold 2 s each)

    Clear deflections in the vertical channel.

  • 5
    10 s Pause
  • 6
    10× blink deliberately (1 s pause between each blink)

    Blinking produces characteristic spikes in the vertical channel – much faster than eye movements.

  • 7
    Keep eyes closed for 20 s

    The signal should remain calm and low. Eye movements behind closed lids (e.g. dreaming) would be visible.

Download the Script

The script plot_exg_timedomain.py can be downloaded here. Place it in the same folder as the EDF file.

Analysis: python plot_exg_timedomain.py FILE.EDF --type eog --channel 0 for the horizontal channel, --channel 1 for vertical. In the zoom panel (5 s) individual eye movements are clearly visible as slow curves. Blinking appears as a sharp, brief spike.
Level 6

Measure Brainwaves – EEG

F3–F4 at the hairline, alpha and beta band, relaxation vs. cognitive load.

⚡ 300 XP
EEG (electroencephalogram) is the most direct window to brain activity measurable from the outside without surgery. The signal is weak – about 10–100 microvolts, 100 times quieter than the ECG – but the Traumschreiber is sensitive enough. What you will measure: frontal brainwaves (F3–F4), which oscillate clearly in the alpha band (8–13 Hz) during relaxation and shift to the beta band (13–25 Hz) during mental tasks. This difference is visible to the naked eye in a good time-frequency plot.

EEG Frequency Bands

What do the bands mean?
BandFrequencyTypical during
Delta0.5–4 HzDeep sleep, deep relaxation
Theta4–8 HzDrowsiness, creative thinking, meditation
Alpha8–13 HzRelaxation with closed eyes, calm wakefulness
Beta13–30 HzActive thinking, concentration, cognitive load
Gamma> 30 HzHigh-frequency processing (hard to measure with skin electrodes)

Attaching Electrodes

Nose A1 A2 Cz Fp1 Fp2 F3 F4 ≈ Hairline Top-down view
F3 – Left frontal electrode

About 3 cm left of the centre of the forehead, as close to the hairline as possible – but do not stick into the hair. Rub the skin there with a cloth. Move any hair out of the way.

F4 – Right frontal electrode

Mirror position to F3, about 3 cm right of the forehead centre. Both electrodes should sit at the same height – use the hairline as a guide.

Important notes
  • No hairspray, no cream on the forehead
  • Do not stick electrode on hairy skin
  • The Traumschreiber has no separate reference electrode – the measurement is purely differential between the two attached electrodes
  • Do not frown or raise eyebrows during recording – this creates muscle artefacts

Making a Recording

  • 1
    Attach electrodes, check cable

    Attach F3 and F4 as described above. Route the cable so there is no tension.

  • 2
    Insert SD card, switch on

    Recording starts immediately after switching on.

  • 3
    Sit still, close eyes – wait 30 s

    The EEG signal needs some time to stabilise. Use the first 30 seconds as a settling period.

  • 4
    Run the experiment sequence

    Exactly following the quest plan below – timing is important for the analysis.

  • 5
    Switch off, analyze

    Use plot_eeg_timefreq.py to select the channel where F3 or F4 is. The script shows the Beta band (13–30 Hz) over 120 s by default and automatically smooths the spectrogram with a median filter.

Quest

🧠 Quest
Relaxation vs. Cognitive Load
Run the following sequence and observe in the time-frequency plot (beta band, 13–30 Hz) how beta power increases during cognitive load – the spectrogram becomes warmer.
  • 1
    20 s Relaxation

    Eyes closed. Think of nothing in particular. Breathe. → Beta band is weak, spectrogram stays cool (blue-purple).

  • 2
    20 s Cognitive Load

    Count backwards from 700 in steps of 7: 700 → 693 → 686 → 679 … Eyes can be open or closed. Work with concentration – do not stop! → Beta power rises, spectrogram becomes warmer.

  • 3
    20 s Relaxation

    Let go again, eyes closed, stop counting.

  • 4
    20 s Cognitive Load

    Continue counting from where you stopped – or start again.

  • 5
    20 s Relaxation

    Final relaxation phase.

Download the Script

The script plot_eeg_timefreq.py can be downloaded here. Place it in the same folder as the EDF file.

Analysis: python plot_eeg_timefreq.py FILE.EDF --channel 0 --duration 120
The script shows the Beta band (13–30 Hz) by default. During relaxation phases colours stay cool (blue-purple); during counting phases they brighten (yellow-orange) – that is the beta rise. If it does not work on F3, try F4 (--channel 1 or whichever channel F4 is on).
Parameter overview
ParameterDefaultMeaning
--channel / -c0Channel index (0 = channel 1)
--start / -s0.0Start time in seconds
--duration / -d120Analysis window in seconds
--median / -m11Horizontal median filter in seconds (0 = disabled)
--median-freq1.0Vertical median filter in Hz (0 = disabled)

Example: choose a different start point and longer window:
python plot_eeg_timefreq.py FILE.EDF --channel 0 --start 60 --duration 180

Example Plot

Recording with the Traumschreiber – 100 s relaxation followed by 100 s online chess against the clock (active cognitive load). Channel 5 (Ch6), F3–F4 position.

Example EEG Time-Frequency Plot: Relaxation vs. Cognitive Load (Online Chess)

What you see:
The spectrogram (lower panel, 13–30 Hz) shows the beta band over time. In the first half (~100–200 s, relaxation) the colour is predominantly cool (blue-purple) – little beta activity, the brain is in rest mode. From ~200 s the chess phase begins: colours shift to warm (yellow-orange-red), signalling markedly elevated beta power – the frontal network is working at full speed under time pressure. The upper panel shows the filtered EEG raw signal; amplitude alone reveals little – the frequency content in the spectrogram is what is actually interesting.

Level 7

Measure Muscle Activity – EMG (Chin)

Electromyography at the chin: masseter, jaw clenching, sleep EMG.

⚡ 150 XP
EMG (electromyogram) measures the electrical activity of muscles. It is the loudest biosignal – a tensed chewing muscle produces signals clearly above the ECG level. This makes EMG particularly beginner-friendly: you see something immediately. The chin EMG (musculus mentalis) is standard in sleep research because muscles almost go limp in REM sleep – this drop to zero is a reliable REM indicator.
EMG Signal high-frequency · 20–200 Hz

Unlike ECG or EEG, the EMG does not consist of individual, regular deflections but of a high-frequency, irregular noise that gets stronger when the muscle is active – and drops almost to zero when relaxed. In the time domain one sees thicker, denser bursts during activity, and an almost flat line at rest.

Attaching Electrodes

1 2 Chin (Mentalis)
Electrode 1 & 2 – Chin (Musculus mentalis)

Two electrodes placed horizontally side by side on the chin, about 2 cm apart. The centre of the chin (slight protrusion, dimple region). Rub the skin thoroughly beforehand – the chin often has some oil/cream.

Other muscles to try
  • Forearm flexor: Electrodes on the forearm (middle inner side) – clear EMG burst pattern when making a fist
  • Temporalis: Electrodes over the temple – responds to chewing and jaw clenching
  • Forehead (Frontalis): Over the forehead – responds to frowning

Making a Recording

  • 1
    Attach electrodes

    Two electrodes on the chin as above – clean and dry. Route the cable upward, not pulling on the jaw.

  • 2
    Insert SD card, switch on

    Recording starts immediately.

  • 3
    Run the experiment sequence

    Sit still. Keep the jaw relaxed. Avoid movement artefacts from head movements.

  • 4
    Switch off, analyze

    plot_exg_timedomain.py --type emg – the bandpass (20–120 Hz) filters everything except the actual muscle signal.

Quest

💪 Quest
Jaw Clench Experiment
Create a clear pattern of tension and relaxation and observe how the EMG channel responds.
  • 1
    10 s jaw fully relaxed

    Mouth slightly open, no teeth clenching. → flat signal.

  • 2
    5 s clench jaw firmly

    As hard as possible. → strong, dense EMG burst pattern.

  • 3
    10 s relax
  • 4
    5 s clench
  • 5
    10 s relax
  • 6
    3× chew quickly (as when eating)

    Short, rhythmic EMG bursts – each chewing cycle visible as a separate burst.

  • 7
    10 s relaxation, then switch off
Download the Script

The script plot_exg_timedomain.py can be downloaded here (also usable for EOG and ECG, just adjust --type).

Analysis: python plot_exg_timedomain.py FILE.EDF --type emg --channel 0
In the zoom panel you can see how the signal becomes noticeably wider and denser during jaw clenching (more motor units firing). At rest the curve is almost flat. Chewing cycles appear as regularly recurring activity bursts.
Level 8

First Computations – ECG & HRV

Automatically detect heartbeats, compute heart rate variability, understand and modify code with AI assistance.

⚡ 350 XP
So far you have been looking at signals. In this level the actual computing begins: a script independently detects every heartbeat in your recording, measures the intervals between them and computes heart rate variability (HRV) – a metric used in medicine, sport and sleep research as an indicator of recovery and stress. This is not magic, but pattern recognition in the signal – and you see the complete code for it.

What is HRV?

Heart Rate Variability – the four metrics in the script
MetricWhat is measured?Typical range (at rest)
Heart RateMean beats per minute from all RR intervals55–80 bpm
SDNNStandard deviation of all RR intervals – overall variability over the time window30–100 ms
RMSSDRoot mean square of successive RR differences – short-term variability, parasympathetic index20–80 ms
pNN50Proportion of adjacent RR intervals differing by more than 50 ms5–40 %

The RR interval (also R-R or NN) is the time between two successive R peaks in the ECG – i.e. between two heartbeats. A healthy heart does not beat at a perfectly constant interval but with measurable variability: this variability is a sign of active nervous regulation and has been shown in studies to predict recovery state, stress level and cardiovascular health.

Example Plot

This is what a good ECG from the Traumschreiber looks like – recorded at rest (sitting, holding breath for a cleaner baseline). R peaks are detected automatically (red dots), the HRV metrics bottom right are computed directly from the RR intervals.

Example ECG plot: heartbeat detection and HRV metrics with the Traumschreiber

Channel 7 (Ch8), 30 s, sitting, breath held – 48 heartbeats detected, HR 95 bpm, SDNN 80.8 ms

Quest

❤️ Quest
Heartbeat Detection on Your Own Recording
Run the script on an ECG recording from Level 2 and read off your personal HRV metrics.
Download the Script

The script plot_ecg_hrv.py can be downloaded here. Place it in the same folder as the EDF file.

  • 1
    Open terminal and change folder

    As described in Level 4. Navigate to the folder with the EDF file and place the script there.

  • 2
    Run the Script

    python plot_ecg_hrv.py ADC/AD0041.EDF (adjust filename). The script immediately prints heart rate, SDNN, RMSSD and pNN50 to the terminal – before the window opens.

  • 3
    Check plot: are the red dots on the R peaks?

    Panel 1 shows the ECG with each detected heartbeat as a red dot. If dots are misplaced or missing: try another channel (--channel 5 or --channel 7), or adjust --start to target quieter signal sections.

  • 4
    Read the RR tachogram

    Panel 3 shows how the heartbeat interval changes over the 30 seconds. Is the curve calm and steady? Or are there jumps? Jumps arise from artefacts or genuine rhythm changes (e.g. breathing variation).

What you should see: In the zoom panel (panel 2) every individual QRS spike is clearly visible – with a red marker sitting directly above it. The RR tachogram fluctuates slightly with breathing frequency (respiratory sinus arrhythmia): the heart speeds up minimally on inhale and slows down on exhale. This effect is well visible when sitting quietly.
🤖 Quest
Have the Code Explained by an AI
You do not need to understand code yourself – but you can ask an AI. This is a core skill in modern scientific work with code.
  • 1
    Copy code to clipboard

    Click the button below. The script plot_ecg_hrv.py will be loaded together with a prepared explanation prompt into your clipboard.

  • 2
    Open ChatGPT or Gemini

    In browser: chatgpt.com or gemini.google.com – both are free to use without sign-up (ChatGPT) or with a Google account (Gemini).

  • 3
    Paste and send

    Start a new chat. Click the input field, press Ctrl+V (Windows/Linux) or Cmd+V (macOS). Then Enter / Send.

The button copies this prompt + the complete code:

I am new to programming and learning Python. I use a biosignal device called Traumschreiber that records ECG signals. I have a ready-made Python script (plot_ecg_hrv.py) that automatically detects heartbeats and computes heart rate variability (HRV). Please explain the following in simple terms, assuming no prior knowledge: 1. What does the function detect_r_peaks() do? How does find_peaks work? 2. What do SDNN and RMSSD mean – and why are they calculated? 3. What happens step by step in compute_hrv()? 4. What is an RR interval and why is it interesting? Here is the complete code: [Code will be appended automatically]
Tip: If the explanation is too complex, reply to the AI: "Please explain that again as if I had never programmed before, in simpler sentences." You can ask follow-up questions at any time – the AI forgets nothing within a conversation.
✏️ Quest
Modify the Code Yourself – First Own Modification
You ask the AI what to change – then make the change yourself in a text editor. No terminal, no IDE, as simple as possible.

The script contains a few easy-to-change variables at the top. Two good starter modifications:

Option A

Change the ECG line colour. In the script there is a line ORANGE = '#ff9151'. The code next to it is a hexadecimal colour value. Change it to another colour – e.g. light blue ('#00ccff') or white ('#ffffff').

Option B

Extend the analysis window. The line WINDOW_S = 30 defines how many seconds are analysed. Change 30 to 60 – then 60 seconds are evaluated and you get more heartbeats and more stable HRV values.

Step by step: making the change with AI help

  • 1
    Ask the AI what to change

    In the already open AI chat (from Quest 2) write: "I want to change the ECG line colour to light blue (#00ccff). Show me only the one line I need to change and how it should look afterwards."
    The AI will show you exactly the line – e.g. ORANGE = '#00ccff'.

  • 2
    Open a text editor – depending on operating system

    Important: No Word, Pages or similar office programmes – these insert invisible formatting that destroys the code. Only use plain text editors:

    🪟 Windows
    1. Press the Windows key
    2. "Notepad" type → Enter
    3. In Notepad: File → Open
    4. Bottom right at file type: select "All Files (*.*)"
    5. Navigate to plot_ecg_hrv.py, open it
    🍎 macOS
    1. Cmd+Space → "TextEdit" → Enter
    2. In TextEdit: top menu Format → Make Plain Text (Cmd+Shift+T)
    3. File → Open
    4. Navigate to plot_ecg_hrv.py, open it
    🐧 Linux
    1. Open file manager
    2. Right-click on plot_ecg_hrv.py
    3. "Open with Text Editor" or "Open With"
    4. Choose gedit / Mousepad / Kate
  • 3
    Find the line

    Ctrl+F (Windows/Linux) or Cmd+F (macOS) opens the search in the text editor. Type ORANGE → Enter. The editor jumps to that line. You see: ORANGE = '#ff9151'

  • 4
    Make the change

    Select the colour value '#ff9151' and replace it with the new one – e.g. '#00ccff'. Only change the value inside the quotation marks, do not remove the quotation marks themselves.

  • 5
    Save

    Ctrl+S (Windows/Linux) or Cmd+S (macOS). The text editor should save the file as .py – not as .py.txt. If Windows appends .txt: File → Save As → set file type to "All Files" and explicitly enter plot_ecg_hrv.py as the name.

  • 6
    Run the script again

    Back to the terminal. Same command as before – the window opens again, this time with the ECG line in the new colour. Congratulations: you have successfully modified your first Python code.

Error after the change? No panic. Read the error message in the terminal – ask the AI to explain it: "I changed plot_ecg_hrv.py and now I get this error: [paste error]. What did I do wrong?" Typical cause: a quotation mark was accidentally deleted or the colon after the variable name. The AI finds this in seconds.
Level 9

Sleep Staging – Automatic AI Analysis

Record full night, automatically divide into sleep stages using AnySleep model.

⚡ 400 XP
Sleep Staging means: Automatically dividing an EEG recording into sleep stages — Wake, N1, N2, N3, and REM. This is a central task in sleep research. Scoring a full night by hand takes hours; a trained AI model now does it in minutes with performance comparable to human scorers. The AnySleep model [Grieger et al., 2025] was trained on millions of real patient data and can analyze frontal EEG electrodes (like F3–F4 on Traumschreiber) directly.

Sleep Stages and Their Characteristics

The 5 Sleep Stages
Sleep StageEEG PatternSignificance
WakeFast, rhythmic (8–13 Hz, Alpha)Awake, at rest with eyes closed
N1Slower, Theta (4–8 Hz)Sleep onset, light sleep
N2Spindles, K-complexes (12–15 Hz)Light to moderate sleep
N3Slow, Delta (0.5–4 Hz), high amplitudeDeep sleep, recovery and regeneration
REMFast, similar to Wake, eye movementsParadoxical sleep, "vivid" dreams

Prerequisites

Installation

Python 3.10+ with PyTorch (the CPU version is sufficient and much smaller). Install required packages:

pip install torch --index-url https://download.pytorch.org/whl/cpu pip install numpy scipy matplotlib

Then download two Python files:

Note: The AI model (~12 MB) will be downloaded and cached automatically on first run. After that everything works offline.

Everything in one place on GitHub: script, installation guide, an explanation of the data format and screenshots are in the repository Traumschreiber_Python_Offline-Data-Analysis.

Recording

Electrode Placement & Timing

Placement as described in Level 6 (Brain Waves – EEG): F3 and F4 at the hairline. For meaningful sleep analysis, record for at least 6–8 hours (a full night).

  1. Attach electrodes (F3–F4 as in Level 6)
  2. Insert SD card, power on device
  3. Go to sleep and sleep
  4. Power off device, remove SD card

Quest

🌙 Quest
Record and analyze a full night
Record a complete night with Traumschreiber, take the BDF file from the ADC/ folder of the SD card (e.g. AD0021_20261020_2351.BDF), and run sleep staging with AnySleep.
Analysis

Basic command:

python plot_sleep_scoring.py NIGHT.BDF --channel 0

The script reads the recording, performs AI-based classification, and opens a window with 6 panels: probabilities (hypnodensity), hypnogram, spectrogram, battery & light, raw-signal window, and sleep statistics. Both EDF and BDF are read — the format is detected from the file itself, not from its extension.

Which channel? Only channels with electrodes connected carry EEG. If you are unsure, run the script once per channel and compare the spectrograms: a good channel shows a band of sleep spindles at 12–14 Hz in N2 sleep and several sleep cycles in the hypnogram. A channel without skin contact looks the same all night and stays at a few µV in the raw signal.

Looking into the raw signal (interactive)

Clicking the probability, hypnogram, spectrogram, or battery/light panel loads that moment as a raw trace into the bottom panel — filtered, in µV. From there you navigate by keyboard:

KeyEffect
← / →10 s back/forward (with Shift: a full window)
↑ / ↓Amplitude scale, ±25 µV to ±1000 µV
+ / −Window width: 10 / 20 / 30 / 45 / 60 / 90 s

The raw panel is ruled like clinical EEG paper: a fine line every second, a stronger one every 5 s. Top right shows the time within the recording, the window width and the amplitude scale. The orange line in the upper panels marks where in the night you currently are.

Parameters
ParameterDefaultMeaning
--channel / -c0EEG channel (0–7)
--modelautoPath to anysleep-run1.pth (optional)
--start / -s0.0Start time in seconds (for debugging)
--duration / -d-1Analysis duration in seconds (-1 = entire file)
--fmax30Spectrogram upper frequency in Hz (5–60)
--save—Save the plot as PNG instead of showing it interactively

Example: Analyze from second 3600 (1h) for 14400 seconds (4h):
python plot_sleep_scoring.py NIGHT.BDF --channel 0 --start 3600 --duration 14400

Note on computation time: AI inference on CPU takes between about 30 seconds and 3 minutes for a full night, depending on your computer. The first run downloads the model (~12 MB) — this is a one-time operation.

Example Output

Example output from plot_sleep_scoring.py: full night with probabilities, hypnogram, spectrogram, battery and light, raw signal, and statistics
What you see in this example

A real recording with the Traumschreiber TS2607: 9.1 hours of night from 23:49, 1090 epochs of 30 s each, channel 2 (forehead electrodes). In the raw-signal window a moment of N2 sleep after 1:25 h is selected. Click the image to enlarge. All 6 panels share the same time axis:

PanelWhat to see
Probabilities (hypnodensity) The stacked color areas sum to 1.0 per epoch — they show the model's confidence for each sleep stage. In clear N3 deep sleep you see mostly orange; in REM magenta dominates. In this example the first ~5.5 hours are clearly structured with alternating NREM and REM blocks; after that more Wake (light blue) and many short transitions — typical morning fragmentation.
Hypnogram The final classification (the most likely stage per epoch) as a step plot. Y-axis from bottom to top: N3 → N2 → N1 → REM → WAKE. In this example you see several NREM-REM cycles of about 90 minutes; deep sleep (N3) only occurs in the first half of the night.
EEG Spectrogram (0–30 Hz) Frequency content of the EEG over time. X = time (h), Y = frequency (Hz), color = log10(Power). Warm colors at the bottom (0.5–4 Hz) = Delta waves, typical of N3. The light green band at 12–14 Hz is sleep spindles and marks N2 sleep. Vertical bright stripes are movements. With --fmax 60 you also see muscle activity and the gap of the 50 Hz notch filter.
Battery & light Green: battery charge in percent, computed exactly as in the sd20 App (here from just over 90 % to just over 50 % during the night). Light blue: the ambient light sensor, upwards = brighter. You see when the light was off and when the morning came — here from about 8 hours after the start.
Raw-signal window A white panel with a thin black trace — the unaveraged EEG at the spot you clicked, in µV. This is where you see what the classification rests on: sleep spindles (short 12–14 Hz bursts in N2, clearly visible in the example), delta waves (slow and high-amplitude in N3), or the artefacts that spoiled an epoch — in the example on the far right. ← / → scroll through the night second by second without losing the overview above.
Sleep Statistics & Stage Breakdown Classical sleep metrics (TIB, TST, SOL, WASO, SE, RL, AW) and division into sleep stages. Mini-boxplots compare your value to normal ranges of healthy adults (25–45 years, meta-analyses): green = within ±1σ (typical range), yellow = within ±2.5σ (still normal), red = outside (abnormal).
Specific findings from this night
MetricValueAssessment
Total sleep time (TST)7:44 h● Normal (norm 7±1 h)
Sleep onset latency (SOL)0:16 h● Normal (norm 15±12 min)
Sleep efficiency (SE)85.2 %● Within range (norm 87±8 %)
WASO1:04 h● Elevated (norm 30±25 min)
REM latency (RL)0:34 h● Short (norm 85±35 min)
N1 percentage19.9 %● Clearly elevated (norm 5±3 %)
N2 percentage46.9 %● Normal (norm 50±7 %)
N3 percentage7.3 %● Rather low (norm 17±8 %)
REM percentage25.8 %● Normal (norm 22±5 %)
Awakenings (AW)47● Strongly elevated (norm 8±5)

Conclusion: Enough sleep, regular NREM-REM cycles and REM in a normal proportion. What stands out are the many awakenings and the high N1 share: the second half of the night from about hour 5.7 is strongly fragmented, clearly visible in the hypnogram. Deep sleep is on the low side. Keep in mind: the model was trained on sleep-lab data, and single short wake epochs (e.g. from movement) quickly count as awakenings.