user11217: We are working on a project to control the reaction of a system to a lever, whose position is monitored by two IR sensors at the ends of its travel, the Reward sensor and the Trigger sensor.
There are three modes of action:
Mode1: lever has to start at TriggerSensor, and a success is recorded if and when the lever is moved to RewardSensor
Mode2: lever starts at TriggerSensor and has to be held for 4 seconds. At the end of this interval a tone is played for 2 seconds, the reward interval. Within this 2 seconds, if the lever is moved to the RewardSensor, a success is recorded.
Mode3: same as Mode2, but the initial 4 second timeout is of random length.
We also want to use the following lines:
digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  //This is to record to our computer the states of the trigger sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  //This is to record to our computer the states of the reward sensor
to constantly write the state of both sensors to our computer. However, this doesn't work as planned: there are delays between the execution of the mode functions (as described in full code below).Essentially, we are struggling to come up with a suitable way to time things correctly.
Please see full code below
// -----LIBRARIES

//#include <elapsedMillis.h>

// ----CONSTANTS (won't change)

const int TriggerSensorIn = 2;   //  Input from trigger sensor, LOW = broken
const int RewardSensorIn = 3;    //  Input from reward sensor, LOW = broken
const int ModeStateIn1 = 4;      //  Input 1 from switch to define paradigm mode
const int ModeStateIn2 = 5;      //  Input 2 from switch to define paradigm mode
const int RewardSignalOut = 12;   //  Output signal of reward, parallel taken off to counter module
const int ServoResetOut = 6;     //  Servo reset output signal
const int ToneOut = 10;          //  Audio stimulus
const int TriggerSensorOut = 7;  //  Output from trigger sensor for DAC board recording
const int RewardSensorOut = 8;   //  Output from reward sensor for DAC board recording

//------- VARIABLES (will change)

boolean backPressed = false;

int timeoutWindow = 4000;    // 4 second preliminary interval
int rewardWindow = 2000;    // 2 second reward interval

unsigned long currentMillis = 0;

//===============

void setup() {

  // initialise the digital pins as inputs and outputs

  pinMode(TriggerSensorIn, INPUT);
  pinMode(RewardSensorIn, INPUT);
  pinMode(ModeStateIn1, INPUT);
  pinMode(ModeStateIn2, INPUT);

  pinMode(RewardSignalOut, OUTPUT);
  pinMode(ServoResetOut, OUTPUT);
  pinMode(ToneOut, OUTPUT);
  pinMode(TriggerSensorOut, OUTPUT);
  pinMode(RewardSensorOut, OUTPUT);

}

//===============

void giveReward() {
  // This function is the protocol for recording a reward
  currentMillis=millis();
  digitalWrite(RewardSignalOut, HIGH);
  while (millis()>currentMillis+200) {
    digitalWrite(RewardSignalOut, LOW);
  }
}

//===============

void servoReset() {
  // This function is the protocol for resetting servos after a failed action
  currentMillis=millis();
  digitalWrite(ServoResetOut, HIGH);
  while (millis()>currentMillis+200) {
    digitalWrite(ServoResetOut, LOW);
  }
}

//===============

void mode1() {
  // This function is the protocol for controlling the system during mode 1, no time constraint on the action
  if (digitalRead(TriggerSensorIn == LOW)) {
    backPressed = true;

    if (backPressed == true && digitalRead(RewardSensorIn == LOW)) {
      giveReward();
      backPressed = false;
    }
  }
}

//===============

void mode2() {
  if (digitalRead(TriggerSensorIn == LOW)) {
    currentMillis=millis();
    while (digitalRead(TriggerSensorIn == LOW)) {
      while (millis() > currentMillis + timeoutWindow) {
        tone(ToneOut, 3000, 2000); 
        {
          goto rewardSeeking2;
        }
      }
    }

rewardSeeking2:
    currentMillis=millis();  // reset timer
    if (millis() < (currentMillis + rewardWindow) && digitalRead(RewardSensorIn == LOW)) {
      giveReward();
    }
    else if (millis() > (currentMillis + rewardWindow)) {
      servoReset();
    }
  }
}

//===============

void mode3() {
  timeoutWindow=random(1000,5000);
  if (digitalRead(TriggerSensorIn == LOW)) {
    currentMillis=millis();
    while (digitalRead(TriggerSensorIn == LOW)) {
      while (millis() > currentMillis + timeoutWindow) {
        tone(ToneOut, 3000, 2000); 
        {
          goto rewardSeeking3;
        }
      }
    }

rewardSeeking3:
    currentMillis=millis();  // reset timer
    if (millis() < (currentMillis + rewardWindow) && digitalRead(RewardSensorIn == LOW)) {
      giveReward();
    }
    else if (millis() > (currentMillis + rewardWindow)) {
      servoReset();
    }
  }
}

