IntoMindLearn

Lab 5 · Middle school

Mind-Controlled Microcontroller

Put one program on a small board, and it switches its light by itself while your custom AI head reads On. Can it work with no computer in the room?

Get ready

You need

  • An IntoMind One with your custom AI head on it, charged, with its cable unplugged
  • A Raspberry Pi Pico 2 W. A Pico 2 without the W has no Bluetooth.
  • A micro USB cable that carries data, and a computer
  • A USB charger for the board
  • A clean microfiber, soft cotton or eyeglass cloth

Roles

Wearer
Wears the IntoMind One, and holds On or Off.
Builder
Puts the program on the board, and plugs it in.
Recorder
Writes down what the board's light does.
Skeptic
Watches: does the light follow the wearer, or something else?

Take turns, so everyone who wants to can be the wearer. In a group of three, the builder is the skeptic too.

Rules

  • Unplug the IntoMind One's cable before anyone puts it on. The board's own cable is fine.
  • Wearing it is your choice. Every role is a real one.
  • The board's pin gives only 3.3 volts: enough for an LED or a signal, and never connected to anything that plugs into a wall.
  • Wipe the electrodes between wearers with the soft cloth, since a rough one can scratch their gold coating.

Steps

  1. Put your custom AI head on

    Open the Mind-Controlled Light Switch demo, connect your IntoMind One, press Install a saved head, and choose the wearer's file. The demo puts the head on your IntoMind One, and runs it. Without a saved file, teach a new one, and run it.

    Then close the tab, so your IntoMind One is free to talk to the board, and switch it off until step 3.

    You should seeThe board drawn on the demo lighting up while the wearer holds their On thought.

  2. Put the program on the board

    Download the program from the Mind-Controlled Microcontroller guide: one file holds all of it. Hold the white BOOTSEL button on the board while you plug it into the computer, then let go. Drag the file onto the drive that appears. When the board's light blinks once a second, unplug the board until step 3.

    You should seeA drive named RP2350 that closes by itself. Then the board's light blinking once a second, while it looks for your IntoMind One.

  3. Connect your IntoMind One to the board

    PredictAfter I start my On thought, the light will come on about seconds later.

    When your teacher calls your group, plug the board back in, and switch on your IntoMind One, unplugged. The wearer puts it on where your custom AI head was taught: the back of the head, a little above the bump where the skull meets the neck. The first time, the board pairs with it, and remembers it after that.

    You should seeThe light stop blinking. Then it comes on a few seconds after you start your On thought, and goes off a few seconds after you rest.

  4. Read the light

    The board's light says what the program is doing. While you wear it, you should see only the first two kinds. The others are warnings: they are here so you can read them if they happen. Don't make them happen.

    What the light didWhat it meansDid you see it?
    One short blink a secondLooking for your IntoMind One
    Off, and onYour custom AI head reads Off, or On
    Two short blinks a secondYour IntoMind One is on its charger, and sends no EEG
    Three short blinks a secondNo custom AI head is installed
    Fast blinkingThe last reading had a gap in the signal, so the board skipped it

    You should seeOne blink a second while the board looks, then off and on while you wear it. You may see none of the warnings, and that is a result to record too.

  5. Take the computer away

    Unplug the board from the computer, and plug it into a USB charger instead. It finds your IntoMind One by itself.

    Take turns. Before each wearer, unplug the board, so your IntoMind One is free. Put the wearer's head on it as in step 1, close the tab, and plug the board back in.

    You should seeThe light following the wearer's custom AI head, with no computer anywhere in the path.

What happened

Your custom AI head runs on your IntoMind One, not on the board. Every few seconds, the IntoMind One sends the board one number, the score: near 0 for Off, near 1 for On, and sometimes a little outside. The board compares it with 0.5. Above, it switches its light on. Below, off.

They talk over Bluetooth, with no computer between them. When they first connected, they paired: they set up secret keys, so anyone who only listens in can't read what passes between them.

