Please Help w/Code

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
jrevard
 
Posts: 3
Joined: Fri Feb 28, 2014 11:13 pm

Please Help w/Code

Post by jrevard »

Hi,

My code keeps jumping out of a loop unexpectedly. It's the while loop in the record() function. It should only exit when I press a button which is connected to PIN 2, but there is a return after a conditional regarding the syncTime which I am not too familiar with as this is my first time using an SD shield. Please help with any input on how to improve code.

Thx

Code: Select all

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

#define LOG_INTERVAL    1000
#define SYNC_INTERVAL   1000

#define aref_voltage 3.3

RTC_DS1307 RTC;
const int chipSelect = 10;

uint32_t syncTime = 0; //time of last sync


const int buttonPin = 2;
const int ledBusy = 6;
const int ledReady = 7;
int stateChange = 0;
int temp[] = {0, 0, 0, 0, 0};

File logfile;

void error()
{
  digitalWrite(ledReady, HIGH);
  digitalWrite(ledBusy, HIGH);
  while(1);
}

void setup(void) {
  analogReference(EXTERNAL);

  pinMode(ledBusy, OUTPUT);
  pinMode(ledReady, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(10, OUTPUT);
  
  digitalWrite(ledReady, LOW);
  digitalWrite(ledBusy, LOW);
  

  if (!SD.begin(chipSelect)) {
    error();
  }

  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      logfile = SD.open(filename, FILE_WRITE);
      break; //leave the loop
    }
  }
  
  if (! logfile) {
    error();
  }
    
  //connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }
  
  logfile.println("millis,stamp,datetime,Temp0 V,Temp0 (F),Temp1 V, Temp1 (F),Temp2 V, Temp2 (F),Temp3 V, Temp3 (F),Temp4 V,Temp4 (F)");
}
  

void loop(void)
{
  
  while (stateChange == LOW){
    stateChange = digitalRead(buttonPin);
  }
  
  delay(450);
  stateChange = LOW;
  digitalWrite(ledReady, HIGH);
  
  while (1){
    stateChange = digitalRead(buttonPin);
    
    if (stateChange == HIGH){
      delay(450);
      stateChange = LOW;
      record();
      digitalWrite(ledReady, HIGH);
      digitalWrite(ledBusy, LOW);
    }
  }
}
      
void record(){
  digitalWrite(ledReady, LOW);
  digitalWrite(ledBusy, HIGH);
  
  while(stateChange == LOW){
    DateTime now;
    
    //delay for the amount of time we want between readings
    delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
    
    //log millis since starting
    uint32_t m = millis();
    logfile.print(m);
    logfile.print(",");
 
    now = RTC.now();
    logfile.print(now.unixtime()); // seconds since 1/1/1970
    logfile.print(", ");
    logfile.print('"');
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.print(now.second(), DEC);
    logfile.print('"');
   
    
    for (int i=0; i<5; i++) {
      temp[i] = analogRead(i);
      float voltage = temp[i]*aref_voltage/1024;
      float tempC = (voltage - 0.5)*100;
      float tempF = tempC*9/5 +32;
  
      logfile.print(",");
      logfile.print(voltage);
      logfile.print(",");
      logfile.print(tempF);
  }
    
    logfile.println();
            
    //sync to SD card!!
    if ((millis() - syncTime) < SYNC_INTERVAL) return;
    syncTime = millis();
    
    logfile.flush();        
  }
  delay(450);
  stateChange = LOW;
}

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Please Help w/Code

Post by adafruit_support_mike »

You're right that the conditional WRT the variable 'syncTime' is what's breaking the loop. Putting a return inside a loop generally leads to confusion. It looks like what you really want is this:

Code: Select all

    //sync to SD card!!
    if ((millis() - syncTime) > SYNC_INTERVAL) {
        logfile.flush();        
        syncTime = millis();
    }
As an aside, you never execute any code inside that loop which will change the value of 'stateChange'. You probably want to throw a 'digitalRead()' in somewhere.

