Go Down

Topic: Freezer code error help (Read 1 time) previous topic - next topic

njsmith1

Hey guys, Im pretty new to programming so ill probably have a few questions along the way as I try to do this project. Just a quick explanation of what I am trying to do - Im programming an arduino to turn on and off a freezer relay during different times of the day. set the temp during the day 7am-7pm to -5 degrees and at night, 7pm - 7am to -20 degrees. I have the code keeping time, getting the temperature and light values and displaying them and am now trying to write the if/else statements that will jump to the two functions called Daytime and Nighttime. Here is the code:

Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define aref_voltage 3.3

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    analogReference(EXTERNAL);
  }

void loop () {
   
    analogRead(photocellPin);
  delay(10);
  photocellReading = analogRead(photocellPin); 
 
  Serial.print("Light reading = ");
  Serial.print(photocellReading);     // the analog reading
 
  // Thresholds for the photocell
  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright");
  }
 
  analogRead(tempPin);
  delay(10);
  tempReading = analogRead(tempPin); 
 
  Serial.print("Temp reading = ");
  Serial.print(tempReading);     // the analog reading
 
  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // print out the voltage
  Serial.print(" - ");
  Serial.print(voltage); Serial.println(" volts");

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC); Serial.println(" degrees C");

  // now convert to Fahrenheight
  float temperatureF = (temperatureC * 9 / 5) + 32;
  Serial.print(temperatureF); Serial.println(" degrees F");

  DateTime now = RTC.now();
   
    Serial.print("The time is:");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    delay(1000);
   
  {
    if (now.hour >= 7 && now.hour <= 19);   //If time is between 7am and 7pm print day time setting)
    {                                                       //It will later call a function to check if the temp is between a value
      Serial.print("Day time setting");           // and then turn a relay on for the freezer if not the correct setting
    }
    else                                                   // if it is not set to day time - set to night time. Which will call a function
    {                                                      // that turns on the freezer if not the correct "Night time" temp.
      Serial.print("Night time setting");
    }
  }
}


My issue is with the last If/else statement. The line  if (now.hour >= 7 && now.hour <= 19); is returning an error saying:
Complex_TempLight_Clock_pde:75: error: invalid use of member (did you forget the '&' ?)
Complex_TempLight_Clock_pde:79: error: 'else' without a previous 'if'.

Any help would be much appreciated.

dxw00d

Code: [Select]
    if (now.hour >= 7 && now.hour <= 19);   //If time is between 7am and 7pm print day time setting)
Should be
Code: [Select]
    if (now.hour() >= 7 && now.hour() <= 19)   //If time is between 7am and 7pm print day time setting)

You missed the brackets off. I also removed the semicolon, which would count as the code executed when the if was true.

njsmith1

THANK YOU haha Ive been sitting here for 2 hours trying to get the brackets in the right spot but couldn't figure it out. Now to wrack your brain again this is what I have added.
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -20
#define NIGHTLOW -22
#define DAYHIGH -4
#define DAYLOW -6
#define aref_voltage 3.3

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    analogReference(EXTERNAL);
  }