The board's light could be anything its pin switches on: another LED, or a signal into a robot's own controller. That is how a brain-computer interface reaches the real world.

Simulated The custom AI head's score, where it falls against 0.5, and the light. The IntoMind One works out the score. The board compares it with 0.5, and switches the light.

Talk about it

  1. Where is the decision On or Off made: on the board, or on your IntoMind One?

  2. What else could the board's pin switch on, instead of a light?

  3. Who could a board like this help?

Lab 5 · High school

Mind-Controlled Microcontroller

Program a small board to follow your custom AI head, and to switch a circuit you built. With no computer in the loop, how long does a change of mind take to reach the pin?

Background

Read it the night before.

Who does what

Your IntoMind One does the hard part. For every four seconds of your EEG, it runs the encoder and your custom AI head on its own chip, and sends one number over Bluetooth: the score, near 0 for Off and near 1 for On, and sometimes a little outside.

The board does the rest. It compares each score with 0.5, and switches its light and its pin. Once the program is on the board, no computer is needed.

Simulated Four seconds of EEG, then the encoder and your custom AI head on the IntoMind One's chip. The score goes to the board, which lights its light while the score is above 0.5.

The program

The program is one file of MicroPython. At its top are three settings, then two functions that are yours to change.

on_switch(on) runs when the decision changes: True for On and False for Off, and losing the link to your IntoMind One counts as Off. on_reading(score, clean) runs for every reading, with the score and whether the signal behind it was clean.

The rest of the file finds your IntoMind One, pairs with it the first time, asks it for scores, and runs the board's light, which shows what the program is doing.

The board's light Its six patterns, a second of each. While you wear it, you should see only one blink a second, then off and on. The others are warnings, here so you can read them. Don't make them happen.

Why the light lags

Each reading is four seconds of EEG, and its score comes once the reading has ended. When you switch, the reading under way holds some of each state, so its score falls in between, and the light often waits for the next reading.

So the delay depends on where in a reading you switch.

Simulated Your EEG in four-second readings, gray for Off and orange for On, with each reading's score under it. The light comes on with the first score above 0.5. Switch at another moment, and the delay changes.

Get ready

You need

  • An IntoMind One, charged, with its cable unplugged
  • A Raspberry Pi Pico 2 WH with the IntoMind MicroPython firmware, and a micro USB cable that carries data
  • A computer with a MicroPython editor: Thonny, or Viper IDE on a Chromebook
  • Your circuit from Microcontrollers and circuits: a breadboard, an LED, a 330 ohm resistor and two jumper wires
  • A USB charger for the board, and a stopwatch
  • A clean microfiber, soft cotton or eyeglass cloth

Roles

Wearer
Wears the IntoMind One, and switches between Off and On when the recorder calls.
Programmer
Puts the program on the board, and changes it.
Recorder
Calls the switches, and times the light.
Skeptic
Watches the wearer and the light. Does the light follow the wearer, or something else?

Take turns, so everyone who wants to can be the wearer. In a group of three, the programmer is the skeptic too.

Rules

  • Unplug the IntoMind One's cable before anyone puts it on. The board's own cable is fine.
  • Wearing it is your choice. Every role is a real one.
  • The board's pin gives 3.3 volts. Projects stay with it, and nothing on it ever plugs into a wall.
  • Have every circuit checked before the board is plugged in.
  • Wipe the electrodes between wearers with the soft cloth, since a rough one can scratch their gold coating.

