Loop uses the Setup function over and over again.

Hello! I’m very new to Arduino programming and I’m sure there will be an easy answer for this one.

I have an LCD and some temperature/gas sensors whose readings I would like to be displayed on this LCD. All the data doesnt fit so I had to do a delay and then the LCD switches page.

But I would like a welcomming message when you fire the LCD up. I have tried the lcd.print function but the message keeps looping all over again. I thought the setup should run only one time and then the loop is the only thing the iterates? What have I done wrong?

#include <dht.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

dht DHT;

#define DHT22_PIN 6
#define MQ_PIN 0
#define RL_VALUE 10
#define RO_CLEAN_AIR_FACTOR 9.83

#define GAS_LPG 0
#define GAS_CO 1
#define GAS_SMOKE 2
#define READ_SAMPLE_TIMES 5
#define READ_SAMPLE_INTERVAL 50
#define CALIBRATION_SAMPLE_TIMES 50
#define CALIBRATION_SAMPLE_INTERVAL 500

float LPGCurve[3] = {2.3,0.21,-0.47}; 
float COCurve[3] = {2.3,0.72,-0.34};
float SmokeCurve[3] = {2.3,0.53,-0.44};
float Ro = 10;    

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Welcome!");
  delay(2000);
  lcd.clear();
  lcd.print("Calibrating...");
  Ro = MQCalibration(MQ_PIN);
  lcd.clear();
  lcd.print("Calibration done!");
  delay(2000);
}
 


void loop()
{
{
  int chk = DHT.read22(DHT22_PIN);
  lcd.setCursor(0,0); 
  lcd.print("Temp = ");
  lcd.print(DHT.temperature);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Luftfukt=");
  lcd.print(DHT.humidity);
  lcd.print("%");
  delay(2000);
}
delay(15000);
{
  lcd.clear();
}
  {             
  lcd.setCursor(0,0);
   lcd.print("Gasol:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG));
   lcd.print( "ppm" );
   lcd.setCursor(0,1);     
   lcd.print(" CO:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO));
   lcd.print( "ppm" ); 
   delay(5000);
}
{
  lcd.clear();
 }
 {             
  lcd.setCursor(0,0); 
   lcd.print("Smoke:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE));
   lcd.print( "ppm" );
   delay(5000);
}
{
  lcd.clear();
 }
}

float MQRead(int mq_pin)
{
  int i;
  float rs=0;
 
  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQResistanceCalculation(analogRead(mq_pin));
    delay(READ_SAMPLE_INTERVAL);
  }
 
  rs = rs/READ_SAMPLE_TIMES;
 
  return rs;  
}

int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
  if ( gas_id == GAS_LPG ) {
     return MQGetPercentage(rs_ro_ratio,LPGCurve);
  } else if ( gas_id == GAS_CO ) {
     return MQGetPercentage(rs_ro_ratio,COCurve);
  } else if ( gas_id == GAS_SMOKE ) {
     return MQGetPercentage(rs_ro_ratio,SmokeCurve);
  }    
 
  return 0;
}


float MQCalibration(int mq_pin)
{
  int i;
  float val=0;
 
  for (i=0;i<CALIBRATION_SAMPLE_TIMES;i++) {            //take multiple samples
    val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBRATION_SAMPLE_TIMES;                   //calculate the average value
 
  val = val/RO_CLEAN_AIR_FACTOR;                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro 
                                                        //according to the chart in the datasheet 
 
  return val; 
}

float MQResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

int  MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}

If setup appears to be looping, it is possible your device is getting reset.

Try putting #if 0 … #endif around all the code in loop() and try again.

Thank you for the quick answer!

But did not seem to work. Now I can't even see the values of the sensors, the setup seems to be the only thing that is being printed and looped..

I wrote the following:

void loop()
{
  #if 0
{
  int chk = DHT.read22(DHT22_PIN);
  lcd.setCursor(0,0); 
  lcd.print("Temp = ");
  lcd.print(DHT.temperature);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Luftfukt=");
  lcd.print(DHT.humidity);
  lcd.print("%");
  delay(2000);
}
delay(15000);
{
  lcd.clear();
}
  {             
  lcd.setCursor(0,0);
   lcd.print("Gasol:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG));
   lcd.print( "ppm" );
   lcd.setCursor(0,1);     
   lcd.print(" CO:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO));
   lcd.print( "ppm" ); 
   delay(5000);
}
{
  lcd.clear();
 }
 {             
  lcd.setCursor(0,0); 
   lcd.print("Smoke:"); 
   lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE));
   lcd.print( "ppm" );
   delay(5000);
}
{
  lcd.clear();
 }
 #endif
}

I decided the record the LCD so you get an idea of what is going on.

Comment-out the code in setup() bit by bit until you locate the problem, but my money is on MQcalibration or an inadequate power supply.

You also need to sort out your {} braces - you have way too many.

Interesting that you mention power supply since the gas sensor is known for drawing quite alot of power. Up to 800mW. Maybe I shouldn't power it from the Arduino Nano..

Hatmpatn:
But did not seem to work. Now I can't even see the values of the sensors, the setup seems to be the only thing that is being printed and looped..

That's pretty much the idea. The code in loop() is now being ignored, so it sort of proves the board is resetting.

(Where did you get the nice old IBM button from.....)

@AWOL: That technique you used presumably works since 0 is false, but why not just comment the block out?

I found the retro button in a electronics junk box at my university.

I have cleaned up the code a little bit and and also tried disconnecting the Gas sensor, and still my problem with the Setup looping persists. This eliminates the possibility that the sensor draws too much current thus resetting the Arduino Nano.

The code looks as following right now:

#include <dht.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

dht DHT;

#define DHT22_PIN 6
#define MQ_PIN 0
#define RL_VALUE 10
#define RO_CLEAN_AIR_FACTOR 9.83

#define GAS_LPG 0
#define GAS_CO 1
#define GAS_SMOKE 2
#define READ_SAMPLE_TIMES 5
#define READ_SAMPLE_INTERVAL 50
#define CALIBRATION_SAMPLE_TIMES 50
#define CALIBRATION_SAMPLE_INTERVAL 500

float LPGCurve[3] = {2.3,0.21,-0.47}; 
float COCurve[3] = {2.3,0.72,-0.34};
float SmokeCurve[3] = {2.3,0.53,-0.44};
float Ro = 10;    

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Welcome!");
  delay(2000);
  lcd.clear();
  lcd.print("Calibrating...");
  Ro = MQCalibration(MQ_PIN);
  lcd.clear();
  lcd.print("Calibration done!");
  delay(2000);
  lcd.clear();
}
 