void loop () {
   
    analogRead(photocellPin);
  delay(10);
  photocellReading = analogRead(photocellPin); 
 
  Serial.print("Light reading = ");
  Serial.print(photocellReading);     // the raw analog reading
 
  // We'll have a few threshholds, qualitatively determined
  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright");
  }
 
  analogRead(tempPin);
  delay(10);
  tempReading = analogRead(tempPin); 
 
  Serial.print("Temp reading = ");
  Serial.print(tempReading);     // the raw analog reading
 
  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // print out the voltage
  Serial.print(" - ");
  Serial.print(voltage); Serial.println(" volts");

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC); Serial.println(" degrees C");

  // now convert to Fahrenheight
  float temperatureF = (temperatureC * 9 / 5) + 32;
  Serial.print(temperatureF); Serial.println(" degrees F");

  DateTime now = RTC.now();
   
    Serial.print("The time is:");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    delay(1000);
   
  {
    if (now.hour() >= 7 && now.hour() <= 19)   //If time is between 7am and 7pm print day time setting)
    {                                       //It will later call a function to check if the temp is between a value
      Serial.println("Day time setting");     // and then turn a relay on for the freezer if not the correct setting
    }
    else                                    // if it is not set to day time - set to night time. Which will call a function
    {                                       // that turns on the freezer if not the correct "Night time" temp.
      Serial.println("Night time setting");
    }
  }
 
  int Nighttime
{
  if(temperatureC > NIGHTHIGH){
  digitalWrite(c.relayPin, High);
  }
 
  else if(temperatureC < NIGHTLOW){
    (digitalWrite(c.relayPin, Low);
  }
}


int Daytime
{
   if(temperatureC > DAYHIGH) {
   digitalWrite(c.relayPin, High);
   }
   
   else if(temperatureC < DAYLOW) {
     (digitalWrite(c.relayPin, Low);
   }
}
}


First I defined the four different temperature paramiters that I needed, and then wrote the two sub routines that should be called in the place of Serial.println("Day time setting") and Serial.println("Night time setting");. I'm not sure of how to call the sub routines after the first If/Else statements, like what to replace the Serial.println("Day time setting") with so that it will jump to that routine. Also do I need to name the main routine - int main and include a return at the end of my subs or will it do that automatically. Anything else you see wrong just let me know.

Thanks again for your help

PaulS

Code: [Select]
  analogRead(tempPin);
If you are going to throw away the value, why bother?

Code: [Select]
  {
    if (now.hour() >= 7 && now.hour() <= 19)   //If time is between 7am and 7pm print day time setting)
    {                                       //It will later call a function to check if the temp is between a value
      Serial.println("Day time setting");     // and then turn a relay on for the freezer if not the correct setting
    }
    else                                    // if it is not set to day time - set to night time. Which will call a function
    {                                       // that turns on the freezer if not the correct "Night time" temp.
      Serial.println("Night time setting");
    }
  }

What are the outer braces for? They are not needed.

Code: [Select]
  int Nighttime
{
  if(temperatureC > NIGHTHIGH){
  digitalWrite(c.relayPin, High);
  }
 
  else if(temperatureC < NIGHTLOW){
    (digitalWrite(c.relayPin, Low);
  }
}

Function definitions MUST have parentheses, even if there are not arguments. Functions can not be defined inside other functions.

You really should out each { on it's own line, and use Tools + Auto format to make your code readable.

Once you get your functions properly defined, in the right place, you just call them.
Code: [Select]
   Nighttime();

njsmith1

Thanks Paul - That analogRead(tempPin); was from when I was trying to solve another issue and it was no longer needed. The following code has included the routine with Auto-format. I also took out the calculation for fahrenheit as I only need Celsius. I also defined which pin I am going to use as an output and defined it.
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -20
#define NIGHTLOW -22
#define DAYHIGH -4
#define DAYLOW -6
[b]#define aref_voltage 3.3 [/b]

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 7

void setup () {
  Serial.begin(9600);
  Wire.begin();
  pinMode(relayPin, HIGH);
  analogReference(EXTERNAL);
}

void loop() {

  analogRead(photocellPin);
  delay(10);
  photocellReading = analogRead(photocellPin); 

  Serial.print("Light reading = ");
  Serial.print(photocellReading);     // The analog reading


    if (photocellReading < 10) {        //Thresholds for Photocell
    Serial.println(" - Dark");
  }
  else if (photocellReading < 200) {
    Serial.println(" - Dim");
  }
  else if (photocellReading < 500) {
    Serial.println(" - Light");
  }
  else if (photocellReading < 800) {
    Serial.println(" - Bright");
  }
  else {
    Serial.println(" - Very bright");
  }

  tempReading = analogRead(tempPin); 

  Serial.print("Temp reading = ");
  Serial.print(tempReading);     // The analog reading

    // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  Serial.print(temperatureC);                   //to degrees ((volatge - 500mV) times 100)
  Serial.println(" degrees C");

  DateTime now = RTC.now();                   // Get time from the RTC chip

  Serial.print("The time is:");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  delay(1000);


  if (now.hour() >= 7 && now.hour() <= 19)   //If time is between 7am and 7pm print Day time setting)
  {
    int Daytime();
    Serial.println(Day time setting);        // Display what Setting we are currently in
  }
  else                                     //Else set to Night time setting 
  {                                 
    int Nighttime();
    Serial.println(Night time setting);      // Display what Setting we are currently in
  }


  int Nighttime()  {                     

    if (temperatureC > NIGHTHIGH)             //Check temp and compare with setting and set the output accordingly
      digitalWrite(relayPin, HIGH);


    else if (temperatureC < NIGHTLOW)
      digitalWrite(relayPin, LOW);
  }

}


Its most unfortunate that the compiler for the arduino doesn't show you the line numbers to follow the errors better but this is what I am getting.

Complex_TempLight_Clock_pde_pde:6: error: expected unqualified-id before numeric constant (From line #define aref_voltage 3.3)
Complex_TempLight_Clock_pde_pde:18: error: expected ',' or ';' before 'void'
Complex_TempLight_Clock_pde_pde.cpp: In function 'void loop()':
Complex_TempLight_Clock_pde_pde:80: error: 'Day' was not declared in this scope
Complex_TempLight_Clock_pde_pde:85: error: 'Night' was not declared in this scope
Complex_TempLight_Clock_pde_pde:89: error: a function-definition is not allowed here before '{' token

I tried researching even just the first error. I am defining my reference voltage as the 3.3v instead of the 5.0v for better precision and according to a couple examples Ive found, I did it correctly. I did restart the comp and program just in case it needed a reset because I wasn't getting that error before. But alas it is still there. Let me know what you think. Thanks

dxw00d

#5
Feb 26, 2012, 09:20 am Last Edit: Feb 26, 2012, 03:15 pm by dxw00d Reason: 1
This compiles:
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -20
#define NIGHTLOW -22
#define DAYHIGH -4
#define DAYLOW -6
#define aref_voltage 3.3

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 7;
float temperatureC;

void setup()
{
 Serial.begin(9600);
 Wire.begin();
 pinMode(relayPin, HIGH);
 analogReference(EXTERNAL);
}

void loop()
{
//  analogRead(photocellPin);
//  delay(10);
 photocellReading = analogRead(photocellPin);  

 Serial.print("Light reading = ");
 Serial.print(photocellReading);     // The analog reading

 if (photocellReading < 10)
 {        //Thresholds for Photocell
   Serial.println(" - Dark");
 }
 else if (photocellReading < 200)
 {
   Serial.println(" - Dim");
 }
 else if (photocellReading < 500)
 {
   Serial.println(" - Light");
 }
 else if (photocellReading < 800)
 {
   Serial.println(" - Bright");
 }
 else
 {
   Serial.println(" - Very bright");
 }

 tempReading = analogRead(tempPin);  

 Serial.print("Temp reading = ");
 Serial.print(tempReading);     // The analog reading

   // converting that reading to voltage, which is based off the reference voltage
 float voltage = tempReading * aref_voltage / 1024;

 // now print out the temperature
 temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
 Serial.print(temperatureC);                   //to degrees ((volatge - 500mV) times 100)
 Serial.println(" degrees C");

 DateTime now = RTC.now();                   // Get time from the RTC chip

 Serial.print("The time is:");
 Serial.print(now.hour(), DEC);
 Serial.print(':');
 Serial.print(now.minute(), DEC);
 Serial.print(':');
 Serial.print(now.second(), DEC);
 Serial.println();

 delay(1000);

 if ((now.hour() >= 7) && (now.hour() <= 19))   //If time is between 7am and 7pm print Day time setting)
 {
   Daytime();
   Serial.println("Day time setting");        // Display what Setting we are currently in
 }
 else                                     //Else set to Night time setting  
 {                                
   Nighttime();
   Serial.println("Night time setting");      // Display what Setting we are currently in
 }
}

void Nighttime()  
{                    
 if (temperatureC > NIGHTHIGH)  //Check temp and compare with setting and set the output accordingly
 {
   digitalWrite(relayPin, HIGH);
 }
 else if (temperatureC < NIGHTLOW)
 {
   digitalWrite(relayPin, LOW);
 }
}

void Daytime()
{
 // you need to write this.
}


I'll let you compare it to yours, and figure out the differences.

PaulS

#6
Feb 26, 2012, 03:10 pm Last Edit: Feb 26, 2012, 03:11 pm by PaulS Reason: 1
Quote
I'll let you compare it to yours, and figure out the differences.

Pay particular attention to the presence/absence of semicolons.

Quote
You really should out each { on it's own line, and use Tools + Auto format to make your code readable.

njsmith1

So I thought I would post the changes that I saw so that if anyone else is having troubles like mine that they can see it.
     he main difference between the two codes is that I originally had a function in a function. I needed to declare my subroutines separately by putting naming them void Nighttime() and void Daytime(). This takes them out of the main routine named void loop().
    Another addition was in the setup where temperatureC was defined as a float. Naming this as a float makes the Temperature a value with a decimal point. I read that a floating point math is alot slower then integer math, but since I'm not doing that much math with the temperature value this should be ok.
I have gone through the code and made sure i entered all the {} onto their own lines and used the auto format. This is teaching me alot and I appreciate your help.

The next step is getting it to write to an SD card as well as display it (right now on serial monitor, next on LCD screen). I have the Data logger shield from Adafruit http://www.ladyada.net/make/logshield/lighttemp.htmland had it logging data with the light and temperature logging sketch from GitHub. I then have taken some of the code and tried to implement it in my sketch. I got it compiling fine with no errors. But now it is not showing anything on the serial port, or logging any data to the SD card. Any Ideas?
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -19
#define NIGHTLOW -21
#define DAYHIGH -4
#define DAYLOW -6
#define aref_voltage 3.3

// For Data Logging
#include <SD.h>
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)
#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()
const int chipSelect = 10;
File logfile;

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 7;
float temperatureC;

void setup()
{
  Serial.begin(9600);           // sets Bud rate to 9600
  Wire.begin();
  pinMode(relayPin, HIGH);      // sets relay pin as output
  analogReference(EXTERNAL);

  //everything below in this loop is for data logging
  char filename[] = "LOGGER00.CSV";   //Create new file on SD card
  for (uint8_t i = 0; i < 100; i++)
  {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename))         // only open a new file if it doesn't exist
    {   
      logfile = SD.open(filename, FILE_WRITE);
    }
  }
  logfile.println("Light,Temp,Datetime,Setting");  // Create these headings in the log (excel) file
}

void loop()
{
  photocellReading = analogRead(photocellPin);  //Get the reading from the sensor

  if (photocellReading < 10)   //Thresholds for Photocell
  {       
    Serial.println("Dark");
  }
  else if (photocellReading < 200)
  {
    Serial.println("Dim");
  }
  else if (photocellReading < 500)
  {
    Serial.println("Light");
  }
  else if (photocellReading < 800)
  {
    Serial.println("Bright");
  }
  else
  {
    Serial.println("Very bright");
  }

  tempReading = analogRead(tempPin); 

  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC);
  Serial.println(" degrees C");

  logfile.print(", ");                        //Logging the photocell and temp
  logfile.print(photocellReading);
  logfile.print(", ");   
  logfile.print(temperatureC);

  DateTime now = RTC.now();                   // Get time from the RTC chip

  logfile.print('"');                         //Logging the Date and Time
  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('"');

  Serial.print("Time:");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

 
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); // delay for the amount of time between readings
 
  uint32_t m = millis();      // log milliseconds since starting
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");     

  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  delay(1000);

  if ((now.hour() >= 7) && (now.hour() <= 19))   //If time is between 7am and 7pm print Day time setting)
  {
    Daytime();
    Serial.println("Temp set to -5'C");    // Display what Setting we are currently in
    logfile.print(",");
    logfile.print("Daytime setting = -5'C");
  }
  else                                     //Else set to Night time setting 
  {                                 
    Nighttime();
    Serial.println("Temp set to -20'C");      // Display what Setting we are currently in
    logfile.print(",");
    logfile.print("Daytime setting = -20'C");
  }

}

