Saving analogRead maximum value into a variable

Hi all,
I'm working on a breathalyser project and i will be using a sensor connected to one of the aeduino pins.
The reading from this pin is pretty simple. I have to set the pin as an input and then use analogRead to get the readings from the sensor.
Quick info, In commercial breathalysers the user is asked to blow into a mouthpiece for 5 seconds and then the value will be displayed (that's reasonable to give time for the sensor to detect the maximum value)

Now i have two questions,
1- How to program arduino to read from the pin for 5 seconds ONLY without using delay?

2- and then after that take the maximum value into a variable that will be displayed on the lcd or even to be used in other function?

Did anyone work on a similar project to this? any example or some direction to follow would be really appreciated.

Have a look at the following example to learn how to time parts of your code without delay.

File -> Examples -> 02.Digital -> BlinkWithoutDelay

The second part is easy. You create a variable that will hold the maximum value and store the minimum value e.g., zero in it. When you read a value you compare it to the maximum value you have. If the value is larger you store it in the max variable, otherwise you forget the value. At the end you will have the largest value of the series in the max variable.

No, that is the minimum time for an alcohol detector to detect the level. Read the data sheets.
Paul

Alright thanks, i will try to write some code and will share it here later

I will be using MQ303A sensor,
There is a time to warm up the sensor and this is the 10-15 seconds that most breathalyzer have and then after that the blowing (exhaling) must be done for about 5 seconds, the sensor is going to react with any concentration of alcohol instantly but it would take sometime to reach the proper reading. check this He is testing on MQ3 sensor but it is similar to the MQ303A

In addition to other replies, I would recommend to filter noise from analog pin. See this noise filter example

Hello and good morning
Post your current sketch to see how we can help you.

Double check the warmup time. Many are 24 hours.

Check out max() and how to use it

I tried to make a code to read the sensor for 5 sec but it keeps reading without stopping.

here is the code

#include <SoftwareSerial.h> 
#include <String.h> 
#include <LiquidCrystal.h>

const int Alcohol = 9; //the pin of the sensor
int Alcoholval;
unsigned long previousMillis = 0; //will store last time readings were updated
const long interval = 5000; //the reading time 

LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //connecting the lcd

void setup() {
  // Setup size of LCD 20 characters and 4 lines
  lcd.begin(20, 4);
  lcd.setCursor(1,2);
  lcd.setCursor(4,3);
  lcd.setCursor(0,0);
  Serial.begin(9600);
  pinMode(Alcohol, INPUT);
}
////////////////////////

void loop()
{
 int Alcoholvalue = digitalRead(Alcohol); 
 unsigned long currentMillis = millis();

 do {
   Serial.print(Alcoholvalue);
 } while (currentMillis - previousMillis <= interval); 
previousMillis = currentMillis;
}

Ignore the lcd set up, i didn't use it yet

Here are partial code snippets from a "similar" program that I wrote...

It's simply a matter of setting (or resetting) Max to zero before you start the timed loop.

Then when you are looping and taking readings for your 5-second period, update Max whenever the current reading is greater than Max.

This goes before setup:

int Analog;                               // The analog reading 
int Max;  

This goes in your main loop():

  Max = 0;                                  //Initialize/reset before running timed while() loop

This goes in your timed while() loop:

    Analog = analogRead(A0) ;                 // Read

    if (Analog > Max)                                    //Find Max before exiting loop 
      Max = Analog; 

That is the problem with loops. If you do not do them right, you end up having no loops or endless loops. :slight_smile:

currentMillis and previousMillis are numbers and they do not change in your case.

While we are talking about loops. I recommend you avoid using while loops of any kind. They tend to be less predictable. The goal should be to execute loop() as often as possible. This will allow you to extend your sketch without breaking what you already have.

Move your code into one or two separate functions and make use of the loop() function. Why did I say two? You probably need one interval for sampling e.g., every 10ms and one for the 5 seconds.

Here is an example (Click to reveal or try yourself first)
#define ALCOHOL_SENSOR_PIN  A0

void setup()
{
  Serial.begin( 9600 );
  while ( !Serial );
}

void loop()
{
  int32_t result = measureAlcohol();
  if ( result >= 0 )
  {
    Serial.print( "Alcohol: " );
    Serial.println( result );
  }
}


int32_t measureAlcohol()
{
  const uint32_t MEASURMENT_INTERVAL = 5000;
  static uint32_t previousMillis = 0;
  static int32_t maxAlcohol = -1;

  uint32_t currentMillis = millis();
  if ( maxAlcohol == -1 )
  {
    previousMillis = currentMillis;
  }

  if ( currentMillis - previousMillis > MEASURMENT_INTERVAL )
  {
    int32_t result = maxAlcohol;
    maxAlcohol = -1;
    return result;
  }

  int32_t alcohol = sampleAlcohol();
  if ( alcohol > maxAlcohol )
  {
    maxAlcohol = alcohol;
  }
  return -1;
}


int32_t sampleAlcohol()
{
  const uint32_t SAMPLING_INTERVAL = 10;
  static uint32_t previousMillis = 0;

  uint32_t currentMillis = millis();
  if ( currentMillis - previousMillis < SAMPLING_INTERVAL )
  {
    return -1;
  }
  previousMillis = currentMillis;

  return analogRead( ALCOHOL_SENSOR_PIN );
}