Help me understand boolean

I am writing a sketch that will switch relay states at predefined times, and/or high/low sensor values. I know my sketch is far from being considered efficiently coded, but in my defense I have language that almost works great… almost.

I know I am needing to get boolean variables added, and also they need to be queried to determine if a state shall be high, and for how long before it reverts back to low, but I am simply unable to grasp the understanding I know I need to effectively use them.

I will attach my entire sketch rather than insert snippets and expect you to know everything else I have therein. This is just so you (my teachers) can get a feel of where I’m at in my understanding of code and advise accordingly. I am not seeking someone to write that snippet per say, but I do wish to learn this stuff as I do intend to share this project with many other gardeners, and want to know the code good enough to further assist others that are yet to get into Arduino.

A link to a good tutorial will probably do me more justice than picking apart my code and renaming my variables and saying things like “you can do this, by changing that” and the like, with no real conveyance of understanding or knowledge.

Thank you all in advance!

#include "DHT.h" // Temp/Humidity Sensor Library
#include <Wire.h> // i2c communications Library
#include "RTClib.h" // RealTimeClock Library for DS1307 and DS3231

#define RELAY_ON 1 // RELAY_ON and RELAY_OFF may need to swich values to work properly
#define RELAY_OFF 0 // Used to switch relay states for on/off of AC devices

#define Relay_A  30  // relay 1 - 
#define Relay_B  31  // relay 2 - 
#define Relay_C  32  // relay 3 - 
#define Relay_D  33  // relay 4 -
#define Relay_E  34  // relay 5 -
#define Relay_F  35  // relay 6 -
#define Relay_G  36  // relay 7 - 
#define Relay_H  37  // relay 8 - 

// Sensor Declaration
#define DHTPIN A2 // DHT22 data wire is connected to Analog 2 pin.  A 10k pullup resistor is needed to connect data to +5V
#define DHTTYPE DHT22

//  Sensor Reference Values
int hiTempDHT = 85; // Max Fahrenheit Value -- Change these around to find what works best for you
int lowTempDHT = 60;  // Min Fahrenheit Value -- Change these around to find what works best for you
int hiHumDHT = 60; // Max Humidity Value -- Change these around to find what works best for you

RTC_DS1307 RTC;

//  declare DHT variables
float h;
float f;

float UTCOffset = -5.0;    // Your timezone relative to UTC (http://en.wikipedia.org/wiki/UTC_offset)


DHT dht(DHTPIN, DHTTYPE);

void setup()
{
  delay( 50 );   // allow some time (50 ms) after powerup and sketch start, for the Wiznet W5100 Reset IC to release
                 // and come out of reset.  http://www.freetronics.com.au/pages/usb-power-and-reset#.VVpp-Eao28g
  Serial.begin(9600);
  //Serial2.begin() // For other baud rates
  //Serial3.begin() // For other baud rates

  //---(Set pins 30-37 as outputs )----
  pinMode(Relay_A, OUTPUT);
  pinMode(Relay_B, OUTPUT);
  pinMode(Relay_C, OUTPUT);
  pinMode(Relay_D, OUTPUT);
  pinMode(Relay_E, OUTPUT);
  pinMode(Relay_F, OUTPUT);
  pinMode(Relay_G, OUTPUT);
  pinMode(Relay_H, OUTPUT);
  delay(1000);

  dht.begin();
  Wire.begin();
  RTC.begin();

  RTC.adjust(DateTime(__DATE__, __TIME__));  //this captures the time from the computer that is uploading sketch to Arduino
                                             // so ensure that the uploading computer has the correct time.
  delay(1000);
}