void Nighttime() 
{                     
  if (temperatureC > NIGHTHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < NIGHTLOW)
  {
    digitalWrite(relayPin, LOW);
  }
}

void Daytime()
{
  if (temperatureC > DAYHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < DAYLOW)
  {
    digitalWrite(relayPin, LOW);
  }


}


As an aside - Im asking about code, but if I should be posting in the project guidance section just let me know. And for intrest sake, I attached a picture of the circuit and datalogger shield with the Arduino.

PaulS

Quote
But now it is not showing anything on the serial port, or logging any data to the SD card. Any Ideas?

Add Serial.print() statements to setup(), before trying to open the file. See if they appear.

There is no code to initialize the SD card reader. I'm pretty sure some is required.

Code like this:
Code: [Select]
  DateTime now = RTC.now();                   // Get time from the RTC chip

  logfile.print('"');                         //Logging the Date and Time
  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('"');

should be in a function. It is the kind of code that either works or it doesn't. There is no in-between. So, having in loop just clutters up loop.

Code: [Select]
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); // delay for the amount of time between readings
There is no reason for any delay()s in your code. Keep track of when you last logged. Log again if it is time.

Code: [Select]
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
Personally, I hate to see return in loop(). If the idea is to not execute the rest of the code unless a condition is true, the if statement can be rewritten.
Code: [Select]
if(millis() - syncTime >= SYNC_INTERVAL)
{
   // Execute the rest of the code
}

