How to get a sensor reading to display on a lcd screen

So with a lot of research and reading, I've been able to blend examples of codes together and end up wi the following code. It starts a timer when I push and hold the start button down. When the speed trap beam is interrupted, it "records" a time and then when the finish line sensor is tripped, it displays the elapsed time from the initial start and the mph which is calculated from the math of finish line sensor - speed trap beam = x time which converts to mph.
I would like to incorporate a second 20 x 4 LCD screen and have it display the elapsed time from the start button to the speed trap sensor being interrupted. I think I can serial display this time but what code is needed to display on a 20x4 screen?

#include <LiquidCrystal_I2C.h>  // LiquidCrystal I2C - Version: 1.1.2
#include <fastIO.h>  // fastIO - Version: Latest 
#include <Wire.h>
#include "DHT.h"
#define DHT11Pin 4
#define DHTType DHT11 //OLED

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

DHT HT(DHT11Pin,DHTType);
float humi;
float tempC;
float tempF;

#define SCREEN_WIDTH 128 // OLED display width, in pixels  
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
LiquidCrystal_I2C lcd(0x27,20,4); // double check your LCD address first using: i2C_scanner

int analogInPin1 = A0;  // Speed Trap beam Analog input Lane 1 A0 Pin
int analogOutPin1 = A1; // Finish line beam lane 1
int analogInPin2 = A3;  // Speed trap beam Analog input Lane 2 A3 Pin
int analogOutPin2 = A2; // Finish line beam lane 2

const int ledPin1 = 11; //lane 1 win LED 
const int ledPin2 = 12; //Lane 2 win LED 
int StartSwitch = 2;

int sensorValueStart1 = 0; 
int sensorValueFinish1 = 0; 
int sensorValueStart2 = 0; 
int sensorValueFinish2 = 0;
int StartState = 0;

int sensorThresh = 800; //adjustable trigger sensing threshold of the IR receivers. 1000 = unblocked(high)

unsigned long timeFirst1; //lane 1 speed trap beam
unsigned long timeSecond1; //lane 1 finish line 
unsigned long timeFirst2; //lane 2 speed trap beam
unsigned long timeSecond2; //lane 2 finish line 
float StartTime = 0;
float StartTime1 = 0;
float trapTime1 = 0;
float velocity1 = 0;
float trapTime2 = 0;
float velocity2 = 0;
float speedConst = 1800; // ((distance between the Speed Gate and Finish IR sensors in mm) x 3600)/1000)to convert mm/millis to km/h) 
                         // In this project we have 500mm between IR sensors on proto board >>> 500x3600/1000 = 1800
float ET1 = 0;
float ET2 = 0;



void setup() 
{

  Serial.begin(9600);
  
  pinMode(StartSwitch, INPUT);
  pinMode(11, OUTPUT); //lane 1
  pinMode(12, OUTPUT); //lane 2
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
  delay(1000);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
    timeSecond1 = 0;
    timeFirst1= 0; 
    timeSecond2 = 0;
    timeFirst2= 0; 
    trapTime2 = 0;
    trapTime1 = 0;
    StartTime = 0;
    
      lcd.init();
      lcd.backlight();
      lcd.setCursor(2,0);
      lcd.print("Drag Strip Timer");    
      lcd.setCursor(3,1);
      lcd.print("by Ricky Kelso"); 
      lcd.setCursor(1,2);
      
      lcd.print("EET411L Sr Project"); 
      delay(2000);
      lcd.setCursor(1,3);
      lcd.print("Ready to race...v6"); 
      
      HT.begin();//For DHT11
    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64  //For OLED I2C
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.display(); //Display logo
  display.clearDisplay();
 pinMode(5, OUTPUT);
   pinMode(6, OUTPUT);
   pinMode(7, OUTPUT);
  delay(3000);
  digitalWrite(5, HIGH);    // turn on LED2
  delay(1000);                 // wait for 200ms
  digitalWrite(5, LOW);     // turn off LED1
 
  digitalWrite(6, HIGH);    // turn on LED2
  delay(1000);
  digitalWrite(6, LOW);     // turn off LED2
  digitalWrite(7, HIGH);    // turn on LED3 
  delay(1000);              // wait for 200ms
  digitalWrite(7, LOW);     
}