//===============

void loop() {

  digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  //This is to record to our computer the states of the trigger sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  //This is to record to our computer the states of the reward sensor


  if (digitalRead(ModeStateIn1) == LOW && digitalRead(ModeStateIn2) == LOW) {
    // Using the two mode selective switches to define mode1
    mode1();
  }

  else if (digitalRead(ModeStateIn1) == LOW && digitalRead(ModeStateIn2) == HIGH) {
    // Using the two mode selective switches to define mode2
    mode2();
  }

  else if (digitalRead(ModeStateIn1) == HIGH && digitalRead(ModeStateIn2) == LOW)  {
    // Using the two mode selective switches to define mode3
    mode3();
  }
}

//===============END


user7856: This is a snippet of how I would refactor the code:
void mode3() {
  int timeout = millis() + random(1000,5000);
  while (digitalRead(TriggerSensorIn == LOW) && 
         millis() < timeout) {
  };
  if (digitalRead(TriggerSensorIn == LOW) && 
         millis() > timeout) {
     tone(ToneOut, 3000); 
     timeout = millis() + rewardWindow;
     while (millis() < timeout)
       if (digitalRead(RewardSensorIn == LOW)
         giveReward();
  }
  noTone();
}

....
void loop() {
  // This is to record to our computer the states of
  // the trigger sensor
  digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  

  // This is to record to our computer the states of
  // the reward sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  


  int msin1 = digitalRead(ModeStateIn1);
  int msin2 = digitalRead(ModeStateIn2);

  if (msin1 == LOW)
      if (msin2 == LOW)
          mode1();
      else
          mode2();
  else if (msin2 == LOW)
    mode3();
}

But I think you should first try to write it down in plain English and verify that at least that algo works.
Then you can think how to transpose it into code.

11217: <p>We are working on a project to control the reaction of a system to a lever, whose position is monitored by two IR sensors at the ends of its travel, the Reward sensor and the Trigger sensor.</p>

<p>There are three modes of action:</p>

<p>Mode1: lever has to start at TriggerSensor, and a success is recorded if and when the lever is moved to RewardSensor</p>

<p>Mode2: lever starts at TriggerSensor and has to be held for 4 seconds. At the end of this interval a tone is played for 2 seconds, the reward interval. Within this 2 seconds, if the lever is moved to the RewardSensor, a success is recorded.</p>

<p>Mode3: same as Mode2, but the initial 4 second timeout is of random length.</p>

<p>We also want to use the following lines:</p>

<p><code>digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  //This is to record to our computer the states of the trigger sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  //This is to record to our computer the states of the reward sensor</code></p>

<p>to constantly write the state of both sensors to our computer. However, this doesn't work as planned: there are delays between the execution of the mode functions (as described in full code below).Essentially, we are struggling to come up with a suitable way to time things correctly.</p>

<p>Please see full code below</p>

<pre><code>// -----LIBRARIES

//#include &lt;elapsedMillis.h&gt;

// ----CONSTANTS (won't change)

const int TriggerSensorIn = 2;   //  Input from trigger sensor, LOW = broken
const int RewardSensorIn = 3;    //  Input from reward sensor, LOW = broken
const int ModeStateIn1 = 4;      //  Input 1 from switch to define paradigm mode
const int ModeStateIn2 = 5;      //  Input 2 from switch to define paradigm mode
const int RewardSignalOut = 12;   //  Output signal of reward, parallel taken off to counter module
const int ServoResetOut = 6;     //  Servo reset output signal
const int ToneOut = 10;          //  Audio stimulus
const int TriggerSensorOut = 7;  //  Output from trigger sensor for DAC board recording
const int RewardSensorOut = 8;   //  Output from reward sensor for DAC board recording

//------- VARIABLES (will change)

boolean backPressed = false;

int timeoutWindow = 4000;    // 4 second preliminary interval
int rewardWindow = 2000;    // 2 second reward interval

unsigned long currentMillis = 0;

//===============

void setup() {

  // initialise the digital pins as inputs and outputs

  pinMode(TriggerSensorIn, INPUT);
  pinMode(RewardSensorIn, INPUT);
  pinMode(ModeStateIn1, INPUT);
  pinMode(ModeStateIn2, INPUT);

  pinMode(RewardSignalOut, OUTPUT);
  pinMode(ServoResetOut, OUTPUT);
  pinMode(ToneOut, OUTPUT);
  pinMode(TriggerSensorOut, OUTPUT);
  pinMode(RewardSensorOut, OUTPUT);

}

//===============

void giveReward() {
  // This function is the protocol for recording a reward
  currentMillis=millis();
  digitalWrite(RewardSignalOut, HIGH);
  while (millis()&gt;currentMillis+200) {
    digitalWrite(RewardSignalOut, LOW);
  }
}

//===============

void servoReset() {
  // This function is the protocol for resetting servos after a failed action
  currentMillis=millis();
  digitalWrite(ServoResetOut, HIGH);
  while (millis()&gt;currentMillis+200) {
    digitalWrite(ServoResetOut, LOW);
  }
}

//===============

void mode1() {
  // This function is the protocol for controlling the system during mode 1, no time constraint on the action
  if (digitalRead(TriggerSensorIn == LOW)) {
    backPressed = true;

    if (backPressed == true &amp;&amp; digitalRead(RewardSensorIn == LOW)) {
      giveReward();
      backPressed = false;
    }
  }
}

//===============

void mode2() {
  if (digitalRead(TriggerSensorIn == LOW)) {
    currentMillis=millis();
    while (digitalRead(TriggerSensorIn == LOW)) {
      while (millis() &gt; currentMillis + timeoutWindow) {
        tone(ToneOut, 3000, 2000); 
        {
          goto rewardSeeking2;
        }
      }
    }

rewardSeeking2:
    currentMillis=millis();  // reset timer
    if (millis() &lt; (currentMillis + rewardWindow) &amp;&amp; digitalRead(RewardSensorIn == LOW)) {
      giveReward();
    }
    else if (millis() &gt; (currentMillis + rewardWindow)) {
      servoReset();
    }
  }
}

//===============

void mode3() {
  timeoutWindow=random(1000,5000);
  if (digitalRead(TriggerSensorIn == LOW)) {
    currentMillis=millis();
    while (digitalRead(TriggerSensorIn == LOW)) {
      while (millis() &gt; currentMillis + timeoutWindow) {
        tone(ToneOut, 3000, 2000); 
        {
          goto rewardSeeking3;
        }
      }
    }

rewardSeeking3:
    currentMillis=millis();  // reset timer
    if (millis() &lt; (currentMillis + rewardWindow) &amp;&amp; digitalRead(RewardSensorIn == LOW)) {
      giveReward();
    }
    else if (millis() &gt; (currentMillis + rewardWindow)) {
      servoReset();
    }
  }
}

//===============

void loop() {

  digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  //This is to record to our computer the states of the trigger sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  //This is to record to our computer the states of the reward sensor


  if (digitalRead(ModeStateIn1) == LOW &amp;&amp; digitalRead(ModeStateIn2) == LOW) {
    // Using the two mode selective switches to define mode1
    mode1();
  }

  else if (digitalRead(ModeStateIn1) == LOW &amp;&amp; digitalRead(ModeStateIn2) == HIGH) {
    // Using the two mode selective switches to define mode2
    mode2();
  }

  else if (digitalRead(ModeStateIn1) == HIGH &amp;&amp; digitalRead(ModeStateIn2) == LOW)  {
    // Using the two mode selective switches to define mode3
    mode3();
  }
}

//===============END
</code></pre>
 7856: <p>This is a snippet of how I would refactor the code:</p>

<pre><code>void mode3() {
  int timeout = millis() + random(1000,5000);
  while (digitalRead(TriggerSensorIn == LOW) &amp;&amp; 
         millis() &lt; timeout) {
  };
  if (digitalRead(TriggerSensorIn == LOW) &amp;&amp; 
         millis() &gt; timeout) {
     tone(ToneOut, 3000); 
     timeout = millis() + rewardWindow;
     while (millis() &lt; timeout)
       if (digitalRead(RewardSensorIn == LOW)
         giveReward();
  }
  noTone();
}
</code></pre>

<p>....</p>

<pre><code>void loop() {
  // This is to record to our computer the states of
  // the trigger sensor
  digitalWrite(TriggerSensorOut, digitalRead(TriggerSensorIn));  

  // This is to record to our computer the states of
  // the reward sensor
  digitalWrite(RewardSensorOut, digitalRead(RewardSensorIn));  


  int msin1 = digitalRead(ModeStateIn1);
  int msin2 = digitalRead(ModeStateIn2);

  if (msin1 == LOW)
      if (msin2 == LOW)
          mode1();
      else
          mode2();
  else if (msin2 == LOW)
    mode3();
}
</code></pre>

<p>But I think you should first try to write it down in plain English and verify that at least that algo works.
Then you can think how to transpose it into code.</p>