njsmith1

So I went back to the example that I had working and added some more stuff and got it working. The data thats printed on the serial monitor has slowed alot so I think a clean up or something is in order - suggestions are welcome. Paul im not sure how to put this function into its own loop.
Quote
Code like this:
Code:

  DateTime now = RTC.now();                   // Get time from the RTC chip

  logfile.print('"');                         //Logging the Date and Time
  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('"');

should be in a function. It is the kind of code that either works or it doesn't. There is no in-between. So, having in loop just clutters up loop.


The most recent code looks like this:

Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -19
#define NIGHTLOW -21
#define DAYHIGH -4
#define DAYLOW -6
#define aref_voltage 3.3

// For Data Logging
#include <SD.h>
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)
#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()
#define redLEDpin 2
#define greenLEDpin 3
const int chipSelect = 10;
File logfile;

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 7;
float temperatureC;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
 
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup()
{
 
  Serial.begin(9600);
  Serial.println();
 
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
 
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");    // make sure that the default chip select pin is set to
  pinMode(10, OUTPUT);                        // output, even if you don't use it:
 
  if (!SD.begin(chipSelect))                  // see if the card is present and can be initialized:
  {         
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
 
  // create a new file
  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))        // only open a new file if it doesn't exist
    {         
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }
 
  if (! logfile)
  {
    error("couldnt create file");
  }
 
  Serial.print("Logging to: ");
  Serial.println(filename);

  Wire.begin();       // connect to RTC
  if (!RTC.begin())
  {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 
  logfile.println("Light,Temp,Datetime,Setting");  // Create these headings in the log (excel) file
 
  analogReference(EXTERNAL);
}