void loop() 
{
  
  StartState = digitalRead(StartSwitch); //Check state of start gate. 0 = closed & 1 = open.
  if(StartState == 0)
  {
     StartTime = 0;
     ET1 = 0;
     ET2 = 0;
  }

      // NOTE: Race timer will reset itself when the startgate is closed, so don't close the gate when the race is still going!
  
  StartState = digitalRead(StartSwitch); //if start gate is trigger, race started. 1 = open.
  if(StartState == 1 && StartTime == 0)
  {
    StartTime = micros(); //use micro seconds since the races can be that close!
  }
  
  //read the analog in value of IR's:
  sensorValueStart1 = analogRead(analogInPin1); // Speed trap Lane 1
  sensorValueStart2 = analogRead(analogInPin2); // Finish line Lane 1
  sensorValueFinish1 = analogRead(analogOutPin1); // Speed trap Lane 2
  sensorValueFinish2 = analogRead(analogOutPin2); //Finish line Lane 2

   // wait for the speed trap start sensors to be triggered
  
   if(sensorValueStart1 < sensorThresh)
     {
      timeFirst1 = micros(); //Lane 1 speed trap start time (First IR Sensor)
     }

   if(sensorValueStart2 < sensorThresh)
     {
      timeFirst2 = micros(); //Lane 2 Speed trap start time (First IR Sensor)
     }

// wait/check for the Finish Line sensors to be triggered
  
  if(sensorValueFinish1 < sensorThresh && timeFirst1 > 0 && ET1 == 0)
  {
    timeSecond1 = micros();
    ET1 = timeSecond1 - StartTime;
    ET1 = ET1 / 1000000; //converting microseconds to milliseconds
  }

 if(sensorValueFinish2 < sensorThresh && timeFirst2 > 0 && ET2 == 0)
  {
    timeSecond2 = micros();
    ET2 = timeSecond2 - StartTime;
    ET2 = ET2 / 1000000; //converting microseconds to milliseconds
  }


if (ET1 < ET2 && ET1 != 0 && ET2 != 0)// Set winner Lane 1, turn on winner LED
   {
   digitalWrite(11, HIGH);
   }

 if(ET1 > ET2 && ET2 != 0 && ET1 != 0) // Set winner Lane 2, turn on winner LED
   {
   digitalWrite(12, HIGH);
   }

 if(ET1 > 0 && ET2 > 0) // Race is over, display times for both lanes.
  {
    trapTime1 = timeSecond1 - timeFirst1;
    trapTime2 = timeSecond2 - timeFirst2;
    trapTime1 = trapTime1 / 1000;
    velocity1 = speedConst / trapTime1;//get the Speed converted from mm/millis to km/h.
    velocity1 = velocity1 * 0.621371;  // use this line to convert KM/H to MP/H
    trapTime2 = trapTime2 / 1000;
    velocity2 = speedConst / trapTime2;//get the Speed converted from mm/millis to km/h.
    velocity2 = velocity2 * 0.621371;  // use this line to convert KM/H to MP/H
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Lane 1" );
    lcd.setCursor(0,1);
    lcd.print("ET:");
    lcd.setCursor(3,1);
    lcd.print(ET1, 4);
    lcd.setCursor(10,1);
    lcd.print("@ ");
    lcd.print(velocity1);
    lcd.setCursor(17,1);
    lcd.print("mph");  //change km to mph 
    if (digitalRead(11) == HIGH)
       {
         lcd.setCursor(10,0);
         lcd.print("*WINNER*");
       }
    lcd.setCursor(0,2);
    lcd.print("Lane 2" );
    lcd.setCursor(0,3);
    lcd.print("ET:");
    lcd.setCursor(3,3);
    lcd.print(ET2, 4);
    lcd.setCursor(10,3);
    lcd.print("@ ");
    lcd.print(velocity2);
    lcd.setCursor(17,3);
    lcd.print("mph");  //changes km to mph 
      if (digitalRead(12) == HIGH)
       {
         lcd.setCursor(10,2);
         lcd.print("*WINNER*");
       }
    delay(10000);
    digitalWrite(11, LOW); //turn off lane winner LED
    digitalWrite(12, LOW); //turn off lane winner LED
    timeSecond1 = 0;
    timeFirst1= 0; 
    timeSecond2 = 0;
    timeFirst2= 0; 
    trapTime2 = 0;
    trapTime1 = 0;
    velocity1 = 0;
    velocity2 = 0;
    StartTime = 0;
    ET1 = 0;
    ET2 = 0;
  }
  
 humi = HT.readHumidity();
 tempC = HT.readTemperature();
 tempF = HT.readTemperature(true);

 display.clearDisplay();
 oledDisplayHeader();
 
 oledDisplay(3,5,28,humi,"%");
 oledDisplay(3,60,28,tempF,"F");
 
 display.display(); 
 
}
void oledDisplayHeader(){
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(0, 0);
 display.print(" Hum  ");
 display.setCursor(60, 0);
 display.print(" Temp");
}
void oledDisplay(int size, int x,int y, float value, String unit){
 int charLen=12;
 int xo=x+charLen*3.2;
 int xunit=x+charLen*3.6;
 int xval = x; 
 display.setTextSize(size);
 display.setTextColor(WHITE);
 
 if (unit=="%"){
   display.setCursor(x, y);
   display.print(value,0); //decimal places for humidity
   display.print(unit);
 } else {
   if (value>99){
    xval=x;
   } else {
    xval=x+charLen;
   }
   display.setCursor(xval, y);
   display.print(value,0);
   display.drawCircle(xo, y+2, 2, WHITE);  // print degree symbols (  )
   display.setCursor(xunit, y);
   display.print(unit);
 }
 
}

