Menu
CoddyTech

Plant Monitor: Report

Part of the Projects section of Coddy's Arduino journey. Lesson 20 of 24.

The last step writes a report once a second: the moisture and a status word, DRY, OK or WET. It goes to the LCD for anyone by the plant, and to the Serial monitor for a computer.

The LCD is wired the usual way: LiquidCrystal lcd(12, 11, 5, 4, 3, 2); and lcd.begin(16, 2) in setup(). The top row shows Moisture: 42% and the bottom row the word.

On the Serial monitor the word ends the same line as the moisture, so print the moisture with Serial.print(), not println(). Then choose the word with the status light's three ranges and print it to both:

if (moisture < 30) {
  lcd.print("DRY");
  Serial.println("DRY");
} else if (moisture <= 70) {
  lcd.print("OK ");
  Serial.println("OK");
} else {
  lcd.print("WET");
  Serial.println("WET");
}

Watch the old characters. OK is shorter than DRY, so print "OK " with a space, or the screen shows OKY. The same goes for 100% becoming 5%: print a couple of spaces after the %.

challenge icon

Challenge

Medium

Write the report once a second:

  • set up the LCD (pins 12, 11, 5, 4, 3, 2) in setup()
  • top row: Moisture: 42%, with spaces after it
  • bottom row: DRY under 30%, OK from 30% to 70%, WET over 70%, padded with spaces
  • Serial monitor: one line like Moisture: 42% OK

Keep the status light and the alarm. Press Run, then Check.

Try it yourself

// The knob stands in for a soil moisture sensor
const int sensorPin = A0;
// The status light: an RGB LED
const int redPin = 9;
const int greenPin = 10;
const int bluePin = 6;
// The alarm
const int buzzerPin = 8;

bool wasDry = false;         // was the soil dry at the last reading?
unsigned long dryStart = 0;  // when it became dry

// The moisture in percent: 0 is bone dry, 100 is soaking wet.
int readMoisture() {
  int reading = analogRead(sensorPin);
  return map(reading, 0, 1023, 0, 100);
}

// Red when dry, green when it is fine, blue when wet.
void showStatus(int moisture) {
  digitalWrite(redPin, LOW);
  digitalWrite(greenPin, LOW);
  digitalWrite(bluePin, LOW);
  if (moisture < 30) {
    digitalWrite(redPin, HIGH);
  } else if (moisture <= 70) {
    digitalWrite(greenPin, HIGH);
  } else {
    digitalWrite(bluePin, HIGH);
  }
}

// Beep once a second when the soil has been dry for more than 5 seconds.
void checkAlarm(int moisture) {
  if (moisture < 30) {
    if (wasDry == false) {
      wasDry = true;
      dryStart = millis();
    }
    if (millis() - dryStart > 5000) {
      tone(buzzerPin, 880, 200);
    }
  } else {
    wasDry = false;
  }
}

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int moisture = readMoisture();
  Serial.print("Moisture: ");
  Serial.print(moisture);
  Serial.println("%");
  showStatus(moisture);
  checkAlarm(moisture);
  delay(1000);
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Projects

Practice on your own: Arduino playground