void loop()
{ //******************************************************************************//
  //****** Setting Time and testing to display 24 hour time as 12 hour time ******//
  //******************************************************************************//
  DateTime now = RTC.now();
  
  int twelveHour = now.hour() - 12; // Variable used to display 13+ hours in 12 hour format
  int zeroHour = 12;                // Variable use to convert "0" zero hour to display it as 12:00+
  
  Serial.print('-');
  Serial.print(' ');
  
  if (now.hour() == 0){              // First we test if the hour reads "0"
  Serial.print (F("AM"));
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  Serial.print(zeroHour);           // if yes, serial print a "12" instead
  }
  else if (now.hour() >= 13){       // if no, Second we test if the hour reads "13 or more"
  Serial.print (F("PM"));
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  Serial.print(twelveHour);         // if yes, serial print that current hour minus 12
  }
  else 
  {
  Serial.print (F("AM"));
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  Serial.print(now.hour(), DEC);    // if no, Third we conclude that the am hours are being displayed correctly.
  }
  {
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  //Serial.print(F("am"));
  //Serial.print(F("PM"));
  Serial.println();

I had to split my code into 2 posts so not to exceed 9600 characters. My board is an EtherMega from Freetronics, but I started this project with a Mega and Ethernet shield.

  //*************************************************************************//
  // Coded alarm triggers for Relays A-D.  Adjust hours and minutes in accordance with 24 hour time format.
  // Major code adjustments are best done when testing in minutes and seconds.
  //****************** 18/6 Light Cycle - RELAY_A ****************************//
  if (now.hour() >= 6 && now.minute() >= 0) {  // Turn on time for Veg Lights, ON at 6am
    digitalWrite(Relay_A, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("Lights On"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() >= 0 && now.minute() >= 0) // "else if" was needed to create opposition to lights on
  {  // Turn off time for Veg Lights, OFF at 12am
    digitalWrite(Relay_A, RELAY_OFF);
    Serial.print("\t");
    Serial.print(F("Lights OFf"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  delay(500);
  //******************** FEED TIMES - RELAY_B ****************************************//
  if (now.hour() == 9 && now.minute() >= 0) {  // Turn on time for FeedPump1, ON 9am
    digitalWrite(Relay_B, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("First 10 Minute Feeding"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() == 9 && now.minute() >= 10) {  // Turn off time for FeedPump1, OFF 9:10am
    digitalWrite(Relay_B, RELAY_OFF);
  }
  delay(500);
  //******************* Second Feed Time *********************************************//
  if (now.hour() == 18 && now.minute() >= 0) {  // Turn on time for FeedPump1, ON 6pm
    digitalWrite(Relay_B, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("Second 10 Minute Feeding"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() == 18 && now.minute() >= 10) {  // Turn off time for FeedPump1, OFF 6:10pm
    digitalWrite(Relay_B, RELAY_OFF);
  }
  delay(500);
  //********************** Heat Mat for Clones - RELAY_C *******************************//
  if (now.hour() >= 2 && now.minute() == 0) {  // Turn on time for HeatMat, ON at 2am
    digitalWrite(Relay_C, RELAY_ON);
  }
  else if (now.hour() == 2 && now.minute() == 50) {  // Turn off time for HeatMat, OFF at 2:50am, will soon be reassigned
    digitalWrite(Relay_C, RELAY_OFF);           // trigger based on DHT values
  }
  delay(500);
  ////////////////////////////////////////////////////////////////////////////////////////
  // if (now.hour() == 21 && now.minute() == 05){   // Turn on time for Relay_C
  //   digitalWrite(Relay_C, RELAY_ON);}
  // if (now.hour() == 21 && now.minute() == 05){   // Turn off time for Relay_C
  //   digitalWrite(Relay_C, RELAY_OFF);
  // if (now.hour() == 21 && now.minute() == 05){   // Turn on time for Relay_D
  //   digitalWrite(Relay_D, RELAY_ON);}
  // if (now.hour() == 21 && now.minute() == 05){   // Turn off time for Relay_D
  //   digitalWrite(Relay_D, RELAY_OFF);}

  // calculate a date which is 7 days and 30 seconds into the future
  DateTime future (now.unixtime() + 7 * 86400L + 30);

  Serial.println();

  Serial.println();
  delay(3000);
  
  //****************************************************************************************//
  //******* Testing the DHT22 sensor values in Fahrenheit and Percent and executing ********// 
  //******* tasks based upon those values
  //****************************************************************************************//

  h = dht.readHumidity();  // assigns humidity reading as "h"
  f = dht.readTemperature(true);  // assigns fahrenheit reading as "f"

  //   Tests temp & humidity to see if preset values are exceed.
  //   If exceeded, a relay is trigger high to power an exhaust fan or heater.

  if ((f) >= (hiTempDHT))  //  "if" current temp in fahrenheit is greater than or equal to preset value
  {
    digitalWrite(Relay_E, RELAY_ON);  // powers on Relay E (exhaust fan).
    Serial.print("\t");
    Serial.print(F("Exhausting the heat!")); //  Text printed to serial monitor
    Serial.print("\t");
  }
  else {
    digitalWrite(Relay_E, RELAY_OFF); //  Otherwise relay E is off.
  }

  if ((f) <= (lowTempDHT))   //  "if" current temp in fahrenheit is less than or equal to preset value
  {
    digitalWrite(Relay_F, RELAY_ON);  // powers on Relay F (heater).
    Serial.print("\t");
    Serial.print(F("Warming the room!"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else {
    digitalWrite(Relay_F, RELAY_OFF);  //  Otherwise Relay F is off.
  }

  if ((h) >= (hiHumDHT))  //  "if" current humidity is greater than or equal to preset value
  {
    digitalWrite(Relay_E, RELAY_ON);  //  powers on Relay E (inlet fan).
    Serial.print("\t");
    Serial.print(F("Drying the air!"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else {
    digitalWrite(Relay_E, RELAY_OFF);  //  Otherwise Relay E is off.
  }


  if (isnan(f) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  }

  else
  {
    float hi = dht.computeHeatIndex(f, h);
    Serial.print(F(" Humidity: "));
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print(F(" Fahrenheit: "));
    Serial.print(f);
    Serial.println(" \t");
  }
  delay(1000);
}
}

What is the program supposed to do ? What does it actually do ? Have you got an explicit problem or a question ?

You treat a boolean like you do any any other variable, ie you assign it a value, and then you read it and do something with the result. In the case of a boolean (and guru's please correct me), it can only have two values, true and false (case sensitive). It can also be represented as 0 (false) or non-0 (true) (within the size allotted for the variable). But I like to stick to true and false as it makes the code easier to read.

So in the case of flags for programming events, just assign true to a boolean if the event has happened, or needs to happen.

Quick Psuedo code for a Motion detection Light:

boolean Motion = false;

void setup()
{ 
  //Setup Code here;
}

void loop{

CheckForMovement();
// Upon detecting movement, set Motion to true,  If no movement is detected, set Motion to false;


If(Motion)  // is the same as if(Motion==true)
{
  TurnLampOn();
}

if(!Motion) // is the same as if(Motion==false)
{
  TurnLampOff();
}

You can simplify that code to read:

If(Motion)
{ 
  TurnLampOn()
}
else
{
  TurnLampOff()
}

Hope that answers your non-question.

myggle: I know I am needing to get boolean variables added, and also they need to be queried to determine if a state shall be high, and for how long before it reverts back to low, but I am simply unable to grasp the understanding I know I need to effectively use them.

Boolean is simply a "yes/no" or "true/false" state. A light bulb on a simple switch is boolean. It's either on or off (as opposed to a light bulb on a dimmer which has an infinite number of states). The way to remember boolean states is to ask "is it empty or not?". For example, zero is boolean false. An empty string is boolean false. A non-zero number (negative or positive) is boolean true. Another thing... declaring a variable as "boolean" doesn't save any space since "boolean" is typedef'd as uint8_t anyway. A piece of code you may have seen in your travels looks something like this:

x == 3 ? lampOn () : lampOff ();

This is just a shorthand way of doing this:

if (x == 3) {
    lampOn ();
} else {
    lampOff ();
}

It's easy to remember like this: IF THIS IS TRUE ? DO THIS : OTHERWISE DO THIS;

Hope this helps....

Heck, that helped me Krupski, thanks.

Sorry for my non question question, I was seeking guidance which was provided and a link(s) to known good tutorials on the subject as I don't wish to take up people's time asking for more insight into (basics?). It's just that what I've read/watched prior to this thread had me still in the dark.

My project is going to be an indoor garden/greenhouse controller. Phase 1 will control all basic AC devices and hopefully soon post the sensor data and coded pin states to my web page. I also have planned for phases 2, 3 and 4, each I expect will be more difficult to learn my way into, than the previous phases, but my desire to build this project is what has brought me here, and what is keeping me here.

Thanks for all the input, I do need to reread it a few times to try and graft it into my understanding.

It's easy to remember like this: IF THIS IS TRUE ? DO THIS : OTHERWISE DO THIS;

Good!

myggle:
I had to split my code into 2 posts so not to exceed 9600 characters.

You can “attach” code to a post.

How to use this forum

In the case of booleans, where we can just check for 'trueness' of it, ie if(foo){}..

does

foo ? bar():rab();

still work?

Marmotjr: In the case of booleans, where we can just check for 'trueness' of it, ie if(foo){}..

does

foo ? bar():rab();

still work?

Yes it does.

does

foo ? bar():rab();

still work?

One of the advantages of the Arduino environment, both hardware and software, is that it only takes a couple of minutes to knock up a test of a question like this.

Think about this. Its convenient to code

if (lighton) {
    // do this 
}
if (lightoff)  {
   // do this
}

but you have to remember that if you change one you must change the other too!

int lighton;
int lightoff;
int power;

enum  State_of_Illumination {on, off};
enum State_of_Illumination lights;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lights = on;
  
}

void loop() {
power =250;
if (power > 0){
  lighton =true;
}
power = 0;
if (power = 0) {
  lightoff =true;
}

// now both lighton and lightoff are true!

//however if we do it this way it can't happen
  

  if (lights == on) {
    Serial.println("lights are on");
  }
  delay(1000);
  lights = off;
  if (lights == off) {
    Serial.println("lights are off");
  }
  delay(1000);
  lights = on;
}
if (power = 0) {

Close, but no cigar.

As to the general principle, why not a single boolean variable then

if (lightsAreOn)
{
  //do stuff when lights are on
}
else
{
  //do stuff when lights are off
}

yes, need == for a comparison check.

DavidI: Think about this. Its convenient to code

if (lighton) {
    // do this 
}
if (lightoff)  {
   // do this
}

but you have to remember that if you change one you must change the other too!

Which is why they invented "else".

if (lighton) {
    // do this 
} else {
   // do this
}
if (lighton) {
    // do this
}
if (lightoff)  {
   // do this
}

For a single element like this that can only have two states, why even bother with two boolean variables? It only seems to add complexity and confusion.

if (lighton) {
    // do this
}
else  {   // not lighton
   // do this
}

I think that there is an echo in here !

Sorry, didn't see the earlier post.