Your code deals with reading temperature and humidity. What does that have to do with racing cars? (at least the initial comments/variables)

Racers use temp and humidity ( and barometric pressure) to record track conditions which help them tune the car more consistently after they have a database of runs recorded.

So the code has an lcd in it - what is the problem? Is it not working? If not, what is being displayed vs. what you want displayed?

The code works as designed. the start button is depressed, a timer starts, when the car crosses the speed trap beam ( ir sensors), the car continues to the finish line and displays the time on the LCD as well as a mph calculated from the time it takes to get from the speed trap to the finish line. I'm wondering if it is possible to add a second 20x4 display to display the time it takes to get from the start line to the speed trap timers

It would be much easier to just use the LCD you have. You already have the data. You could display the data after both speed traps have tripped and then display the final data after both finish lines have tripped.

Or, you could alternate the display between the two after the race with a 1-2 second pause between them. Kind of like a rotating message - screen 1, pause, screen 2, pause.

As a suggestion, it would be easier if you structured your code like a finite state machine, rather than sequentially doing everything and checking lots of different variables. Your states would be something like

  1. waiting to start
  2. racing (waiting for all sensors to trip)
  3. finished
    then go back back to 1
    untested:
#include <LiquidCrystal_I2C.h>  // LiquidCrystal I2C - Version: 1.1.2
//#include <fastIO.h>  // fastIO - Version: Latest
#include <Wire.h>
#include "DHT.h"
#define DHT11Pin 4
#define DHTType DHT11 //OLED

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

DHT HT(DHT11Pin, DHTType);
float humi;
float tempC;
float tempF;

#define SCREEN_WIDTH 128 // OLED display width, in pixels  
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
LiquidCrystal_I2C lcd(0x27, 20, 4); // double check your LCD address first using: i2C_scanner

const byte LANES = 2;

const byte pinSpeedTrap[LANES] = { A0, A3 };
const byte pinFinishLine[LANES] = { A1, A2 };
const int sensorThresh = 800; //adjustable trigger sensing threshold of the IR receivers. 1000 = unblocked(high)

const byte pinWinner[LANES] = { 11, 12 };
const byte pinStartSwitch = 2;

const byte pinStartTree[] = { 5, 6, 7 };
const byte startTreeCount = sizeof(pinStartTree) / sizeof(pinStartTree[0]);


enum { PRE_START_CHECK, PRE_START, START, RACING, FINISHED, POST_FINISH } state;

unsigned long StartTime;
unsigned long timeFirst[LANES]; //speed trap beam time, usec
unsigned long timeSecond[LANES]; //finish line, usec
int winner;

const float speedConst = 1800.0; // ((distance between the Speed Gate and Finish IR sensors in mm) x 3600)/1000)to convert mm/millis to km/h)
// In this project we have 500mm between IR sensors on proto board >>> 500x3600/1000 = 1800


void setup()
{
  Serial.begin(9600);

  pinMode(pinStartSwitch, INPUT);
  for ( int i = 0; i < LANES; ++i ) {
    pinMode(pinWinner[i], OUTPUT);
    digitalWrite(pinWinner[i], HIGH);
  }
  delay(1000);
  for ( int i = 0; i < LANES; ++i ) {
    digitalWrite(pinWinner[i], LOW);
  }

  lcd.init();
  lcd.backlight();
  lcd.setCursor(2, 0);
  lcd.print("Drag Strip Timer");
  lcd.setCursor(3, 1);
  lcd.print("by Ricky Kelso");
  lcd.setCursor(1, 2);

  lcd.print("EET411L Sr Project");
  delay(2000);
  lcd.setCursor(1, 3);
  lcd.print("Ready to race...v6");

  HT.begin();//For DHT11
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64  //For OLED I2C
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.display(); //Display logo
  display.clearDisplay();

  for ( int i = 0; i < startTreeCount; ++i ) {
    pinMode(pinStartTree[i], OUTPUT);
  }
  delay(3000);
  for ( int i = 0; i < startTreeCount; ++i ) {
    digitalWrite(pinStartTree[i], HIGH);
    delay(1000);
  }
}

