Need help with code for displaying multiple pages

Can someone give me a little guidance here. I have been working on coding for a few weeks and I've finally got the basics working, but I would like to output my results to an OLED display and I'm running into issues. So I have 2 sensors running and I would like to display information from the 1st sensor have that shown for roughly 8 seconds and then display the 2nd sensor's information for 8 seconds and repeat.

I have tried adding coding for a delay, but that only delays the reading of the sensor information.
Thank you for any help.

////////// SEND DATA TO OLED DISPLAY ///////////////
  LCD.clearDisplay();
  LCD.setCursor(0, 0);
	LCD.setTextSize(2);
  if (temperatureF >= 100 || temperatureF <= -10) {
    LCD.setCursor(0, 0);
  } else {
    LCD.setCursor(10, 0);
  }
	LCD.print(temperatureF);
	LCD.print((char)247);
	LCD.print("F/");
  if (SwapFuelCwithA1){
	  LCD.print(AltA1);
	  LCD.print((char)247);
	  LCD.println("F");
  } else {
    LCD.print(temperature);
    LCD.print((char)247);
    LCD.println("C");    
  }
	LCD.setTextSize(5);
  LCD.setCursor(40, 20);
  if ((eContent >= 10) && (eContent <= 99)) {
    LCD.setCursor(20, 20);
  } else if (eContent == 100) {
    LCD.setCursor(4, 20);
  }
	LCD.print(eContent);
	LCD.println("%");
	delay(8000);
	///// 2nd page//////
	LCD.clearDisplay();
	LCD.setTextSize(2);
	LCD.setCursor(0,0); //sets cursor to column 0, row 0
  LCD.print("Pressure:"); //prints label
  LCD.setTextSize(5);
  LCD.setCursor(40, 20);
  LCD.print(pressureValue, 1); //prints pressure value to lcd screen, 1 digit on float
  LCD.setTextSize(2);
  LCD.print("psi"); //prints label after value
  LCD.print("   "); //to clear the display after large values or negatives
  delay(8000); //delay in milliseconds between read values

Your loop could look like this

Read the data ( both sensors)
Display first one
Wait 8 s
Display second one
Wait 8s

Right, this is what I would like to do. How would I do that? Sorry, this is my first project. I was thinking I could do that with the delay(8000) but that's not working. It is just delaying the read time.

Post your full code.

Operations will be blocked during delay() of course
If you have other thing to do then explore the usage of millis()

The code is huge, but I'll post it now. I am basically merging to opensource codes together. Just a second.

1 Like

Ok, this is my code.



// Ethanol Analyzer v2.1 with BLE & optional DAC analog out(MCP4725 required).. This code only works with AVR based boards(ATmega/Keywish/eMakeFun).  Will NOT work with Nano 33 BLE!
// GOFi2cOLED - Version: Latest 
// v1.4 change notes: Analog out range 0-5v, DAC
// v1.5 change notes: dacOut 5.15v adjustment
// v1.6 change notes: averaging A1 code to reduce noise
// v2.0 change notes: Enable/disable certain features to make it easier for yall, also merged all code branches into this one
// v2.1 change notes: Slight memory efficiency, re-init screen if gets disconnected w/o having to key off/on, watchdog reset if board freezes, dacOut 5.00v
#include <Wire.h>
#include <Adafruit_SleepyDog.h>
#include <GOFi2cOLED.h>
#include <Adafruit_MCP4725.h>
GOFi2cOLED LCD;
Adafruit_MCP4725 dac;

#define A1 1
#define SENSOR_PIN 10
#define OUTPUT_PIN 9
float verz = 2.1;               //code release

///////// Features can be enabled or disabled below ///////
bool featureDAC = 0;             //DAC analog output (MCP4725 required)           default=1   (enabled)
bool featurePWMout = 1;          //PWM Analog output (pin D9)                     default=1   (enabled)
int voltOUTRange = 0;            //PWM&DAC Output Range (0=0-5v , 1=0.5-4.5v)     default=0   (0-5v)     Setting to 1 will output 0.5v-4.5v and also enable Cobb error conditions