void loop()
{
  photocellReading = analogRead(photocellPin);  //Get the reading from the sensor

  if (photocellReading < 10)   //Thresholds for Photocell
  {       
    Serial.println("Dark");
  }
  else if (photocellReading < 200)
  {
    Serial.println("Dim");
  }
  else if (photocellReading < 500)
  {
    Serial.println("Light");
  }
  else if (photocellReading < 800)
  {
    Serial.println("Bright");
  }
  else
  {
    Serial.println("Very bright");
  }

  tempReading = analogRead(tempPin); 

  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

                                                // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                                //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC);
  Serial.println(" degrees C");

  logfile.print(", ");                           //Logging the photocell and temp
  logfile.print(photocellReading);
  logfile.print(", ");   
  logfile.print(temperatureC);


 
  DateTime now = RTC.now();                   // Get time from the RTC chip
 
  logfile.print(", ");
  logfile.print('"');                         //Logging the Date and Time
  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('"');

  Serial.print("Time:");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();     

  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  if ((now.hour() >= 7) && (now.hour() <= 19))   //If time is between 7am and 7pm print Day time setting)
  {
    Daytime();
    Serial.println("Temp set to -5'C");    // Display what Setting we are currently in
    logfile.print(",");
    logfile.print("Daytime setting = -5'C");
  }
  else                                     //Else set to Night time setting 
  {                                 
    Nighttime();
    Serial.println("Temp set to -20'C");      // Display what Setting we are currently in
    logfile.print(",");
    logfile.print("Daytime setting = -20'C");
  }

    logfile.println();
    #if ECHO_TO_SERIAL
    Serial.println();
    #endif // ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);
 
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);
 
}