Steps

  1. Put your custom AI head on

    Open the Mind-Controlled Light Switch demo, connect your IntoMind One, press Install a saved head, and choose the wearer's file. The demo puts the head in slot 2 on your IntoMind One, and runs it. Without a saved file, teach a new one, and run it.

    Then close the tab, so your IntoMind One is free for the board, and switch it off until step 3.

    You should seeThe board drawn on the demo lighting up while the wearer holds On.

  2. Put the program on the board

    # Where the Mind-Controlled Light Switch demo installs your custom AI head.
    HEAD_SLOT = 2
    # A reading above this means On, the same line the demo draws.
    SWITCH_THRESHOLD = 0.5
    # The start of your IntoMind One's name, like "Ada's", to choose one among
    # several. Empty takes the one heard most strongly.
    DEVICE_NAME_PREFIX = ""

    Download the program. Plug the board into the computer, and open your editor. Save the program on the board as main.py: in Thonny, open it, choose Save as, then Raspberry Pi Pico. In Viper IDE, drop it onto the board's files, and rename it. The board runs main.py whenever it has power.

    The settings at its top are the slot your head is in, the line a score must cross to read On, and the start of your IntoMind One's name, if your teacher named them.

    You should seemain.py among the board's files in your editor.

  3. Connect your IntoMind One to the board

    Looking for your IntoMind One.
    Found IntoMind One. Connecting.
    Running your custom AI head.
    Reading 0.14
    Reading 0.09
    Reading 0.83

    The wearer puts the IntoMind One on at the site where the head was taught, the same way around. A head learned that site's signal, and at another site the same state makes a different one.

    When your teacher says, switch your IntoMind One on, keep the board beside it, and press Ctrl-D in the editor to restart the board. The first time, the board pairs with your IntoMind One, and it remembers it after that.

    You should seeThe board's light blinking once a second while it looks, then off, and on while the wearer holds On. The editor shows each reading's score, every few seconds.

  4. Time it

    PredictAfter I switch to On, the light will come on about seconds later.

    The recorder calls five switches to On, and times each one, from the call to the light coming on. After each, the wearer goes back to Off until the light goes off.

    CallSeconds to the lightDid the light follow?Skeptic's notes
    1
    2
    3
    4
    5

    You should seeDelays of several seconds, and not the same each time.

  5. Light your own LED

    Unplug the board, and check your circuit: from pin 20, which is GP15, through the 330 ohm resistor and the LED to ground on pin 18, with the LED's longer leg toward pin 20. Have it checked, then plug the board back in.

    In main.py, remove the # from the two lines marked for the pin: pin = Pin(15, Pin.OUT, value=0), and pin.value(on) in on_switch. Save, and press Ctrl-D.

    You should seeYour LED following your custom AI head, with the board's own light.

  6. Make it yours

    pin = Pin(15, Pin.OUT, value=0)
    
    def on_switch(on):
        pin.value(on)
    
    def on_reading(score, clean):
        pass

    Change what happens. Count your switches to On, and print the count. Light your LED only when the score is above 0.8. Print a row of # signs as long as the score, for a graph in the editor. Or plan something of your own.

    Keep both functions quick: a sleep inside one pauses the whole program, the board's light included. When it works, keep a copy: save main.py on the computer too.

    You should seeYour project doing what you wrote, each time you save and press Ctrl-D. A mistake shows in the editor, with the line it is on.

  7. Take the computer away

    Unplug the board from the computer, and plug it into the USB charger. It runs main.py by itself, and finds your IntoMind One.

    Take turns. Before each wearer, unplug the board, so your IntoMind One is free. Put the wearer's head on it as in step 1, close the tab, and plug the board back in.

    You should seeYour project following each wearer's custom AI head, with no computer in the path. With no editor to print to, the board's light tells you what the program is doing.

  8. Remove it, if your teacher asks

    Your custom AI head stays on your IntoMind One until it is removed or replaced. When your teacher wants the device clear, unplug the board, then open the Light Switch demo, connect, and press Remove it from your IntoMind One.

    You should seeRemoved. Your IntoMind One holds no custom AI head in slot 2.

Work it out

Work it outOur median delay, the middle of the five in order: . That is about four-second readings.

Talk about it

  1. on_switch runs only when the decision changes, and on_reading runs for every reading. Which would you use to count how many times you switched to On? Why?

  2. A reading with a gap in its signal changes nothing, and the light blinks fast instead. Why is that a good rule?

  3. Your five delays weren't the same. Give two reasons.

  4. Why must your project stay with the board's own 3.3 volts?