///// If you choose to use input A1 pin to attach to a MAP sensor, or some other sensor to monitor input voltage (voltage follower needed for resistance circuits (ie ECT/IAT) //////////
bool featureAnalogInA1 = 0;      //0-5v Analog Input(Pin A1) for bar graph        default=0   (disabled) (setting this to zero essentially turns off monitoring A1 input pin)
float DangerToManifoldA1 = 5.1;  //Danger to Manifold Warning voltage threshold   default=5.1 (5.1v - basically should never cross this, thus will never show)
bool ShowBarGraphA1 = 0;         //Show Analog Input Bar Graph                    default=0   (must have A1 input pin attached to a 0-5v input source)
bool ShowTriangleA1 = 1;         //Show Analog Input Triangle Gauge               default=1   (must have A1 input pin attached to a 0-5v input source)
bool ReverseGraphA1 = 0;         //Swap left/right start point                    default=0   (by default, graph starts from the left side of the screen when detecting 0 voltage)
bool ShowTickMarksA1 = 1;        //Show tick marks for A1 gauge                   default=1   (to show 1/4, 1/2, 3/4 tick marks, like a fuel gauge)
//// To adjust Triangle/Graph gauge, for example: Min(195) Max(530) monitors Fiesta IAT sensor at two given points: 2.6v(59F) to .96v(138F), triangle stays pegged below 59F and above 138F.
int GraphScalerP1A1 = 0;         //A1 Scaler start point                          default=0   (view range window start point, ex. set to 512 to set start point at half of full range) 
int GraphScalerP2A1 = 1024;      //A1 Scaler end point                            default=1024(view range window end point)
//// Below is if you decide to swap the fuel temp Celsius metric with whatever is attached to A1 pin, for example Fuel/IAT temps side by side
bool SwapFuelCwithA1 = 0;        //Replace Celsius field with A1 input            default=0
int AlternateScalerP1A1 = 0;     //Alternate Scaler start point IAT example       default=0   (138 for tapping into Fiesta IAT)   
int AlternateScalerP2A1 = 1024;  //Alternate Scaler end point IAT example         default=1024(59 for tapping into Fiesta IAT)

int eContentSkew = 50;           //Skew Ethanol Content readings                  default=50   (50 is neutral, set to 57 to subtract "-7%" ethanol or 45 to add "5%", I know it sounds backwards)

int splashScreenDelay = 2000;    //show splash screen in miliseconds              default=2000 OR default=0 for Cobb (helps to get ethanol content immediately after key on start
int refreshDelay = 0;            //delay between refresing new ethanol content    default=0    (zero = refresh as quickly as possible)
int eContentOverride = 0;        //Set to above 0 to override ethanol content     default=0    (for testing purposes ONLY)





unsigned int counttick = 0;      //for skipping/retry invalid data
bool resetDisplay = false;       //if oled gets disconnected, resync without key-off/on again

const int pressureInput = A0; //select the analog input pin for the pressure transducer
const int pressureZero = 102.4; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 150psi
const int pressuretransducermaxPSI = 150; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 250; //constant integer to set the sensor read delay in milliseconds

float pressureValue = 0; //variable to store the value coming from the pressure transducer

void setup()
{   /////////// INTRO SCREEN & initializations ///////////
  Serial.begin(9600);
  if (featurePWMout){
    // Setup for analog out, pin 9 to fast mode.
    pinMode(OUTPUT_PIN, OUTPUT);
    TCCR1B = TCCR1B & 0b11111000 | 0x01;
    int analogOut = 255 * (0.1 / 5.0); // setting analog to 0.1v until content can be calculated
    analogWrite(OUTPUT_PIN, int(analogOut));
  }
  if (featureDAC){
    dac.begin(0x60);
    int dacOut = 4095 * (0.1 / 5.0);  // setting DAC to 0.1v until content can be calculated
    dac.setVoltage(dacOut, false);
  }
	LCD.init(0x3C);
	LCD.setTextWrap(false);
	LCD.clearDisplay();
	LCD.setCursor(0, 0);
	LCD.setTextSize(1);
	LCD.print(featureDAC);
	LCD.print(featurePWMout);
  LCD.print(voltOUTRange);
	LCD.println(featureAnalogInA1);
  LCD.print("               v");
  LCD.println(verz,1);
	LCD.setTextSize(2);
	LCD.println();
	LCD.println("Ethanol"); // -> Change the text of these two lines if you want a different startup screen
	LCD.println("Analyzer");
	LCD.display();
	delay(splashScreenDelay);
  Watchdog.enable(8000);
}





