ils-labs-dev

How-tos

Adding a BeexyBox button box to a Zep experiment

Last updated on 5 November 2018 by Ty Mees

If you have suggestions on how to improve this document, or find mistakes, please send them to labman.gw@uu.nl

When using ZEP, you can use a BeexyBox buttons box to measure participant responses and response times. Most ZEP 2 experiment templates already have the necessary code to use these button boxes. However, not all ZEP 1 templates come with this support out of the box, so you’ll need to add it yourself. This page will give you a step-by-step guide to adding a BeexyBox button box as input to your experiment.

ZEP 1

  1. Check your experiments ZEP version
    The BeexyBox requires ZEP version 1.12 or higher. You can check the version your experiment is using by opening your main zep file, which should be located in the root of your experiment.
    The first line of code should be required 1.xx, with the number indicating the version of ZEP this script is using.
    Please note that using the latest version of ZEP is always recommended.
  2. Enabling the module
    Some versions of ZEP default to the predecessor of the BeexyBox button box (called ButtonBox in ZEP 1).
    To fix this, we need to add our own module to the modules/ folder, which will tell ZEP to use the BeexyBox instead. Go to the page on the ZEP wiki, and download the file ‘response_box.zm’ under the relevant files section.
    Place the file in your modules folder, and open it in a text editor. You will see two lines of code both beginning with the word alias, with the last line commented out. By default, it’s using the line referencing the old ButtonBox, but we want to use the BeexyBox. Comment out the line referencing the ButtonBox, and uncomment the line referencing the BeexyBox.

ZEP needs to connect to the BeexyBox. Use the following line of code to open the connection:

control.button_box.open();

You only have to open the connection once in your experiment. The best place to do this is in the entry event in your .zp script, like so:

Experiment experiment
{
    on_event:entry()
    {        
        control.button_box.open();
        show_test_windows();
    }
...

Note: Some of the template experiments open the connection in the entry event in the task.zm, like so:

Block task
{
    on_event:entry()
    {
        control.button_box.open();
    }
...

The disadvantage of opening the connection to the button box as late as in task.zm is that an unfortunate combination of the nature of the BeexyBox and human behavior will lead to the Beexybox getting into a fancy mode involving lights and beeping and not working with your experiment.

The human behavior is that you will find yourself wanting to use the button box to get past the welcome screen (which will not work, but you’ll want to). When you press the button multiple times (as a person is likely to do when something doesn’t work, even though it doesn’t help), the BeexyBox gets into its weird mode.

You can get it out of its weird mode by just disconnecting the cable and starting your experiment again. But to avoid this from happening at all, just enable the connection in your .zp script, and comment out the line in task.zm if it’s there.

By default, all buttons are disabled. You have to manually enable them and assign a code (or response value) to them. A good place to set up your buttons is in the setup function in your test_page.zm file.

  1. Enabling a button
    You can enable a button with control.button_box.enable_button(int btn, int code);
    In which btn is an integer which identifies a button. Buttons are numbered from zero to two/three (depending on the number of buttons on your box) from left to right. Code is an integer which corresponds with the response that should be given for that button.
  2. Enabling all buttons
    You can use control.button_box.enable_all_buttons(int code) to enable all buttons at once with the same code. This is useful for when a participant needs to press any button, for example when starting an experiment from the instruction screen.
  3. Disabling buttons
    Sometimes it’s necessary to disable all buttons, in which case you can use control.button_box.disable_buttons().
    It is recommended to do this before you enable any buttons, as in most experiments all buttons are enabled for the instructions screen. If you don’t disable them before setting the buttons up for your experiment, you might have a button active that is not used for the actual experiment. If the participant accidentally presses a button that should not be working, you can register a wrong value.
  4. Example
    Below is an example for setting up two buttons with corresponding codes.

    control.button_box.disable_buttons();
    control.button_box.enable_button(0, 2); // button 0, with as code 2. 
    control.button_box.enable_button(1, 3); // button 1, with as code 3.
  5. Testing the button mappings
    In the lab under Linux and on the experimental laptops under Linux, you can check which button is mapped to what number by running the following command in a terminal:

    test-beexybox-zep2

    If you work elsewhere or under Windows, this will not work. Instead, check your button mappings by running the experiment, remembering which button you pressed, and checking the output to see which value the button gives in the output.

Processing button presses
ZEP handles button presses by sending a message to the current target. This means we need to make a so-called event handler. This is just a simple function that is called to handle an event, you only need to add the following code to your test page and ZEP will automatically execute the code when a button is pressed:

on_event:message()
{
    // process code here
}

You can use the variable message_arg to get the code you set for the key that was pressed. You can use the variable event_time to get the exact time when the button was pressed. Most of the time, you want the Response object to actually handle the button presses, like in this example:

on_event:message()
{
    response.process_hit(message_arg, event_time);
}

Setting the target
As the button press is sent to the current target, we need to set the test page as the current target. Simply add the following line to your test page:

control.target = this;

It can be useful to add this line somewhere near where you enabled the buttons. This way most of the relevant code for the button box is in one place. A good place to put all of your button box code is in the setup function of your test_page.zm. For example:

control.target = this;
control.button_box.disable_buttons();
control.button_box.enable_button(0, 2); // button 0, with as code 2. 
control.button_box.enable_button(1, 3); // button 1, with as code 3.
In most templates, the button box is not enabled in the welcome screen, as it’s configured in the instructions page. For participants, this can be counter-intuitive. (As described in the note in step 2).

Luckily, we can fix this easily with one line of code. In your main ZEP file, add the following line to the entry event of your experiment:

control.button_box.enable_all_buttons(CONTINUE);

You should put this right after you opened the connection to the button box. This will tell ZEP that any button press means that we want to continue to the next page.

All together, your experiment should begin like this:

Experiment experiment
{
    on_event:entry()
    {
        show_test_windows();
        
        control.button_box.open();
        control.button_box.enable_all_buttons(CONTINUE);
    }
...

ZEP 2

Enabling the BeexyBox in ZEP 2 is very simple. Add the following line to your main zep file (alongside the other import lines):

import io_beexybox;
By default, all buttons are disabled. You have to manually enable them and assign a code to them. A good place to set up your buttons is in the setup function in your test_page.zm file.

    1. Enabling a button
      You can enable a button with control.enable_button(int btn, int code);
      In which btn is an integer which identifies a button. Buttons are numbered from zero to two/three (depending on the number of buttons on your box) from left to right. Code is an integer which corresponds with the response that should be given for that button.
    2. Enabling all buttons
      You can use control.enable_all_buttons(int code) to enable all buttons at once with the same code. This is useful for when a participant needs to press any button, for example when starting an experiment from the instruction screen.
    3. Disabling buttons
      Sometimes it’s necessary to disable all buttons, in which case you can use control.disable_buttons().
      It is recommended to do this before you enable any buttons, as in most experiments all buttons are enabled for the instructions screen. If you don’t disable them before setting the buttons up for your experiment, you might have a button active that is not used for the actual experiment. If the participant accidentally presses a button that should not be working, you can register a wrong value.
    4. Example
      Below is an example for setting up two buttons with corresponding codes.

      control.disable_buttons();
      control.enable_button(0, 2); // button 0, with as code 2. 
      control.enable_button(1, 3); // button 1, with as code 3.
    5. Testing the button mappings
      In the lab under Linux and on the experimental laptops under Linux, you can check which button is mapped to what number by running the following command in a terminal:

      test-beexybox-zep2

      If you work elsewhere or under Windows, this will not work. Instead, check your button mappings by running the experiment, remembering which button you pressed, and checking the output to see which value the button gives in the output.

Processing button presses
ZEP handles button presses by sending a message to the current target. This means we need to make a so-called event handler. This is just a simple function that is called to handle an event, you only need to add the following code to your test page and ZEP will automatically execute the code when a button is pressed:

on_event:message()
{
    // process code here
}

You can use the variable message_arg to get the code you set for the key that was pressed. You can use the variable event_time to get the exact time when the button was pressed. Most of the time, you want the Response object to actually handle the button presses, like in this example:

on_event:message()
{
    response.process_hit(message_arg, event_time);
}

Setting the target
As the button press is sent to the current target, we need to set the test page as the current target. Simply add the following line to your test page:

control.target = this;

It can be useful to add this line somewhere near where you enable the buttons. This way most of the relevant code for the button box is in one place. A good place to put all of your button box code is in the setup function of your test_page.zm. For example:

control.target = this;
control.button_box.disable_buttons();
control.button_box.enable_button(0, 2); // button 0, with as code 2. 
control.button_box.enable_button(1, 3); // button 1, with as code 3.
In most templates, the button box is not enabled in the welcome screen, as it’s configured in the instructions page. For participants, this can be counter-intuitive.
The human behavior is that you will find yourself wanting to use the button box to get past the welcome screen (which will not work, but you’ll want to).

Luckily, we can fix this easily with one line of code. In your main ZEP file, add the following line to the entry event of your experiment:

control.enable_all_buttons(CONTINUE);

You should put this right after you opened the connection to the button box. This will tell ZEP that any button press means that we want to continue to the next page.

All together, your experiment should start like this:

Experiment experiment
{
    on_event:entry()
    {
        show_test_windows();
        
        control.enable_all_buttons(CONTINUE);
    }
...