Sketch shortening possible?

I made a working weather station sketch that MAY be able to be shortened to use less storage. Any help would be very appreciated.

#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <SFE_BMP180.h>
#include <Wire.h>
#include “RTClib.h”
#define DHTPIN 2
#define DHTPIN2 11
#define DHTTYPE DHT11
#define ALTITUDE xxx.0 //Station altitude in meters
DHT dht(DHTPIN, DHTTYPE);
DHT dht2 (DHTPIN2, DHTTYPE);
SFE_BMP180 pressure;
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,20,4);
float tF;
float t2F;
float dP;
float dPF;
int DHTgnd = 5;
int DHTvcc = 6;
int DHTgnd2 = 10;
int DHTvcc2 = 12;

void setup() {
Serial.begin(9600);
Serial.println( );
// provide power to the DHT
pinMode(DHTgnd,OUTPUT);
pinMode(DHTvcc,OUTPUT);
digitalWrite(DHTgnd,LOW);
digitalWrite(DHTvcc,HIGH);
dht.begin();
dht2.begin();
pinMode(DHTgnd2,OUTPUT);
pinMode(DHTvcc2,OUTPUT);
digitalWrite(DHTgnd2,LOW);
digitalWrite(DHTvcc2,HIGH);
RTC.begin();

if (pressure.begin())
Serial.println( );
else
{

Serial.println(“BMP180 init fail\n\n”);
while(1);
}
}