void loop()
{
  Watchdog.reset();
  //////////// Detect OLED Disconnect & ReSync ////////////
  byte OLEDerror = false;
  Wire.beginTransmission(60);
  OLEDerror = Wire.endTransmission();
  if (OLEDerror != 0){
      resetDisplay=true;
  }
  if (OLEDerror == 0 && resetDisplay==true){
    delay(1000);
    Watchdog.reset();
    LCD.init(0x3C);
    LCD.setTextWrap(false);
    LCD.clearDisplay();
    LCD.setCursor(0, 0);
    LCD.setTextSize(1);
    LCD.print(featureDAC);
    LCD.print(featurePWMout);
    LCD.print(voltOUTRange);
    LCD.println(featureAnalogInA1);
    LCD.print("               v");
    LCD.println(verz,1);
    LCD.setTextSize(2);
    LCD.println();
    LCD.println("Ethanol"); // -> Change the text of these two lines if you want a different startup screen
    LCD.println("Analyzer");
    LCD.display();
    delay(splashScreenDelay);
    Watchdog.reset();
    resetDisplay=false;
  }
{
 //////////// CALCULATE FUEL PRESSURE ///////////
  pressureValue = analogRead(pressureInput); //reads value from input pin and assigns to variable
  pressureValue = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero); //conversion equation to convert analog reading to psi
  Serial.print(pressureValue, 1); //prints value from previous line to serial
  Serial.println("psi"); //prints label to serial

}

  /////// READ FLEX-FUEL SENSOR DATA /////////
  unsigned long highTime = pulseIn(SENSOR_PIN, HIGH);
  unsigned long lowTime = pulseIn(SENSOR_PIN, LOW);
  unsigned long pulsetime = highTime + lowTime;

  
  /////// READ 0-5V INPUT VOLTAGE from A1 PIN ////////
  float VInA1;
  int AverageVoltagebitsA1;
  int AltA1;
  if (featureAnalogInA1) {
    // start averaging analog A1 input
    AverageVoltagebitsA1 = 0;
    int MeasurementsToAverage = 16;
    for(int i = 0; i < MeasurementsToAverage; ++i)
    {
      AverageVoltagebitsA1 += MeasureVoltage();
      delay(1);
    }
    AverageVoltagebitsA1 /= MeasurementsToAverage;
    //end averaging input
    VInA1 = AverageVoltagebitsA1 * (5.0 / 1023.0);
    AltA1 = mapf(AverageVoltagebitsA1, GraphScalerP1A1, GraphScalerP2A1, AlternateScalerP1A1, AlternateScalerP2A1);
  } else {
    VInA1 = 0.0; //We are setting Analog In to zero because feature is disabled.
  }



  //////// IF FLEX-FUEL SENSOR DATA OUT OF RANGE, SET VARIOUS Vout ERROR CONDITIONS on DAC & ANALOG ///////
	// 20000 uS = 50 HZ - ~6667 uS = 150 HZ
	if (pulsetime > 20100 || pulsetime < 6400) {
		// If the value falls outside the range just skip it for this iteration, perhaps from noise?
    if (counttick >= 2){  // if flex-fuel sensor data is invalid twice in a row, then display debug content - otherwise skip and use old calculations
      if (voltOUTRange){
        //below are for Cobb specific error codes when using 0.5-4.5v DAC analog out
        if (pulsetime == 0 ) {
          // setting analog to 0.1v because sensor got disconnected
          if (featurePWMout){
            int analogOut = 255 * (0.1 / 5.0);
            analogWrite(OUTPUT_PIN, int(analogOut));
          }
          if (featureDAC){
            int dacOut = 4095 * (0.1 / 5.0);
            dac.setVoltage(dacOut, false);
          }
        }
        if (pulsetime >= 20100 ) {
          // setting analog to 4.8v because fuel is probably contaminated (less than 0% ethanol)
          if (featurePWMout){
            int analogOut = 255 * (4.8 / 5.0);
            analogWrite(OUTPUT_PIN, int(analogOut));
          }
          if (featureDAC){
            int dacOut = 4095 * (4.8 / 5.0);
            dac.setVoltage(dacOut, false);
          }
        }
        if ((pulsetime <= 6400) && (pulsetime >= 1)) {
          // setting analog to 4.9v because fuel is water contaminated (greater than 100% ethanol)
          if (featurePWMout){
            int analogOut = 255 * (4.9 / 5.0);
            analogWrite(OUTPUT_PIN, int(analogOut));
          }
          if (featureDAC){
            int dacOut = 4095 * (4.9 / 5.0);
            dac.setVoltage(dacOut, false);
          }
        }
     }
	    
	    //////// ALSO DISPLAY DEBUG ERROR DATA //////////
	    LCD.clearDisplay();
	    LCD.setCursor(0, 0);
	    LCD.setTextSize(0);
	    LCD.print("Sensor Data = ");
      LCD.println(pulsetime);
      LCD.print("VoltsIn = ");
      LCD.print(VInA1,1);
      LCD.print("   v");
      LCD.print(verz,1);
	    LCD.setTextSize(2);
	    LCD.println("");
	    LCD.println("Is Sensor");
	    LCD.println("Connected?");
	    LCD.display();

      /////// ALSO SEND ERROR DATA TO BLUETOOTH CORDLESS TELEPHONES ////////
	    Serial.print("[");
	    Serial.print("=");
	    Serial.print(pulsetime);
	    Serial.print(",");
	    Serial.print("-,");
      Serial.print("-,");
      Serial.print(verz,1);
      Serial.print(",");
      Serial.print(VInA1,1);
	    Serial.print("]");
    } else if (counttick < 2) {
      //uncomment below to display debug ticks
      //LCD.clearDisplay();
	    //LCD.setCursor(0, 0);
	    //LCD.setTextSize(4);
	    //LCD.println(counttick);
	    //LCD.display();
	    counttick++;
    }
		return;
	}





	//////////// CALCULATE ETHANOL CONTENT FROM PULSETIME & TEMP FROM DUTY CYCLE ///////////
	// 50 HZ = 0% ethanol, 150 HZ = 100% ethanol
	long eContent = int((1000000 / pulsetime) - eContentSkew);
  if (eContentOverride){
    eContent = eContentOverride;	
  } 
	if (eContent < 0) {
		eContent = 0;
	}
	else if (eContent > 100) {
		eContent = 100;
	}

	// 1 millisecond = -40C, 5 milliseconds = 125C
	float frequency = float(1000000 / pulsetime);
	float dutyCycle = 100 * (highTime / float(lowTime + highTime));
	float totalTime = float(1.0 / frequency);
	float period = float(100 - dutyCycle) * totalTime;
	int temperature = 40.25 * 10 * period - 81.25;
	int temperatureF = temperature * 1.8 + 32;

  if (temperatureF < -39 || temperatureF > 250) {
    // throw these results out, perhaps from noise?
    return;
  }



	////////// SEND Vout to ANALOG & DAC /////////////
  float desiredVoltage;
  if (voltOUTRange){
	  desiredVoltage = mapf(eContent, 0, 100, 0.5, 4.5); // DAC out: (0.5 volts = 0%, 4.5 volts = 100%)
  } else {
    desiredVoltage = mapf(eContent, 0, 100, 0, 5); // Analog out: (0 volts = 0%, 5 volts = 100%)
  }
  if (featurePWMout){
	  int analogOut = 255 * (desiredVoltage / 5.0);
    analogWrite(OUTPUT_PIN, int(analogOut));
  }
  if (featureDAC){
    int dacOut = 4095 * (desiredVoltage / 5.0);
	  dac.setVoltage(dacOut, false);
  }



  ////////// SEND DATA TO OLED DISPLAY ///////////////
  LCD.clearDisplay();
  LCD.setCursor(0, 0);
	LCD.setTextSize(2);
  if (temperatureF >= 100 || temperatureF <= -10) {
    LCD.setCursor(0, 0);
  } else {
    LCD.setCursor(10, 0);
  }
	LCD.print(temperatureF);
	LCD.print((char)247);
	LCD.print("F/");
  if (SwapFuelCwithA1){
	  LCD.print(AltA1);
	  LCD.print((char)247);
	  LCD.println("F");
  } else {
    LCD.print(temperature);
    LCD.print((char)247);
    LCD.println("C");    
  }
	LCD.setTextSize(5);
  LCD.setCursor(40, 20);
  if ((eContent >= 10) && (eContent <= 99)) {
    LCD.setCursor(20, 20);
  } else if (eContent == 100) {
    LCD.setCursor(4, 20);
  }
	LCD.print(eContent);
	LCD.println("%");
	delay(8000);
	///// 2nd page//////
	LCD.clearDisplay();
	LCD.setTextSize(2);
	LCD.setCursor(0,0); //sets cursor to column 0, row 0
  LCD.print("Pressure:"); //prints label
  LCD.setTextSize(5);
  LCD.setCursor(40, 20);
  LCD.print(pressureValue, 1); //prints pressure value to lcd screen, 1 digit on float
  LCD.setTextSize(2);
  LCD.print("psi"); //prints label after value
  LCD.print("   "); //to clear the display after large values or negatives
  delay(8000); //delay in milliseconds between read values

  ////////////// IF ANALOG INPUT IS ENABLED, DISPLAY BAR GRAPH AND/OR TRIANGLE THINGIE ////////////
  if (featureAnalogInA1) {
    if (VInA1 >= 0.00  && VInA1 <= DangerToManifoldA1){
      //////////////// TRIANGLE GAUGE //////////////
      if (ShowTriangleA1) {
        int bitsA1 = mapf(AverageVoltagebitsA1, GraphScalerP1A1, GraphScalerP2A1, 0, 1024);
        int midpoint;
        if (ReverseGraphA1) {
          midpoint = 127 - (bitsA1 / 8);  //reverses triangle graph
        } else {
          midpoint = (bitsA1 / 8); //normal triangle graph
        }
        int leftfoot = 0;
        int rightfoot = 0;
        if (midpoint > 127){
          midpoint = 127;    
        }
        if (midpoint < 0){
          midpoint = 0;
        }
        if (midpoint < 5){
          leftfoot = 0;
        } else {
          leftfoot = midpoint - 5;
        }
        if (midpoint > 122){
          rightfoot = 127;
        } else {
          rightfoot = midpoint + 5;
        }
        LCD.fillTriangle(leftfoot,63,midpoint,57,rightfoot,63,WHITE); //triangle graph
      }

      //////// RECTANGLE BAR GRAPH ////////////
      if (ShowBarGraphA1) {
        int A1barsize;
        int bitsA1 = mapf(AverageVoltagebitsA1, GraphScalerP1A1, GraphScalerP2A1, 0, 1024);
        if (ReverseGraphA1) {
          A1barsize = 127 - (bitsA1 / 8);
        } else {
          A1barsize = bitsA1 / 8;
        }
        LCD.fillRect(0,60,A1barsize,4,WHITE); //rectangle bar graph
      }

      ///////// TICK MARKS /////////
      if (ShowTickMarksA1) {
        LCD.fillRect(0,58,1,6,WHITE);   //tick mark
        LCD.fillRect(31,61,1,3,WHITE);  //tick mark
        LCD.fillRect(63,58,1,6,WHITE);  //tick mark
        LCD.fillRect(95,61,1,3,WHITE);  //tick mark
        LCD.fillRect(127,58,1,6,WHITE); //tick mark
      }
    } else if (VInA1 > DangerToManifoldA1){
      LCD.setTextSize(0);
      LCD.setCursor(0, 57);
      LCD.print(" !DANGER TO MANIFOLD!");
    }
  }
	LCD.display();
  /////////// SEND DATA TO BLUETOOTH CORDLESS TELEPHONES ////////////
	Serial.print("[");
	Serial.print(temperature);
	Serial.print(",");
	Serial.print(eContent);
	Serial.print(",");
	Serial.print(desiredVoltage,1);
	Serial.print(",");
  Serial.print(verz,1);
  Serial.print(",");
  Serial.print(VInA1,1);
	Serial.print("]");
  Watchdog.reset();
	delay(refreshDelay);
  Watchdog.reset();
	counttick = 0;
}