Sources

Raspberry Pi Ltd. Raspberry Pi Pico 2 W documentation.

The demos' source, github.com/intomind/demo: the program in micropython/mind_controlled_microcontroller.py.

The IntoMind MicroPython repository, github.com/intomind/micropython.

Lab 6 · College

Mind-Controlled Microcontroller

Close the loop on a board you program. How long does a change of mental state take to reach its pin, how much of that is the four-second window, and does your budget predict the rest?

Background

Read it before the lab.

The program

One MicroPython file, mind_controlled_microcontroller.py, in the demos' source. It scans for an IntoMind One, pairs the first time and reconnects with the bond after that, selects the head in slot 2, starts the stream, and turns predictions on. Each prediction carries the head's output for one four-second window: the program compares it with SWITCH_THRESHOLD, 0.5, drops any reading whose window had a gap, and counts the link lost after 20 seconds without a reading.

It is a small state machine, and the board's light shows its state. Two functions are yours: on_switch(on), when the decision changes, and on_reading(score, clean), for every reading.

The board's light Its six patterns, a second of each: the program's states. While you wear it you should see only the first and then off and on. The others are warnings, explained, not to be made.

A model of the delay

The IntoMind One sends a reading every four seconds. Suppose a reading's score passes 0.5 once more than half of it is On. A call that falls at a random moment in a reading is then answered when that reading ends, if the call came in its first half, or when the next one ends: between 2 and 6 seconds later, spread evenly, a mean of 4 and a standard deviation of 4/√12, about 1.15. Everything else, the model on the chip, the link, the program and the pin, adds a delay δ on top.

Timing by hand adds the people: the wearer reacting to the call, and the operator to the light.

Simulated EEG in four-second readings, gray for Off and orange for On, each with its score. The light comes on with the first score above 0.5. Switch at another moment, and the delay changes.

Hypothesis

Write it from your latency budget, before anyone connects.

HypothesisThe mean delay from a call to the pin will be about , with a spread of about , and δ, everything after the window, about .

Get ready

You need

  • An IntoMind One, charged, with its cable unplugged, and the wearer's saved head
  • A Raspberry Pi Pico 2 WH with the IntoMind MicroPython firmware, and a micro USB cable that carries data
  • A computer with a MicroPython editor: Thonny, or Viper IDE on a Chromebook
  • The LED circuit, a USB charger, and a stopwatch
  • A clean microfiber, soft cotton or eyeglass cloth

Roles

Wearer
Wears the IntoMind One, and switches when the operator calls.
Operator
Programs the board, calls the switches and times the pin's LED.
Analyst
Writes down each delay, and keeps the board's log.

Rules

  • Unplug the IntoMind One's cable before anyone puts it on. The board's own cable is fine.
  • Wearing it is your choice. Every role is a real one.
  • The pin gives 3.3 volts: projects stay with it, nothing on it plugs into a wall, and every circuit is checked before power.
  • Wipe the electrodes between wearers with the soft cloth, since a rough one can scratch their gold coating.

