Go Down

Topic: Timing multiple sensors (Read 112 times) previous topic - next topic

lakapo

Hello communitiy,

I am very new to the Arduino ecosystem. I recently started with a project for school to make an automated greenhouse with the following sensors:
2x water level sensor (I'm using two different reservoirs)
3x soil moisture
1x DHT 22 (Temp and Humidity)
1x LDR module (light intensity)
1x SD module to log temp, humidity and light intensity
1x 4 relay board of which I use 3 relays for pumps to turn on when the paired soil humidity sensor returns a low value
2x LED to indicate if the water levels are low

I really simplified timing because I find it quite difficult, so I just let my loop run every 30 minutes, in which the light intensity, humidity and temperature gets measured and logged, the water level gets checked and the soil moisture as well. That is where my problem lies. I want to turn the corresponding pump on for 10 seconds when one of the moisture sensors returns a low value. However I have no clue how to do this. I have attached my main file and a test file in which I try to get the timing right with leds to simplify the process.

I have been trying to make it work with the millis function but I don't think I get it. This is my test file:

unsigned long previousMillis = 0;

void setup() {
 
  Serial.begin(9600);
  int LedPin = 8;
  int LedState = LOW;
  int LedPin2 = 9;
  int LedState2 = LOW;
}

void loop() {

unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= 20000){
      unsigned long SMillis = millis();
      digitalWrite(9, HIGH);
      int LightVal = analogRead(0);
      Serial.println(LightVal);
     if(LightVal > 800){
        SMillis = currentMillis;
        while(currentMillis - SMillis <= 10000){
        digitalWrite(8,HIGH);
     }
     }
  else{
    digitalWrite(8,LOW);
  }
  previousMillis = currentMillis;

}
}

The led on pin 9 is meant as a  test to make sure the pocess runs, but led 8 just turns on as well.

This is my full sketch:
 //SD
  #include <SD.h>
  #include <SPI.h>
  File sdcard_file;
  const byte CS_pin =     10;
//DHT
  #include <DHT.h>
  #define DHTTYPE DHT22
  const byte DHTpin =     3;     
  DHT dht(DHTpin, DHTTYPE);
//Water
  const byte WledPin1 =   8;
  const byte WledPin2 =   9;
  int WledState1 = LOW;
  int WledState2 = LOW;
//Soil
  unsigned long previousMillis = 0;
  const byte RelayPin1 =      4;
  const byte RelayPin2 =      5;
  const byte RelayPin3 =      6;
  int RelayState1 = LOW;
  int RelayState2 = LOW;
  int RelayState3 = LOW;
//Variables
  double LightVal; 
  double HumVal; 
  double TempVal;

void setup() {
    Serial.begin(9600);
    //DHT
    dht.begin();
    //SD
    pinMode(CS_pin, OUTPUT);

    if (SD.begin()){
      Serial.println(F("SDReady"));
    }
    else{
      Serial.println(F("SDError"));
      return;
    }
   
    sdcard_file = SD.open(F("data.txt"), FILE_WRITE);
    if (sdcard_file) {
      sdcard_file.print(F("Light"));
      sdcard_file.print(F(" "));
      sdcard_file.print(F("Temp"));
      sdcard_file.print(F(" "));
      sdcard_file.print(F("Hum"));
      sdcard_file.println(F(" "));
      sdcard_file.close();
    }
    //Water
    pinMode(WledPin1, OUTPUT);
    pinMode(WledPin2, OUTPUT);
    //Soil
    pinMode(RPin1, OUTPUT);
    pinMode(RPin2, OUTPUT);
    pinMode(RPin3, OUTPUT);
}

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

  if(currentMillis - previousMillis >= 60000){
     
    //DHT
      HumVal = dht.readHumidity();
      TempVal= dht.readTemperature();
     
    //Lichtsensor
      LightVal = analogRead(A0);

    //SD module
      sdcard_file = SD.open(F("data.txt"), FILE_WRITE);
      if (sdcard_file) {   
        sdcard_file.print(LightVal);
        sdcard_file.print(F(" "));
        sdcard_file.print(TempVal);
        sdcard_file.print(F(" "));
        sdcard_file.println(HumVal);
        sdcard_file.close();
      }
   
      else {
        Serial.println(F("ErrorSDOpen"));
      }

     //Water
       int WaterValA1 = analogRead(A1);
       int WaterValA2 = analogRead(A2);
       Serial.println(WaterValA1);
       Serial.println(WaterValA2);

       if(WaterValA1 <=400){
         digitalWrite(8,HIGH);
       }
       else{
         digitalWrite(8,LOW);
       }
 
       if(WaterValA2 <=400){
         digitalWrite(9,HIGH);
       }
       else{
         digitalWrite(9,LOW);
       }

     //Soil
       int SoilValA3 = analogRead(3);
       int SoilValA4 = analogRead(4);
       int SoilValA5 = analogRead(5);
       Serial.println(SoilValA3);
       Serial.println(SoilValA4);
       Serial.println(SoilValA5);

       if(SoilValA3 <=700){
         digitalWrite(4,HIGH);
       }
       else{
         digitalWrite(4,LOW);
       }

       if(SoilValA4 <=500){
         digitalWrite(5,HIGH);
       }
       else{
         digitalWrite(5,LOW);
       }
 
       if(SoilValA5 <=500){
         digitalWrite(6,HIGH);
       }
       else{
         digitalWrite(6,LOW);
       }
       
    previousMillis = currentMillis;
  }
 
}

This does not include a timing feature to turn on the pumps.
I really hope I provided enough information. Thanks in advance.

PaulRB

Welcome to the forum. But stop right there. Go and read the forum guide in the sticky post. Then modify your post above and at least put in some code tags. Ideally also add the other things suggested in the guide. Thanks.

PaulRB

#2
Oct 19, 2018, 11:05 am Last Edit: Oct 19, 2018, 11:09 am by PaulRB
I'm not sure why you are so keen to use millis(). At the moment I can't see any need for you to use anything other than delay(). Your code does not have to check for button presses or other external events, in other words it doesn't need to do "two things at the same time".

What surprised me is that you are recording data to the SD card without any date/time information. I would have thought this would make the information much less valuable. You should get a Real Time Clock (RTC) module. The ones based on ds3231 chip are better than the older ds1307 chips.

Silente

Your code can become very shorter. First: the HIGH and LOW in digitalRead() can be changed into controls. For example if I want switvh on a pin if the value of a variable is more than 40, and switch it off if the valuebis less than 40 I can write simply
Code: [Select]

digitalWrite (pin, variable>40);

You can also print a string (NOT variables) in a single .print function.

Forry for my English
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pichi capiscono l'importanza di formattare, sii tra di essi

Go Up