arduino skipping line of code

Hi,
I am turning a valve on and off for a set period of time, which is triggered when a photogate is crossed. However, occasionally the arduino seems to miss the line of code turning the valve off and it stays on. Does anyone know why this is happening? code below (this is within void loop):

while (((val_left > 500)&&(val_right > 500))||(error_flag==1)){
val_left = analogRead(analog_left); val_right = analogRead(analog_right);
switch (curr_trial){
case 1:
if (val_right < 500) {
tone(5,70,500);
to_print=(String)"left error|"+millis(); Serial.println(to_print);
matrix_center.clear(); matrix_center.fillRect(1,1,6,6, LED_OFF); matrix_center.writeDisplay();
delay(1500);
}
if (val_left < 500){
matrix_center.clear(); matrix_center.fillRect(1,1,6,6, LED_OFF); matrix_center.writeDisplay();
to_print=(String)"correct left|"+millis(); Serial.println(to_print);
digitalWrite(6, LOW); digitalWrite(13, HIGH); delay(reward_time); digitalWrite(6, LOW); digitalWrite(13, LOW);
waitTime=waitTime+1;
duration=duration+1;
to_print=(String)"wait time|"+waitTime; Serial.println(to_print);
}
break;
etcetc

it seems to be the digitalWrite(LOW) which is missed

thanks!

You MUST post the entire program - we have no idea how the variables are defined or what other code might affect them.

And please use the code button </> so your code looks like this and is easy to copy to a text editor.

You can be 110% certain that the Arduino is not skipping anything by mistake - it will do exactly what your code tells it to do.

...R

What does your code do when error_flag is 1 and val_right is 500?

What does your code do when error_flag is 1 and val_left is 500?

to_print=(String)"left error|"+millis(); Serial.println(to_print);

That is a horrible way to print that message.

sorry, below is the full code - thanks!

int high_rate = 100; int low_rate = 0;
int start_waitTime = 50;
int waitTime = 0;
int reward_time = 300;


#include "pitches.h"
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

int curr_trial = 1;
int last_trial = 1;

const int analog_left = A0;
const int analog_right = A2;
const int digital_center = 8;
int val_left = 0;
int val_right = 0;
int val_center = 0;
int repeat_flag = 0;
int num_repeat = 0;
String to_print = "";

unsigned long trial_start;
unsigned long current_time;
unsigned long currStart;

unsigned long startTime;
volatile unsigned long elapsedTime;
volatile boolean pokeIn;

int play_flag = 0;
int clicks_flag = 0;
int timestep = 1;
int duration = 300;
int left_rate = 0; int right_rate = 0;
int left_click[100] = {}; int right_click[100] = {};
int click_numL = 0; int click_numR = 0;
int curr_leftclick = 1; int curr_rightclick = 1;

Adafruit_8x8matrix matrix_left = Adafruit_8x8matrix();
Adafruit_8x8matrix matrix_center = Adafruit_8x8matrix();
Adafruit_8x8matrix matrix_right = Adafruit_8x8matrix();

void setup() {
  Serial.begin(9600);
  matrix_left.begin(0x72); matrix_left.clear(); matrix_left.fillRect(1, 1, 6, 6, LED_OFF); matrix_left.writeDisplay();
  matrix_center.begin(0x70); matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
  matrix_right.begin(0x71); matrix_right.clear(); matrix_right.fillRect(1, 1, 6, 6, LED_OFF); matrix_right.writeDisplay();

  pinMode(digital_center, INPUT);

  pinMode(6, OUTPUT);
  pinMode(13, OUTPUT);
  attachInterrupt (0, portWait, CHANGE);

  randomSeed(analogRead(5));
  generate_clicks();
  waitTime = start_waitTime;
}

void loop() {

  trial_start = millis();

  if (pokeIn) {
    to_print = (String)"wait interval|" + waitTime; Serial.println(to_print);
    currStart = startTime / 1000;
    matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_ON); matrix_center.writeDisplay();
    switch (curr_trial) {
      case 1:
        to_print = (String)"left trial|" + millis(); Serial.println(to_print);
        break;
      case 2:
        to_print = (String)"right trial|" + millis(); Serial.println(to_print);
        break;
    }
  }
  else
    return;

  while (pokeIn) {
    current_time = millis();
    if ((int)(current_time - currStart) > (waitTime - duration)) {
      if ((curr_leftclick < duration * 2) || (curr_rightclick < duration * 2)) {

        if (current_time - currStart - (waitTime - duration) > left_click[curr_leftclick]) {
          tone(12, 37, 15);
          if (left_click[curr_leftclick + 1] > 0) {
            curr_leftclick = curr_leftclick + 1;
            Serial.println("left");
          }
          else {
            curr_leftclick = 10000;
          }
        }
        else if (current_time - currStart - (waitTime - duration) > right_click[curr_rightclick]) {
          tone(5, 37, 15);
          if (right_click[curr_rightclick + 1] > 0) {
            curr_rightclick = curr_rightclick + 1;
            Serial.println("right");
          }
          else {
            curr_rightclick = 10000;
          }
        }
      }
    }
  }

  Serial.println(elapsedTime);
  if (elapsedTime < waitTime) {
    Serial.println("early exit|");
    matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
    tone(12, 80, 1000);
    tone(5, 80, 1000);
    tone(12, 80, 200);
    tone(5, 80, 200);
    curr_leftclick = 1;
    curr_rightclick = 1;
    delay(1500);
  }
  else {
    val_left = analogRead(analog_left); val_right = analogRead(analog_right);
    while ((val_left > 500) && (val_right > 500)) {
      val_left = analogRead(analog_left); val_right = analogRead(analog_right);
      switch (curr_trial) {
        case 1:
          if (val_right < 500) {
            tone(5, 70, 500);
            to_print = (String)"left error|" + millis(); Serial.println(to_print);
            matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
            delay(1500);
          }
          if (val_left < 500) {
            matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
            to_print = (String)"correct left|" + millis(); Serial.println(to_print);
            digitalWrite(6, LOW); digitalWrite(13, HIGH); delay(reward_time); digitalWrite(6, LOW); digitalWrite(13, LOW);
            waitTime = waitTime + 1;
            duration = duration + 1;
            to_print = (String)"wait time|" + waitTime; Serial.println(to_print);
          }
          break;
        case 2:
          if (val_left < 500) {
            tone(12, 70, 500);
            to_print = (String)"right error|" + millis(); Serial.println(to_print);
            matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
            delay(1500);
          }
          if (val_right < 500) {
            matrix_center.clear(); matrix_center.fillRect(1, 1, 6, 6, LED_OFF); matrix_center.writeDisplay();
            to_print = (String)"correct right|" + millis(); Serial.println(to_print);
            digitalWrite(6, HIGH); digitalWrite(13, LOW); delay(reward_time); digitalWrite(6, LOW); digitalWrite(13, LOW);
            waitTime = waitTime + 1;
            duration = duration + 1;
            to_print = (String)"wait time|" + waitTime; Serial.println(to_print);
          }
          break;
      }
    }
  }
  curr_leftclick = 1; curr_rightclick = 1;
  generate_trial();
  generate_clicks();
  play_flag = 0;
  digitalWrite(6, LOW); digitalWrite(13, LOW);
}

void generate_trial() {
  last_trial = curr_trial;
  curr_trial = random(1, 3);
  if (curr_trial == last_trial) {
    num_repeat = num_repeat + 1;
    if (num_repeat >= 3) {
      num_repeat = 0;
      if (curr_trial == 1) {
        curr_trial = 2;
      }
      else {
        curr_trial = 1;
      }
    }
  }
  Serial.println("trials generated");
}

void generate_clicks() {
  if (curr_trial == 1) {
    left_rate = high_rate; right_rate = low_rate;
  }
  else {
    left_rate = low_rate; right_rate = high_rate;
  }

  for (int ind = 0; ind < duration; ind++) {
    if (left_rate > random(1, 1000)) {
      left_click[click_numL] = ind;
      click_numL = click_numL + 1;
    }
    if (right_rate > random(1, 1000)) {
      right_click[click_numR] = ind;
      click_numR = click_numR + 1;
    }
  }
  for (int ind = click_numL + 1; ind < 100; ind++) {
    left_click[ind] = 0;
  }
  for (int ind = click_numR + 1; ind < 100; ind++) {
    right_click[ind] = 0;
  }
  click_numL = 0; click_numR = 0;
  clicks_flag = 1;
}

void portWait () {
  if (digitalRead (2) == LOW) {
    startTime = micros ();
    pokeIn = true;
  }
  else {
    elapsedTime = (micros () - startTime) / 1000;
    pokeIn = false;
  }
}

I know it makes sense to you but combining multiple statements on one line doesn't help anyone else read it. I think the auto format function on the Tools menu will fix this for you.

Don't use (String). Try this instead:

serial.print("wait time|");
serial.println(waitTime);

I don't see any code to turn a valve off. All I see is code to print stuff to an LCD.

Which line is not being executed?

the valves are being turned on and off with:
digitalWrite(6, LOW); digitalWrite(13, HIGH);
delay(reward_time);
digitalWrite(6, LOW); digitalWrite(13, LOW);

similar to this problem where the digital channel gets stuck on high, I also seem to find that the following lines only produce one tone, rather than 4:
tone(12, 80, 1000);
tone(5, 80, 1000);
tone(12, 80, 200);
tone(5, 80, 200);

This starts each tone, then starts the next without waiting for the previous one to finish, so you only hear the last.
(The program is not halted while each tone plays. You need to add delays in between to do that.)

tone(12, 80, 1000);
tone(5, 80, 1000);
tone(12, 80, 200);
tone(5, 80, 200);

Edit:
So in this, you're saying that pin 13 stays HIGH? :-

digitalWrite(6, LOW);
digitalWrite(13, HIGH);
delay(reward_time);
digitalWrite(6, LOW);
digitalWrite(13, LOW);

(Using descriptive names rather than pin numbers would make your code much easier to follow. Also, moving each statement to it's own line as mentioned by MorganS would help a lot. So would comments in your code.)

yes, pin13 stays on HIGH. thanks for wading through my poor code....

albuddah:
yes, pin13 stays on HIGH. thanks for wading through my poor code....

I find it very hard to believe that pin 13 stays HIGH. I suspect that you have another problem, either in your hardware wiring or maybe the valve itself is sticking. There's nothing in your code that would prevent pin 13 from returning to LOW and closing the valve.
Try attaching a LED (with resistor) to that pin, to visually follow what it does. I'll bet that the LED goes out when it's supposed to.

Incidentally, writing a LOW to pin 6 twice achieves nothing. It won't go HIGH by itself in between the two writes. You just need the first one.