//////////// FANCY SCALER ////////////
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
{
	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


/////////// READ A1 INPUT ///////////
int MeasureVoltage()
 {
   int rawbitsA1 = analogRead(A1);
   return rawbitsA1;
 }

Seems you are reading data, then displaying, then reading something else, then displaying etc…

Yeah, that was the plan, but with code in it's current form it is not operating that way.

If you look at the snipet I posted in the 1st post, the only data that is being displayed is from the 1st reading. The 2nd page information is not being displayed.

Try not enabling the 8-second watchdog timer. It will reset your Arduino if you don't call Watchdog.reset() at least every 8 seconds and that will be hard to do if you put delay(8000); in your sketch.

Ok, I will give that a shot.

Quick question. Do I need to add something different then the delay(8000) after each page section? I ask, because it seems to delay the sensor read time, instead of delaying the next page information. I would prefer that the sensor information show live information while displayed, rather than a screen shot of the value from 8 seconds prior.

Then you certainly don't want to use delay().

So is this something that is possible with a different line of code?

It will take more than one line.

I would start by putting the two 'pages' into separate functions. Then you can grab the guts of the File -> Examples -> 02.Digital -> BlinkWithoutDelay example to switch between the two every 8 seconds.

Hello and good morning
My recommendation is to put the pages into a structured array and one function that makes the output to the display.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.