Procedure

  1. Put your custom AI head on

    On the Mind-Controlled Light Switch demo, connect, press Install a saved head, and choose the wearer's file: the demo puts it in slot 2 and runs it. Then close the tab, so the IntoMind One is free for the board, and switch it off until step 3.

  2. Put the program on the board

    pin = Pin(15, Pin.OUT, value=0)
    
    def on_switch(on):
        pin.value(on)
    
    def on_reading(score, clean):
        print(time.ticks_ms(), "%.2f" % score, clean)

    Download the program, and save it on the board as main.py. In its section for your code, uncomment the two lines for the pin, and make on_reading log each reading's time on the board's clock, its score and whether it was clean. Check the LED circuit on pin 20 before the board is plugged in.

  3. Connect

    Looking for your IntoMind One.
    Found IntoMind One. Connecting.
    Running your custom AI head.
    51234 0.14 True
    Reading 0.14
    55233 0.09 True
    Reading 0.09

    The wearer puts the IntoMind One on at the site where the head was taught. When your instructor says, switch it on, keep the board beside it, and press Ctrl-D in the editor to restart the board.

    You should seeThe board's light blinking once a second while it looks, then off, and on while the wearer holds On, and a logged line for every reading, about four seconds apart.

  4. Ten timed calls

    The operator calls a switch to On at a random moment, times it to the LED on pin 20, and waits for the light to go off again before the next. Ten calls. Then copy the editor's log into a file, log.txt.

    CallSeconds to the pinNotes
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  5. Take the computer away

    Unplug the board and plug it into the USB charger. It runs main.py by itself and finds the IntoMind One again.

    You should seeThe LED following the wearer, with no computer anywhere in the loop.

Analysis

Compare your ten delays with the window's model, estimate δ, and check the reading interval from the board's own clock.

import numpy as np

delays = np.array([5.1, 3.2, 4.8, 6.0, 2.9, 4.4, 5.6, 3.7, 4.9, 4.1])   # your ten timed calls, in seconds
print("mean", round(delays.mean(), 2), "s, spread", round(delays.std(ddof=1), 2), "s")
# If a call falls anywhere in a four-second reading, and the reading under way counts once
# more than half of it is On, the window alone gives a delay spread evenly from 2 to 6 seconds.
print("the window alone: mean 4.0 s, spread", round(4 / np.sqrt(12), 2), "s")
print("the rest of the loop and the people, about", round(delays.mean() - 4, 2), "s")

# The board's log: one line per reading, its time in milliseconds, its score, and whether it was clean.
ticks = np.array([int(line.split()[0]) for line in open("log.txt") if line[:1].isdigit()])
print("a reading every", round(np.diff(ticks).mean() / 1000, 2), "s")

Work it outOur mean delay: , spread . δ, about , against our budget's .

Report

  1. The question, and your budget and hypothesis as you wrote them first.
  2. Methods: the program and your changes, how the calls were made and timed, and the log.
  3. Results: the ten delays, their mean and spread against the model's, δ, and the interval between readings.
  4. Interpretation: which stage dominates, where your budget was wrong, and what would shorten the loop at what cost.
  5. Limitations: ten calls, timing by hand, one wearer and one head.
  6. Your program and analysis code, as an appendix.

Problems

  1. List the steps from power on to the first prediction, in Bluetooth terms.

  2. What does pairing with LE Secure Connections and no user confirmation protect against, and what not?

  3. Break your measured delay into parts.

  4. Map each light pattern to a state in the program.

Sources

Raspberry Pi Ltd. Raspberry Pi Pico 2 W documentation.

The demos' source, github.com/intomind/demo: the program in micropython/mind_controlled_microcontroller.py, and in C in pico/board.

The IntoMind MicroPython repository, github.com/intomind/micropython.

Bluetooth SIG. Bluetooth Core Specification, Security Manager.

Lab 6 · Graduate

Mind-Controlled Microcontroller

Measured on the board's own clock, how long does a change of state take to reach the pin, does the window model explain it, how often does the pin go high on its own, and what would it take to know?

The loop, exactly

PartWhat it doesSource
FindingScans for three seconds, keeps the IntoMind Ones whose names start with DEVICE_NAME_PREFIX, empty by default, and connects to the strongest. Pairs the first time, and after two failed connections in a row forgets its pairings and pairs again.mind_controlled_microcontroller.py
RunningSelects the head in slot 2, starts the stream unless one is running, and turns on predictions: one score for every four-second window.the same
DecidingOn when a clean reading's score is above 0.5, Off when it isn't. A reading with a gap changes nothing. No hold and no hysteresis.the same
Failing safeOff at start, and whenever the link is lost. The link counts as lost after 20 seconds without a reading. Retries every 5 seconds.the same
Your codeon_switch(on) when the decision changes, and on_reading(score, clean) for every reading.the same