void loop() {
char status;
double T,P,p0,a;
Serial.print (“Lat:xx.xx,Lon:xxx.xx, xxx FtASL”); //LAT & LONG with Elevation of station
Serial.println();
DateTime now = RTC.now();
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
char DOW[4]={“SUN”,“MON”,“TUE”,“WED”,“THU”,“FRI”,“SAT”};
//lcd.print(DOW[now.dayOfWeek()]);
Serial.print(DOW[now.dayOfWeek()]);
lcd.print(" “);
Serial.print(” “);
if (now.month() < 10) lcd.print(“0”); // Check if we need to add leading zero
lcd.print(now.month(), DEC);
if (now.month() < 10) Serial.print(“0”); // Check if we need to add leading zero
Serial.print(now.month(), DEC);
lcd.print(”/");
Serial.print("/");
if (now.day() < 10) lcd.print(“0”); // Check if we need to add leading zero
lcd.print(now.day(), DEC);
if (now.day() < 10) Serial.print(“0”); // Check if we need to add leading zero
Serial.print(now.day(), DEC);
lcd.print("/");
Serial.print("/");
lcd.print(now.year(), DEC);
Serial.print(now.year(), DEC);
lcd.print(" “);
Serial.print(” “);
if (now.hour() < 10) lcd.print(“0”); // Check if we need to add leading zero
lcd.print(now.hour(), DEC);
if (now.hour() < 10) Serial.print(“0”); // Check if we need to add leading zero
Serial.print(now.hour(), DEC);
lcd.print(”:");
Serial.print(":");
if (now.minute() < 10) lcd.print(“0”); // Check if we need to add leading zero
lcd.print(now.minute(), DEC);
if (now.minute() < 10) Serial.print(“0”); // Check if we need to add leading zero
Serial.print(now.minute(), DEC);
lcd.print(":");
Serial.print(":");
if (now.second() < 10) lcd.print(“0”); // Check if we need to add leading zero
lcd.print(now.second(), DEC);
if (now.second() < 10) Serial.print(“0”); // Check if we need to add leading zero
Serial.print(now.second(), DEC);
Serial.println();

status = pressure.startTemperature();
if (status != 0)
{

delay(status);

status = pressure.getTemperature(T);
if (status != 0)
{

status = pressure.startPressure(2);
if (status != 0)
{

delay(status);

status = pressure.getPressure(P,T);
if (status != 0)
{
lcd.setCursor(1, 2);
lcd.print(" BMP:");
Serial.print(“BMP: “);
Serial.print(P,2);
Serial.print(” mb, “);
lcd.print(P0.0295333727,2);
Serial.print(P
0.0295333727,2);
lcd.print(” inHg”);
Serial.println(" in");

}
else Serial.println(“error retrieving pressure measurement\n”);
}
else Serial.println(“error starting pressure measurement\n”);
}
else Serial.println(“error retrieving temperature measurement\n”);
}
else Serial.println(“error starting temperature measurement\n”);

float h = dht.readHumidity();
float t = dht.readTemperature();
float h2 = dht2.readHumidity();
float t2 = dht2.readTemperature();

{
lcd.setCursor(2, 1);
lcd.print(“H:”);
Serial.print(“Hum%:”);
lcd.print(h);
lcd.print("% “);
Serial.print(h);
lcd.print(“T:”);
Serial.print(” TempF:");
tF=((t9)/5)+32;
lcd.print(tF);
lcd.print(“F”);
Serial.print(tF);
Serial.println();
lcd.setCursor(0, 2);
Serial.print("DP
F:");
dP=(dewPointFast(t, h));
dPF=((dP9)/5)+32;
Serial.print(dPF);
Serial.print(" ");
Serial.print("HtIdx
F:");
Serial.print(heatIndex(tF,h));
Serial.println();
lcd.setCursor(0,3);
lcd.print(“InH:”);
Serial.println(“Inside Hum%:”);
lcd.print(h2);
Serial.print(h2);
Serial.println();
lcd.print(" InT:");
Serial.print("Inside TempF:");
Serial.println();
t2F=((t2
9)/5)+32;
lcd.print(t2F);
lcd.print(“F”);
Serial.print(t2F);
Serial.println();
delay(60000); //Get information at 1 minute intervals
}
}

double dewPointFast(double celsius, double humidity)
{
double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
double Td = (b * temp) / (a - temp);
return Td;
}

double heatIndex(double tempF, double humidity)
{
double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6 ;
double T = tempF;
double R = humidity;

double A = (( c5 * T) + c2) * T + c1;
double B = ((c7 * T) + c4) * T + c3;
double C = ((c9 * T) + c8) * T + c6;

double rv = (C * R + B) * R + A;
return rv;

}

It won't make your sketch much shorter, but getting stuff likeSerial.print ("Lat:xx.xx,Lon:xxx.xx, xxx FtASL");into flash using the F() macros will save precious RAM.

Use code tags when posting code, please.

Sorry, first posting on forum.

Welcome to the Forum. Please read the second and third posts at the top of this Forum by Nick Gammon, as they tell you how to get the most help from the readers here. Also, make sure you use the source code tags to post your code.

A few things: First, in your function:

double heatIndex(double tempF, double humidity)
{
  double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6  ;
  double T = tempF;
  double R = humidity;

  double A = (( c5 * T) + c2) * T + c1;
  double B = ((c7 * T) + c4) * T + c3;
  double C = ((c9 * T) + c8) * T + c6;

  double rv = (C * R + B) * R + A;
  return rv;
  
}

you pass tempF and humidity in as parameters, but immediate assign them to new variables. This wastes memory. Also, for most Arduino boards, there is no real double data type...they are floats, so you may as well use float. There are some other temporary variables that you can get rid of, too.

While it won't make much difference, you can use arrays to simplify things. You can write:

 double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6  ;

as

 float myConstants[] = {-42.38, 2.049, 10.14, -0.2248, -6.838e-3, -5.482e-2, 1.228e-3,
                                    8.528e-4, -1.99e-6}  ;

and replace line like:

  double A = (( c5 * T) + c2) * T + c1;

with:

  float A = (( myConstants[4] * T) + myConstants[1]) * T + myConstants[0];

It may not shorten your code but it would sure make it more easy to understand and to maintain if you were to split it into several short functions each of which just does one little piece.

This Thread planning and implementing a program illustrates the idea.

...R

This pattern is occurring 6 times (or so)

   if (now.month() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.month(), DEC);  
  if (now.month() < 10) Serial.print("0"); // Check if we need to add leading zero
  Serial.print(now.month(), DEC);

wrap it in a function

void displayField(int value)
{
  if (value < 10)
  {
    lcd.print("0"); // Check if we need to add leading zero
    Serial.print("0"); // Check if we need to add leading zero
  }
  lcd.print(value, DEC);  
  Serial.print(value, DEC);
}

and it skips one test

code becomes

char DOW[][4]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
  //lcd.print(DOW[now.dayOfWeek()]);
  Serial.print(DOW[now.dayOfWeek()]);
  lcd.print(" ");
  Serial.print(" ");
  displayField(now.month());
  lcd.print("/");
  Serial.print("/");

  displayField(now.day());
  lcd.print("/");
  Serial.print("/");

  displayField(now.year());
  lcd.print(" ");
  Serial.print(" ");

  displayField(now.hour());
  lcd.print(":");
  Serial.print(":");

  displayField(now.minute());
  lcd.print(":");
  Serial.print(":");

  displayField(now.second());

  Serial.println();

as every displayField call has a char/separator in front. We can refactor that in

void displayField(char *str, int value, )  // could be a char but this is more flex
{
  lcd.print(str);  
  Serial.print(str);
  if (value < 10)  // Check if we need to add leading zero
  {
    lcd.print("0"); 
    Serial.print("0");
  }
  lcd.print(value, DEC);  
  Serial.print(value, DEC);  
}

code becomes

char DOW[][4]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
  //lcd.print(DOW[now.dayOfWeek()]);
  Serial.print(DOW[now.dayOfWeek()]);

  displayField(" ", now.month());
  displayField("/", now.day());
  displayField("/", now.year());
  displayField(" ", now.hour());
  displayField(":", now.minute());
  displayField(":", now.second());

  Serial.println();

please add some empty lines for readability (at the top), and remove double blank lines
some comment might enlight you when you see the code in 3 months time :wink:

#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <SFE_BMP180.h>
#include <Wire.h>
#include "RTClib.h"

// DHT 
#define DHTPIN 2
#define DHTPIN2 11
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);
DHT dht2 (DHTPIN2, DHTTYPE);
int DHTgnd = 5;
int DHTvcc = 6;
int DHTgnd2 = 10;
int DHTvcc2 = 12;

// PRESSURE 
#define ALTITUDE xxx.0 //Station altitude in meters
SFE_BMP180 pressure;

// CLOCK
RTC_DS1307 RTC;

// DISPLAY
LiquidCrystal_I2C lcd(0x27,20,4);

// ???
float tF;
float t2F;
float dP;
float dPF;

void setup() 
{
  Serial.begin(9600);
  Serial.println(ËNTER YOUR SKETCH NAME HERE" );

  if (pressure.begin())
  {
    Serial.println("BMP180 OK!");
  }
  else
  {
    Serial.println("BMP180 init fail\nProgram halted");
    while(1);
  }

  // INITIALIZE DHT 
  pinMode(DHTgnd,OUTPUT); 
  pinMode(DHTvcc,OUTPUT); 
  digitalWrite(DHTgnd,LOW);   
  digitalWrite(DHTvcc,HIGH); 
  pinMode(DHTgnd2,OUTPUT); 
  pinMode(DHTvcc2,OUTPUT); 
  digitalWrite(DHTgnd2,LOW);   
  digitalWrite(DHTvcc2,HIGH);
  dht.begin();
  dht2.begin();


  // INITIALIZE CLOCK
  RTC.begin();
}

void loop()
{
  char status;
  double T,P,p0,a;

  DateTime now = RTC.now();

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);

  Serial.print ("Lat:xx.xx,Lon:xxx.xx, xxx FtASL"); //LAT & LONG with Elevation of station
  Serial.println();

 char DOW[][4]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
  //lcd.print( DOW[ now.dayOfWeek() ] );
  Serial.print( DOW[ now.dayOfWeek() ] );

  displayField(" ", now.month() );
  displayField("/", now.day() );
  displayField("/", now.year() );
  displayField(" ", now.hour() );
  displayField(":", now.minute() );
  displayField(":", now.second() );

  Serial.println();

  ....

Get the idea of readable code… ==> your turn