Digital I/O Demo 3 – Starting a digital out schedule using a digital input trigger

In this demo, we set up different schedules for digital out values, which will be activated with digital in triggers.

We upload a waveform to the Digital Out buffer at address 0 + 4096*desired_digital_in_trigger. The waveform will always be executed on the digital out determined by the waveform, but how it gets started depends on the address you write the waveform to.

The value of your waveform should be determined by \sum\limits_{all~channel} 2^{d_{out}}. Therefore, you assign 1 for output on digital out 0, you put 2 for digital out 1 and if you want to output to both Digital Out 0 and 1, you would put 1+2 = 3, up to a value of 2^16 - 1.

doutWaveform = [ 2, 0, 0, 0, 0, 1, 1, 1];

Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*2);

For example, this will send [0 0 0 0 0 1 1 1] on Digital Out 0 and [1 0 0 0 0 0 0 0] on Digital Out 2 whenever Digital In 2 is triggered (this corresponds to RESPONSEPixx Green button).

Since the last value of the waveform gets replaced by the default value almost instantly, your device reading the Digital In signal might not be triggered by it. A possible fix is to specify to the Digital Out schedule an extra frame. In this case, we set the third argument of Datapixx('SetDoutSchedule', 0, 1000, 9, doutBufferBaseAddr); to be 9 instead of 8 to overcome that.

To start this special kind of schedule, we must first set the digital in you are going to use as a trigger to the right direction. Datapixx('SetDinDataDirection', 0); sets all the digital ins to be directed towards the device (digital in can be configured as digital out, for example if you want to light up the buttons on the RESPONSEPixx).

Once this is done, the schedule is started using Datapixx('EnableDoutButtonSchedules'); and will run until manually stopped (or when the device is reset).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function DatapixxDoutButtonScheduleDemo()
% DatapixxDoutButtonScheduleDemo()
%
% Demonstrates the use of automatic digital output schedules when user presses digital input buttons.
%
% History:
%
% Apr 30, 2012  paa     Written
% Oct 29, 2014  dml     Revised
% Mar 26, 2020  dml		Updated

AssertOpenGL;   % We use PTB-3

% Open Datapixx, and stop any schedules which might already be running
Datapixx('Open');
Datapixx('StopAllSchedules');
Datapixx('RegWrRd');    % Synchronize DATAPixx registers to local register cache

% Upload some arbitrary digital output waveforms for the first 5 button
% inputs.  Note that the digital output waveforms must be stored at 4kB
% increments from the DOUT buffer base address.
% Also note that the last value in the digital output waveform will be
% almost immediately replaced with the original contents of the digital
% output port when the schedule terminates.

% The mode can be:
% 0 -- The schedules starts on a raising edge (normal behavior)
% 1 -- The schedules starts on a falling edge (normal behavior)
% 2 -- The schedules starts on a raising and on a falling edge (double-edge behavior)
% Please note that for the mode 2 we only set up the Din0 and Din1 in this demo.
% For mode 0 and 1, you put the schedule at baseAddr + 4096*DinValue
% For mode 2, you put the schedule of a push at baseAddr + 4096*DinValue + 2048*DinValue and a release at baseAddr + 4096*DinValue + 2048

doutBufferBaseAddr = 0;
doutButtonSchedulesMode  = 2;


doutWaveform = [ 1, 1, 0, 0, 0, 1, 1, 0];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*0+2048*0); % RESPONSEPixx RED/Din0 Push 

if doutButtonSchedulesMode == 2
doutWaveform = [ 2, 2, 0, 0, 0, 2, 2, 0];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*0+2048*1); % RESPONSEPixx RED/Din0 Release
end

doutWaveform = [ 3, 3, 0, 0, 0, 3, 3, 0];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*1+2048*0); % RESPONSEPixx Yellow/Din1 Push

if doutButtonSchedulesMode == 2
doutWaveform = [ 1, 2, 1, 2, 0, 0, 0, 0];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*1+2048*1); % RESPONSEPixx Yellow/Din1 Release
end

doutWaveform = [ 0, 0, 0, 0, 0, 1, 1, 1];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*2); % RESPONSEPixx Green/Din2

doutWaveform = [ 0, 0, 0, 0, 1, 1, 1, 1];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*3); % RESPONSEPixx Blue/Din3

doutWaveform = [ 0, 0, 0, 1, 1, 1, 1, 1];
Datapixx('WriteDoutBuffer', doutWaveform, doutBufferBaseAddr + 4096*4); % RESPONSEPixx White/Din4

Datapixx('SetDoutSchedule', 0, 1000, 9, doutBufferBaseAddr); 
% NOTE THE 9 instead of 8, this fixes the problem mentioned above.
Datapixx('SetDinDataDirection', 0);
Datapixx('EnableDinDebounce');      % Filter out button bounce
Datapixx('EnableDoutButtonSchedules', 2); % This starts the schedules
Datapixx('RegWrRd');    % Synchronize DATAPixx registers to local register cache
Datapixx('Close');
fprintf('\n\nAutomatic buttons schedules running\n\n');