analogRead without delay function

analogRead function without delay:
I am using Arduino in an application where I have to measure the flow rate (flow meter YF-s-402) and temperature (thermistor) reading in a same program. I can't use delay because of the flow meter program, which is using millis function.
I do not have any issue in flow meter program but when I am writing temperature sensor ADC program without delay function, the delay is not showing, Could you please help me what I can modify following code, or any other alternative?

#define INTERVAL 1000 // [ms]
#define temp1 A0 // for temp sensor
unsigned long previousMillis = 0;
const long interval1 = 1000; 
const long interval2 = 2000; 

long ADC_temp;

float volt_temp, logR2, R2;
float temp, temp2, temp3, temp_c;

float R1 = 10000; // value of R1 as voltage divider on board, 10 K Ohm
float c1 = 0.001129148, c2 = 0.000234125, c3 = 0.0000000876741;  //steinhart-hart coeficients for thermistor

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

void loop() 
{
unsigned long currentMillis = millis();
ADC_temp=0;               //Clear the ADC_volt value
      
for(int i=0; i< 100; i++) // do the task 100 times
  {  
    {
    ADC_temp = ADC_temp+analogRead(temp1);
    if (currentMillis - previousMillis >= interval1) 
      {
        previousMillis = currentMillis;        
      }  
    ADC_temp = ADC_temp+analogRead(temp1);
    }
    {
    if (currentMillis - previousMillis >= interval2) 
      {
        previousMillis = currentMillis;        
      } 
    } 

  }        
  
        ADC_temp=ADC_temp/100;                       //Averaging the ADC_volt value
        R2 = R1 * (1023.0 / (float)ADC_temp - 1.0); //calculate resistance of thermistor from voltage divider circuit
        logR2 = log(R2);                            //calculate the log of R2, to be used in the next line
        temp2 = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2)); // temperature in Kelvin
        temp3 = temp2 - 273.15;           //steinhart-hart equation for temperature  
          

        Serial.print("Temp: ");
        Serial.print(temp3,1);
        Serial.println(" C");
}
    for(int i=0; i< 100; i++) {  // do the task 100 times
        ADC_temp = ADC_temp+analogRead(temp1);
        if (currentMillis - previousMillis >= interval1)
            previousMillis = currentMillis;
        ADC_temp = ADC_temp+analogRead(temp1);
        if (currentMillis - previousMillis >= interval2)
            previousMillis = currentMillis;
    }

i doubt the used of currentMillis in the code above is doing anything except to reset previousMillis every sec. In other words, the analogRead() will just be executed 200 time each iteration of loop

doubt there's a need to average the temperature measurement, it's not likely to change very quickly

i don't see code for the flow meter

Welcome

Something like this ? t1144361 - Wokwi ESP32, STM32, Arduino Simulator

Thank you @gcjr, I was searching a way to deal with analogRead without delay. Is it possible in someway?
Flow meter code does not work properly with this code, therefore, I tested it separately, calibrated it , it is working.

@guix . Thank you for sharing, interesting, Let me try this way, if it works, I will update.

just read it once each iteration of loop.

post the flow code

thanks @gcjr , here is the code, it has both temp and flow meter:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); 
 
#define temp1 A0 // for temp sensor

#define relayuv 5 // Relay 1 for UV
#define relaycooler 6 // Relay 2 for Water cooler

#define flowm1 2 // for flow meter

long ADC_temp;

float volt_temp, logR2, R2;
float temp, temp2, temp3;

float R1 = 10000; // value of R1 as voltage divider on board, 10 K Ohm
float c1 = 0.001129148, c2 = 0.000234125, c3 = 0.0000000876741;  //steinhart-hart coeficients for thermistor

volatile int flow_frequency; // Measures flow sensor pulsesunsigned 

float flowrate1; // Calculated litres/hour
float total = 0;
float LS = 0;
unsigned char flowsensor = 2; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;

void flow () // Interrupt function

{
   flow_frequency++;
}

   void setup()
 {
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;

  lcd.init();           // initialize 16X2 LCD
  lcd.backlight();      // Enabling backlight


}

   void loop ()
{
  
   currentTime = millis();
   // Every second, calculate and print litres/hour
   if(currentTime >= (cloopTime + 1000))
   {
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      flowrate1 = (flow_frequency*0.0137); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
      LS = flowrate1/60.0;
      total=total+LS;
      flow_frequency = 0; // Reset Counter
      Serial.print(flowrate1, 2); // Print litres/hour
      Serial.println(" L/min");
      
                lcd.setCursor(0,0);
                lcd.print("Flow: ");
                lcd.print(flowrate1,2);  

                lcd.setCursor(13,0);
                lcd.print("LPM");

                
                // lcd.setCursor(0,1);
                // lcd.print("Total: ");
                // lcd.print(total); 
                // lcd.print(" L");

     }

I don't see a temp reading in your code.

Also, when dealing with variable, changeable in interrupt, you should switch interrupt off before coping the value and than switch it on again.
So instead of this:

it would be better using this:

  noInterrupts();
  flowrate1 = (flow_frequency*0.0137); // (Pulse frequency x 60 min) / 7.5Q 
  flow_frequency = 0; // Reset Counter
  interrupts();
  LS = flowrate1/60.0;
  total=total+LS;
     

you can read about it there:

not sure about some of your conversions
may be best to start with displaying the raw values: adc and cnt

look this over

# include <Wire.h>
# include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte PinTemp = A0;
const byte PinFlow = 2;

// -----------------------------------------------------------------------------
float R1 = 10000;        // value of R1 as voltage divider on board, 10 K Ohm
float c1 = 0.001129148;  // steinhart-hart coeficients for thermistor
float c2 = 0.000234125;
float c3 = 0.0000000876741;

float
getTempK (void)
{
    int  adc    = analogRead (PinTemp);
    float R2    = R1 * (1023.0 / adc - 1.0); // resistance of thermister
    float logR2 = log(R2);
    float temp2 = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
    float temp3 = temp2 - 273.15;
    return temp3;
}

// -----------------------------------------------------------------------------
volatile unsigned flow_cnt; // Measures flow sensor pulsesunsigned
unsigned          cntLst;
float             flowTotal;

float
getFlow (void)
{
    // quickly capture cnt with interrupts disabled
    noInterrupts ();
    int dCnt = flow_cnt;
    interrupts ();

    dCnt -= cntLst;     // unsigned variabls handle overflow/wrap

    // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour

    float flowPsec   = dCnt * 0.0137;     // flow / sec
    float flowPmin   = flowPsec / 60;     // flow / min
    flowTotal += flowPmin;

    return flowPmin;
}

// -------------------------------------
// Interrupt function
void flow ()
{
    flow_cnt++;
}

// -----------------------------------------------------------------------------
unsigned long msecLst;

void loop ()
{
    unsigned long msec = millis();

    // process once evey sec
    if (msec - msecLst < 1000)
        return;

    msecLst = msec;

    // make measurement and format output
    char t [20];
    dtostrf (getTempK (), 6, 2, t);

    char f [20];
    dtostrf (getFlow( ), 6, 2, f);

    char s [80];
    sprintf (s, "%s L/min, %s degK", f, t);
    Serial.println (s);

    lcd.setCursor (0,0);
    lcd.print     (s);
}

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

    lcd.init();           // initialize 16X2 LCD
    lcd.backlight();      // Enabling backlight

    pinMode  (PinFlow, INPUT_PULLUP);
    attachInterrupt(0, flow, RISING); // Setup Interrupt

    msecLst = millis();
}

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