Preregister

Fill it in before the lab, from Microcontrollers and circuits. The report names every deviation.

ItemYour plan, before any data
The delay you expect, its spread, and where each part comes from
The false switches you expect in five minutes at rest, and what five minutes can show
How you will test the delay against the window model
The board's threats you will demonstrate or argue, and how

Get ready

You need

  • An IntoMind One, charged, with its cable unplugged, and a saved custom AI head
  • The board with the IntoMind MicroPython firmware, its cable, the LED circuit, a push button, two jumper wires, and a USB charger
  • A computer with Chrome or Edge and a MicroPython editor
  • A clean microfiber, soft cotton or eyeglass cloth

Roles

Wearer
Wears the IntoMind One, and switches state at each call.
Operator
Presses the button as they call each switch.
Analyst
Keeps the logs, and notes anything that disturbs a call.

Rotate, so everyone who wants to is the wearer once.

Rules

  • Unplug the IntoMind One's cable before anyone puts it on.
  • The board's pin is 3.3 volts. It switches an LED or a signal, never anything that plugs into a wall.
  • Check every breadboard before the board is plugged in.
  • Wipe the electrodes between wearers with the soft cloth, since a rough one can scratch their gold coating.

Procedure

  1. Put your custom AI head on

    On the Mind-Controlled Light Switch demo, connect, press Install a saved head, and choose the wearer's file: the demo puts it in slot 2 and runs it. Then close the tab, so the IntoMind One is free for the board, and switch it off until step 3.

  2. Wire the button, and put the program on the board

    pin = Pin(15, Pin.OUT, value=0)
    cue = Pin(14, Pin.IN, Pin.PULL_UP)
    last_cue = 0
    
    def on_cue(p):
        global last_cue
        now = time.ticks_ms()
        if time.ticks_diff(now, last_cue) > 300:      # a button bounces: one press, one cue
            last_cue = now
            print("cue", now)
    
    cue.irq(trigger=Pin.IRQ_FALLING, handler=on_cue)
    
    def on_switch(on):
        pin.value(on)
        print("switch", time.ticks_ms(), int(on))
    
    def on_reading(score, clean):
        print("reading", time.ticks_ms(), "%.3f" % score, clean)

    Download the program, and save it on the board as main.py. With the board unplugged, add a push button from pin 19, GP14, to ground at pin 23, beside the LED circuit on pin 20. Replace the program's section for your code with these lines: the pin, a cue logged on the board's clock when the button is pressed, and every switch and reading logged on the same clock.

  3. Connect

    Looking for your IntoMind One.
    Found IntoMind One. Connecting.
    Running your custom AI head.
    reading 51234 0.142 True
    Reading 0.14

    The wearer puts the IntoMind One on at the site where the head was taught. When your instructor says, switch it on, keep the board beside it, and press Ctrl-D in the editor to restart the board.

    You should seeThe board's light blinking once a second while it looks, then off, and on while the wearer holds On, and a logged reading about every four seconds.

  4. Ten cued calls

    The operator calls On and presses the button at the same moment, at random times, waits for the LED, then calls Off and waits for it to go out. Ten calls. Copy the editor's log into calls.txt.

  5. Five minutes at rest

    The wearer holds Off for five minutes with no calls. Copy the log into rest.txt.

  6. The prefix, demonstrated

    With the board's prefix empty, bring a second IntoMind One, switched on, unworn and connected to nothing, nearer to the board than the wearer's, and restart the board. Then set DEVICE_NAME_PREFIX to the start of the wearer's IntoMind One's name and restart it again.

  7. Take the computer away

    Unplug the board and plug it into the USB charger. It runs main.py by itself and finds the IntoMind One again.

    You should seeThe LED following the wearer, with no computer anywhere in the loop.