void loop()
{
  int StartState = digitalRead(pinStartSwitch); //Check state of start gate. 0 = closed & 1 = open.

  //read the analog in value of IR's:
  int sensorValueStart[LANES];
  int sensorValueFinish[LANES];

  for ( int i = 0; i < LANES; ++i ) {
    sensorValueStart[i] = analogRead(pinSpeedTrap[i]);
    sensorValueFinish[i] = analogRead(pinFinishLine[i]);
  }

  switch ( state ) {
    //enum { PRE_START_CHECK, PRE_START, START, RACING, FINISHED, POST } state;
    case PRE_START_CHECK:
      // make sure start gate is closed/reset before we attempt a start
      // display a message 1 time and move to next state
      if ( StartState == LOW ) {
        // we are good
        Serial.println("Pre start check okay");
      }
      else {
        // we are not good
        Serial.println("Pre start check failed - close start gate");
      }
      state = PRE_START;
      // turn off all leds
      for ( int i = 0; i < LANES; ++i ) {
        digitalWrite(pinWinner[i], LOW);
      }
      break;

    case PRE_START:
      // make sure start gate is closed/reset before we attempt a start
      if ( StartState == LOW ) {
        // we are ready to start so rest things and move to next state
        for ( int i = 0; i < LANES; ++i ) {
          timeFirst[i] = 0;
          timeSecond[i] = 0;
        }
        winner = 0; // 0 == no winner yet
        Serial.println("Waiting to start");
        state = START;
      }
      break;

    case START:
      // waiting to start
      if ( StartState == LOW ) {
        // we have started, so note time and move to next state
        StartTime = micros(); //use micro seconds since the races can be that close!
        state = RACING;
      }
      break;

    case RACING:
      for ( int i = 0; i < LANES; ++i ) {
        // check speed trap sensors and only record time if it hasn't been recorded yet
        if (sensorValueStart[i] < sensorThresh && timeFirst[i] == 0) {
          timeFirst[i] = micros(); // speed trap start time (First IR Sensor)
        }

        // wait/check for the Finish Line sensors to be triggered
        if (sensorValueFinish[i] < sensorThresh && timeFirst[i] > 0 && timeSecond[i] == 0) {
          timeSecond[i] = micros();
          if ( winner == 0 ) {
            winner = i + 1;
            digitalWrite(pinWinner[i], HIGH);
          }
        }
      }

      // check to see if we are all done
      state = FINISHED;   // assume we are done
      for ( int i = 0; i < LANES; ++i ) {
        if ( timeSecond[i] == 0 ) {
          // lane has not finished so we are not done
          state = RACING;
        }
      }
      break;

    case FINISHED:
      lcd.clear();
      for ( int i = 0; i < LANES; ++i ) {
        float endTime = (timeSecond[i] - StartTime) / 1000000.0;   // total time in seconds
        unsigned long trapTime = (timeSecond[i] - timeFirst[i]) / 1000;   // trap time in msec
        float velocity = speedConst / trapTime;   //get the Speed converted from mm/millis to km/h.
        velocity *= 0.621371;  // use this line to convert KM/H to MP/H

        lcd.setCursor(0, i);
        lcd.print("Lane " );  lcd.print(i + 1);
        lcd.setCursor(0, i + 1);
        lcd.print("ET:");
        lcd.print(endTime, 4);
        lcd.setCursor(10, 1);
        lcd.print("@ ");
        lcd.print(velocity);
        lcd.setCursor(17, 1);
        lcd.print("mph");  //change km to mph
        if (winner == i + 1) {
          lcd.setCursor(10, i);
          lcd.print("*WINNER*");
        }
      }
      state = POST_FINISH;
      break;

    case POST_FINISH:
      // update oled

      float humi = HT.readHumidity();
      //float tempC = HT.readTemperature();
      float tempF = HT.readTemperature(true);

      display.clearDisplay();
      oledDisplayHeader();

      oledDisplay(3, 5, 28, humi, "%");
      oledDisplay(3, 60, 28, tempF, "F");

      display.display();
      delay(10000);
      state = PRE_START_CHECK;
      break;
  }
}

void oledDisplayHeader() {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print(" Hum  ");
  display.setCursor(60, 0);
  display.print(" Temp");
}
void oledDisplay(int size, int x, int y, float value, String unit) {
  int charLen = 12;
  int xo = x + charLen * 3.2;
  int xunit = x + charLen * 3.6;
  int xval = x;
  display.setTextSize(size);
  display.setTextColor(WHITE);

  if (unit == "%") {
    display.setCursor(x, y);
    display.print(value, 0); //decimal places for humidity
    display.print(unit);
  } else {
    if (value > 99) {
      xval = x;
    } else {
      xval = x + charLen;
    }
    display.setCursor(xval, y);
    display.print(value, 0);
    display.drawCircle(xo, y + 2, 2, WHITE); // print degree symbols (  )
    display.setCursor(xunit, y);
    display.print(unit);
  }

}