User avatar
jrevard
 
Posts: 3
Joined: Fri Feb 28, 2014 11:13 pm

Re: Please Help w/Code

Post by jrevard »

Aha! Thx! And thanks for saving me the headache of dealing with the digitalRead; I probably would have thought it was something more complex and never would have thought of something that simple.

Works like a champ. I have modified the code a bit to account for the length of time it takes to execute the while loop in the record() function.

I put the digitalWrite for the LEDs in a better place to notify user as soon as the code realizes the state has changed. This helped me to determine that it takes about a second and a half for each iteration. Is this typical or might I be interpreting the results incorrectly? I came to this conclusion because while recording I have to hold the button down for about a second and a half before the LEDs will switch to ready.

Any other comments on how to better code this procedure would be welcomed as well.

THANKS!!!!

Code: Select all

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

#define LOG_INTERVAL    1000
#define SYNC_INTERVAL   1000

#define aref_voltage 3.3

RTC_DS1307 RTC;
const int chipSelect = 10;

uint32_t syncTime = 0; //time of last sync


const int buttonPin = 2;
const int ledBusy = 6;
const int ledReady = 7;
int stateChange = 0;
int temp[] = {0, 0, 0, 0, 0};

File logfile;

void error()
{
  digitalWrite(ledReady, HIGH);
  digitalWrite(ledBusy, HIGH);
  while(1);
}

void setup(void) {
  analogReference(EXTERNAL);

  pinMode(ledBusy, OUTPUT);
  pinMode(ledReady, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(10, OUTPUT);

  digitalWrite(ledReady, LOW);
  digitalWrite(ledBusy, LOW);


  if (!SD.begin(chipSelect)) {
    error();
  }

  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      logfile = SD.open(filename, FILE_WRITE);
      break; //leave the loop
    }
  }

  if (! logfile) {
    error();
  }

  //connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }

  logfile.println("millis,stamp,datetime,Temp0 V,Temp0 (F),Temp1 V, Temp1 (F),Temp2 V, Temp2 (F),Temp3 V, Temp3 (F),Temp4 V,Temp4 (F)");
}


void loop(void)
{

  while (stateChange == LOW){
    stateChange = digitalRead(buttonPin);
  }

  delay(450);
  stateChange = LOW;
  digitalWrite(ledReady, HIGH);

  while (1){
    stateChange = digitalRead(buttonPin);

    if (stateChange == HIGH){
      digitalWrite(ledReady, LOW);
      digitalWrite(ledBusy, HIGH);
      delay(1000);
      stateChange = LOW;
      record();
    }
  }
}

void record(){

  while(stateChange == LOW){
    DateTime now;

    //delay for the amount of time we want between readings
    delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));

    //log millis since starting
    uint32_t m = millis();
    logfile.print(m);
    logfile.print(",");

    now = RTC.now();
    logfile.print(now.unixtime()); // seconds since 1/1/1970
    logfile.print(", ");
    logfile.print('"');
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.print(now.second(), DEC);
    logfile.print('"');


    for (int i=0; i<5; i++) {
      temp[i] = analogRead(i);
      float voltage = temp[i]*aref_voltage/1024;
      float tempC = (voltage - 0.5)*100;
      float tempF = tempC*9/5 +32;

      logfile.print(",");
      logfile.print(voltage);
      logfile.print(",");
      logfile.print(tempF);
  }

    logfile.println();

    
    //sync to SD card!!
    if ((millis() - syncTime) < SYNC_INTERVAL){
      syncTime = millis();
      logfile.flush();
    }
    stateChange = digitalRead(buttonPin);
  }
  
  digitalWrite(ledReady, HIGH);
  digitalWrite(ledBusy, LOW);
  delay(1000);
  stateChange = LOW;
}

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Please Help w/Code

Post by adafruit_support_mike »

Glad to hear it's working for you. Happy hacking! ;-)

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”