void Nighttime() 
{                     
  if (temperatureC > NIGHTHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < NIGHTLOW)
  {
    digitalWrite(relayPin, LOW);
  }
}

void Daytime()
{
  if (temperatureC > DAYHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < DAYLOW)
  {
    digitalWrite(relayPin, LOW);
  }

   delay(1000);

}



Any thoughts on how to get this to run faster would be appreciated. I have also attached the most recent data collection. If you open it up, you can see that it takes the program 2 lines to start getting into the swing of things. Im sure this is only an order of events problem.
The only other thing that Im looking at is how to delete the old data files off the SD card. I found that its not as simple as just clicking delete lol but with a little research it should be good.

njsmith1

Here is the excel document with the data

PaulS

Quote
im not sure how to put this function into its own loop.

That isn't a function. It is some code that currently is in a function called loop().

Code: [Select]
void logDate()
{
  DateTime now = RTC.now();                   // Get time from the RTC chip

  logfile.print('"');                         //Logging the Date and Time
  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('"');
}


Then, where that code was in loop(), put:
Code: [Select]
  logDate();

njsmith1

Ok so was going good. I sauldered on the relay to the freezer and ran the program. The only problem is that it doesnt appear to be following the code. Here is the code that I am using, and I will explain below.
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -19   
#define NIGHTLOW -21   
#define DAYHIGH -4
#define DAYLOW -6
#define aref_voltage 3.3

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 6;
float temperatureC;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(relayPin, HIGH);      // sets relay pin as output
  analogReference(EXTERNAL);
}

void loop()

{
  photocellReading = analogRead(photocellPin); 

  if (photocellReading < 10)
  {     
    Serial.println("Dark");
  }
  else if (photocellReading < 200)
  {
    Serial.println("Dim");
  }
  else if (photocellReading < 500)
  {
    Serial.println("Light");
  }
  else if (photocellReading < 800)
  {
    Serial.println("Bright");
  }
  else
  {
    Serial.println("Very bright");
  }

  tempReading = analogRead(tempPin); 

  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC);
  Serial.println(" degrees C");

  DateTime now = RTC.now();                   // Get time from the RTC chip

  Serial.print("Time:");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  delay(1000);

  if ((now.hour() >= 7) && (now.hour() < 19))   //If time is between 7am and 7pm print Day time setting)
  {
    Daytime();
    Serial.println("Temp set to -5'C");        // Display what Setting we are currently in
  }
  else                                     //Else set to Night time setting 
  {                                 
    Nighttime();
    Serial.println("Temp set to -20'C");      // Display what Setting we are currently in
  }

  Serial.print("The Relay pin is set = ");
  Serial.println(digitalRead(relayPin));

}


void Nighttime() 
{                     
  if (temperatureC > NIGHTHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < NIGHTLOW)
  {
    digitalWrite(relayPin, LOW);
  }
}

void Daytime()
{
  if (temperatureC > DAYHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
  }
  else if (temperatureC < DAYLOW)
  {
    digitalWrite(relayPin, LOW);
  }
}

It correctly displays time, the temperature, the brightness but it consistently displays the relay pin as low (0). This is the code that I had in there to do this
Code: [Select]
Serial.print("The Relay pin is set = ");
  Serial.println(digitalRead(relayPin));


Also, a larger issue - when I run the program, it displays that is at the correct setting, but it always outputs a high and does not toggle off when it reaches the DAYLOW, or NIGHTLOW. It just keeps it on all the time. I did try forcing the pin high and low and read the voltages coming out of the relay and it did change accordingly but the monitor still showed a low (0). My voltages at the relay were 1.23V as HIGH, and 0V as LOW. So I know that it is going to the correct Daytime, or Nighttime routine, I know it can toggle from forcing it low and high and the freezer responding accordingly, but it just isnt following the program and switching at the set temperatures within the Daytime and Nighttime routines. Does anyone have any ideas? Attached is a print screen of the serial monitor notice how the temperature, light, and temp setting are displaying correctly. But the relay pin shows low (0) and the freezer is still running. It says that it is running in daytime mode - so the max temperature it should reach is a little over -6 and it is at -11.01 and still climbing.
 