void loop()
{
  //#if 0
{
  int chk = DHT.read22(DHT22_PIN);
  lcd.setCursor(0,0); 
  lcd.print("Temp = ");
  lcd.print(DHT.temperature);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Luftfukt=");
  lcd.print(DHT.humidity);
  lcd.print("%");
  delay(15000);
  lcd.clear();             
  lcd.setCursor(0,0);
  lcd.print("Gasol:"); 
  lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG));
  lcd.print( "ppm" );
  lcd.setCursor(0,1);     
  lcd.print(" CO:"); 
  lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO));
  lcd.print( "ppm" ); 
  delay(5000);
  lcd.clear();             
  lcd.setCursor(0,0); 
  lcd.print("Smoke:"); 
  lcd.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE));
  lcd.print( "ppm" );
  delay(5000);
  lcd.clear();
 }
 //#endif
}

float MQRead(int mq_pin)
{
  int i;
  float rs=0;
 
  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQResistanceCalculation(analogRead(mq_pin));
    delay(READ_SAMPLE_INTERVAL);
  }
 
  rs = rs/READ_SAMPLE_TIMES;
 
  return rs;  
}

int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
  if ( gas_id == GAS_LPG ) {
     return MQGetPercentage(rs_ro_ratio,LPGCurve);
  } else if ( gas_id == GAS_CO ) {
     return MQGetPercentage(rs_ro_ratio,COCurve);
  } else if ( gas_id == GAS_SMOKE ) {
     return MQGetPercentage(rs_ro_ratio,SmokeCurve);
  }    
 
  return 0;
}


float MQCalibration(int mq_pin)
{
  int i;
  float val=0;
 
  for (i=0;i<CALIBRATION_SAMPLE_TIMES;i++) {            //take multiple samples
    val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBRATION_SAMPLE_TIMES;                   //calculate the average value
 
  val = val/RO_CLEAN_AIR_FACTOR;                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro 
                                                        //according to the chart in the datasheet 
 
  return val; 
}

float MQResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

int  MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.... :slight_smile:

Why did you comment out the #if statement? You’re supposed to be simplifying the sketch to find what is causing the reset. I’d do a quick sanity check with a simple sketch like:

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

void loop() {
}

If that doesn’t cause the reset then try:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Welcome!");
}
void loop(){}

I tried what you wrote and that sure worked. But I decided to skip the gas sensor altogether and only go with the temperature and humidity sensor. Commenting out all that got the Arduino to work as it should again without looping the Setup. I’m pleased with that, didn’t need to gas sensor anyway,…

Thanks for all the help!

JimboZA:
@AWOL: That technique you used presumably works since 0 is false, but why not just comment the block out?

Because it may already have /* */ comments in it.

Forget "may" - it should have comments in it.