Analyses

From the board's logs: each call's delay from the cue to the pin, the delays against the window model once the rest of the loop and the wearer's reaction are taken out, the spacing of readings, and the rate of false switches at rest with its upper bound.

import numpy as np
from scipy import stats

def events(path, kind):
    """The board's times, in seconds, for every logged line of one kind."""
    rows = [line.split() for line in open(path) if line.startswith(kind + " ")]
    return rows, np.array([int(r[1]) / 1000 for r in rows])

_, cues = events("calls.txt", "cue")                 # the editor's log, copied to files
switches, t = events("calls.txt", "switch")
ons = t[[r[2] == "1" for r in switches]]
delays = np.array([ons[ons > c].min() - c for c in cues if (ons > c).any()])
print(f"{len(delays)} calls: median {np.median(delays):.2f} s, mean {delays.mean():.2f}, "
      f"sd {delays.std(ddof=1):.2f}")

# Against the model: uniform from 2 to 6 seconds, shifted by the rest of the loop and the
# wearer's own reaction, estimated as the mean's excess over 4.
extra = delays.mean() - 4
fit = stats.kstest(delays - extra, stats.uniform(loc=2, scale=4).cdf)
print(f"the rest of the loop and the wearer: about {extra:.2f} s; "
      f"uniform from 2 to 6 after removing it: p {fit.pvalue:.2f}")

_, readings = events("calls.txt", "reading")
gaps = np.diff(readings)
print(f"a reading every {np.median(gaps):.2f} s, the longest gap {gaps.max():.2f} s")

# At rest: switches to On while the wearer held Off, and what that rate could be.
switches, t = events("rest.txt", "switch")
_, rest_readings = events("rest.txt", "reading")
hours = (rest_readings.max() - rest_readings.min()) / 3600
n = sum(r[2] == "1" for r in switches)
upper = stats.chi2.ppf(0.95, 2 * (n + 1)) / 2 / hours           # one-sided 95 percent bound
print(f"{n} false switches in {hours * 60:.0f} minutes: "
      f"at most {upper:.0f} an hour, at 95 percent")

Then report:

  1. The delays, their fit to the window model, and what the remainder is made of.
  2. The rate at rest with its bound, and how long a recording would need to show the once-in-two-hours that users ask for.
  3. A rule, a threshold and a hold, that would meet that requirement for your head, and what it would cost in delay.
  4. Your threat model, with the prefix demonstration as evidence.

Open problems

  1. Evaluation in use. Delay and false switches measured in a lab, cued and watched, differ from those in a home over weeks, and long-term home use is where noninvasive interfaces are tested least (Wolpaw and others, 2018).
  2. Asynchronous control. Knowing when someone means nothing at all, the no-control state, is harder than telling two states apart, and asynchronous interfaces still trade speed for false activations (Mason and Birch, 2000).
  3. Trusting the other end. A board that can't authenticate its device, and a device that can't authenticate its heads, rest on physical control of who is nearby. How to do better on hardware this small is open.

Report

  1. The preregistration as written, and every deviation from it, each with its reason.
  2. Methods: the head and its session, the board's code, the cues, and the rest period.
  3. Results: the delays and their fit, the rate at rest and its bound.
  4. The rule you would ship for a use you name, and the threat model.
  5. The code, and the logs, which hold scores and times and nothing else.

Sources

Mason, S. G., and Birch, G. E. (2000). A brain-controlled switch for asynchronous control applications. IEEE Transactions on Biomedical Engineering.

Huggins, J. E., Wren, P. A., and Gruis, K. L. (2011). What would brain-computer interface users want? Opinions and priorities of potential users with amyotrophic lateral sclerosis. Amyotrophic Lateral Sclerosis.

Wolpaw, J. R., and others (2018). Independent home use of a brain-computer interface by people with amyotrophic lateral sclerosis. Neurology.

The IntoMind MicroPython repository, github.com/intomind/micropython.