PaulS

Code: [Select]
  pinMode(relayPin, HIGH);      // sets relay pin as output
Do you then turn the pin pn and off using INPUT and OUTPUT?

Quote
Also, a larger issue - when I run the program, it displays that is at the correct setting

That what is at the correct setting?

Quote
but it always outputs a high and does not toggle off when it reaches the DAYLOW, or NIGHTLOW.

Perhaps it has to do with the incorrect mode you are using.

Like error messages from the compiler, you need to correct the first problem and see what that does about the rest of the issues.

njsmith1

Hey, so I went back and I was declaring the Digital I/O pin wrong. It should have been pinmode (relayPin, OUTPUT) not pinmode (relayPin, HIGH). I also went back and added in the settings (NIGHTHIGH, NIGHTLOW ect.) as a float because I thought that since the temperature reading had decimal places this could have caused an issue.
The code reads temperature and the time good, It compares them correctly and prints to the serial screen that it is on the correct setting. BUT - it does not turn off when it reaches the low parameter - it seems that once it gets to the void loop, it just turns on the freezer and keeps it on. I also noticed another problem - when i put in a positive value for the daytime parameters the serial monitor only displays this:
Dark                    //Light setting
-3.23 degrees C     //Temp
Time: 17:43:24      //Time
Temp set to -5'C     //Setting (Daytime)

but does not display
HIGH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   //relay pin high

even though the freezer is still running. I dont understand why a positive number would make it skip just that one part, and i dont understand how it will jump to the correct subroutine but only turns the freezer on but never off. Here is my code:

Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#define NIGHTHIGH -19.00   
#define NIGHTLOW -21.00   
#define DAYHIGH 3.00
#define DAYLOW -6.00
#define aref_voltage 3.3

RTC_DS1307 RTC;

int tempReading;
int tempPin = 1;
int photocellReading;
int photocellPin = 2;
int relayPin = 6;
float temperatureC;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(relayPin, OUTPUT);      // sets relay pin as output
  analogReference(EXTERNAL);
}

void loop()
{
  photocellReading = analogRead(photocellPin); 

  if (photocellReading < 10)
  {     
    Serial.println("Dark");
  }
  else if (photocellReading < 200)
  {
    Serial.println("Dim");
  }
  else if (photocellReading < 500)
  {
    Serial.println("Light");
  }
  else if (photocellReading < 800)
  {
    Serial.println("Bright");
  }
  else
  {
    Serial.println("Very bright");
  }

  tempReading = analogRead(tempPin); 
 
  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((volatge - 500mV) times 100)
  Serial.print(temperatureC); Serial.println(" degrees C");

  DateTime now = RTC.now();                   // Get time from the RTC chip
 
  Serial.print("Time:");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  delay(1000);
 
  if (now.hour() >= 7 && now.hour() <= 19)   //If time is between 7am and 7pm print Day time setting)
  {
    Daytime();
    Serial.println("Temp set to -5'C");        // Display what Setting we are currently in
  }
  else                                     //Else set to Night time setting 
  {                                 
    Nighttime();
    Serial.println("Temp set to -20'C");      // Display what Setting we are currently in
  }
   
}

void Nighttime() 
{                     
  if (temperatureC > (float)NIGHTHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
    if (relayPin = HIGH)
      {
        Serial.println("HIGH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      }
  }
  else if (temperatureC < (float)NIGHTLOW)
  {
    digitalWrite(relayPin, LOW);
    if (relayPin = LOW)
      {
        Serial.println("OFFFFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      }
  }
}

void Daytime()
{
  if (temperatureC > (float)DAYHIGH)  //Check temp and compare with setting and set the output accordingly
  {
    digitalWrite(relayPin, HIGH);
    if (relayPin = HIGH)
      {
        Serial.println("HIGH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      }
  }
  else if (temperatureC < (float)DAYLOW)
  {
    digitalWrite(relayPin, LOW);
    if (relayPin = LOW)
      {
        Serial.println("OFFFFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      }
  }
}



Thanks

Go Up