Problem with nested if statement.

Hello, First off I will explain the code. I have an lcd display in which I click the down button and the Arduino will then take data every two minutes forever.

I am collecting a large amount of data, which will read a sensor of 512 pixels 6 times (this is just a requirement of the project). So data collection takes ~27 seconds more or less. Now the code:

//Libraries included in code
#include <SPI.h>
#include <Adafruit_ADS1015.h>
#include <SD.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <TimeLib.h>
#include <TimeAlarms.h>

//Peripheral components ADC(ADS1115) & LCD

Adafruit_ADS1115 ads1115;
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

//Define several global variables
#define WHITE 0x7
const PROGMEM int PIXELS = 512;  //number of pixels on linear sensor 
volatile boolean startMeasuring;
File myFile;

void setup() {
 
//Begin Serial at BAUD 115200
  Serial.begin(115200);
 
  //Begin communication with LCD
  lcd.begin(16, 2);
  lcd.setBacklight(WHITE);
  
  //Begin communication with ADS1115 ADC
  ads1115.begin();

  //initialize pins
  pinMode(2, OUTPUT); //clock pin
  pinMode(3, OUTPUT); //start pin
  pinMode(6, OUTPUT); //2.9V reference pin for ADC

  //Assert Default setting:
  analogReference(DEFAULT);

  // Set all IO pins low:
  for (uint8_t i = 0; i < 53; i++) {
    digitalWrite(i, LOW);
  }

  //Set pin 6 high
  digitalWrite(6, HIGH); //2.9V reference for ADC
  
  //check to see if the SD card is there and will initialize
    if (!SD.begin(4)) {
    Serial.println(F("SD card failed to initialize"));
    return;
  }
    
    myFile = SD.open("datalog.txt", FILE_WRITE);
   
    
    //Configure alarm for data collection
    setTime(8, 30, 0, 4, 15, 16); //set time to now
    //First time taking data called after 3 seconds
    Alarm.timerOnce(3, onceOnly);             
    //Alarm every two minutes to take data
    Alarm.timerRepeat(120, dataCollect); 

    
   //set up opening menu for lcd screen
   lcd.setCursor(0, 1);
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(F("Calibration"));
   lcd.setCursor(0, 1);
   lcd.print(F("Field Collect"));
}


void onceOnly() {
  startMeasuring = true;
}

void dataCollect() {
  startMeasuring = true; 
}


void loop() {
  uint8_t buttons = lcd.readButtons();
  if (buttons) {
    if (buttons & BUTTON_DOWN) {
      while (1) {
        if (startMeasuring) {
      
        //notify user that Arduino is scanning sensor
        lcd.clear();
        lcd.print(F("Scanning"));
       
       button_press(); 
  
      //Notify user that arduino is done scanning
      lcd.clear();
      lcd.print(F("Done Scanning"));
      
      //close file and wait two minutes to begin next scan
      myFile.close();
      startMeasuring = false;
  }
  else{ }
    }
  }
}
}

//--------------------------------------PIXEL-SCAN--------------------------------------------------------\\

int startTime(int pixel) {
  unsigned int adc;
  PORTE |= _BV(5); //start high
  PORTE |= _BV(4); //clock high
  delayMicroseconds(4); //delay for start pulse width
  PORTE &= ~_BV(4); //clock low
  PORTE &= ~_BV(5); //start low

  for (int i = 0; i < pixel; i++) { //clock goes from low to high to
    //shuffle through pixels, find the one we want
    PORTE |= _BV(4); //clock high
    delayMicroseconds(4);
    PORTE &= ~_BV(4); //clock low, need to read now
  }
   adc = ads1115.readADC_Differential_0_1() + 21000;
  //adc = ads1115.readADC_SingleEnded(0);
  myFile.println(adc); 
  Serial.println(adc);
  
  for (int i = 0; i <= (PIXELS - pixel); i++) {
    PORTE |= _BV(4); //clock high
    delayMicroseconds(4);
    PORTE &= ~_BV(4); //clock low
  }

}

void button_press() {
      
      for (uint8_t i=0; i < 6; i++) {
      //first value is discarded from each scan
      startTime(0);
      delay(1);

      for (int i = 0; i < PIXELS; i++) {
        startTime(i);
        delay(1);
      }
      } 
}

My first attempt at this used a delay, so after each measurement I delayed 90 seconds. So that 90 seconds, plus data collection took about 2 minutes. This was just to test the code, but is not accurate. I need the Arduino to sync with other instruments in the field, and so data collection must occur every two minutes exactly.

In this code decided to use alarms and the time library. What I do is set the time and date and then ring an alarm every 120 seconds. when the alarm rings it sets startMeasuring to true. In the loop I have the LCD code which includes a while (1) { loop so that data is taken forever. Once the alarm rings the if statement in the for loop goes to true and data collection should begin. At the end of data collection, startMeasuring goes to false and it waits for another alarm to trigger it to be true again (after 120 seconds). I also included an alarm that only goes off after 3 seconds once so that data collection can start when I turn the arduino on, without having to wait 2 minutes for the first alarm.

My problem is that nothing seems to happen in the while (1) loop. If the alarm is going off, it doesnt seem to trigger data collection. Im not sure what I am doing wrong. Can a for loop be nested in a while (1) loop or is it something else. Maybe a trigger cant go off while in a while (1) loop?

Thanks, arduino is 2560 mega

In this code decided to use alarms and the time library. What I do is set the time and date and then ring an alarm every 120 seconds.

Why add all that complexity? Look at the blink without delay example. Instead of toggling an LED, you take the series of measurements, when the time is appropriate.

cosmictealeaf:
I need the Arduino to sync with other instruments in the field, and so data collection must occur every two minutes exactly.

Never going to happen with a Arduino alone. The clock of the Arduino is not accurate so if you really need accurate 2 minutes you should consider something like a RTC.

And some things, whatch your indentation :wink:

And a while(1) which you never break inside the loop, mm. So the only way to exit it to turn off the Arduino...

    if (buttons & BUTTON_DOWN) {

Are you sure that's how you read the button? (Might be, I don't know.) Aka, a bitwise compare.

And once you're in the while() you only look for startMeasuring. Which is initialized to 0 aka false. So it's never going to become true! Because all the code that might set it true isn't run because of it being false...

Thank you for the replies. PaulS, that is good advice and for the time I will use the blinkwithout delay example. Considering that I do in fact use the RTC to better sync the electronics, how would one go about doing that? Would it be to set alarms in the RTC or is there a simpler way to use the RTC to keep track of time?

Thank you again!

Would it be to set alarms in the RTC or is there a simpler way to use the RTC to keep track of time?

Are you planning on sleeping? How do YOU manage to leave work on time? Does someone need to tell you it is time to go home? Or can you see for yourself that it is quitting time?

Thanks PaulS for the tip