Automated Watering System to Keep House Plants Alive

I learned from my girlfriend, a self-described plant person, that I’ve probably killed most of my plants from giving them too much water rather than not enough. However, our plans to be out of town for several weeks were going to be too long for her several houseplants to go without water. My solution: a timer-controlled water pump that can be adjusted to provide the right amount of water to several plants at regular intervals!

Components used in this project were:

  • Arduino Uno – the brains of the operation
  • HD44780-based 2×16 LCD screen – for data display
  • PEC11 Rotary Encoder – for user input
  • PCF8523 Real Time Clock (RTC) – for accurate timekeeping
  • 5V submersible water pump – this will actually go in the water source
  • 5V relay module – to control the pump
  • Screw potentiometer – to adjust LCD brightness.

Background

I started this project thinking I would measure soil moisture and release water automatically. There are plenty of kits online that sell cheap PCBs shaped like a tuning fork for this purpose. These act as a potentiometer with resistance varying with moisture. Unfortunately they’re just not very accurate and worse the exposed metal corrodes over time. Supposedly capacitive sensors are better in this regard but I realized measurement isn’t very necessary. All our houseplants are watered on a schedule anyways, so I just needed a way to automate that.

Concept of Operations

The user configures how often they want the plant watered and how much water to use. Settings are selected by turning the rotary encoder and confirmed with a push. These settings translate to a time and duration to run the pump for. I did some experiments to measure the flow through the pump and found it conveniently moves about 1oz of water every 1 second.

The internal oscillator on the Arduino board will lose several minutes per day. While this is not a big deal for our application, I decided to add a Real Time Clock (RTC) module to the build. Accuracy loss on this device is several seconds per month! The big advantage is that the RTC can generate an interrupt on a configurable interval (I chose 10 seconds) to wake the board up.

After settings are confirmed, the unit goes into sleep (SLEEP_MODE_PWR_DOWN) until the RTC interrupt fires. If it’s not time for watering yet the unit repeats the sleep cycle. In theory this should make it low power enough to run off a 9V battery, though in our installation we used a USB cable and wall wart for power.

The pump is submerged in a vase of water. When time for watering, a digital output pin from the Arduino trips a relay which powers on the pump for the required duration (using 1s = 1oz). After watering is complete, a timer is set for the next watering interval and the unit sleeps again.

Wiring & Build

Sketch of wiring diagram between Arduino and major components.

I house the electronics in a simple project box and made the cutouts by hand with my Dremel. Boards were mounted using screws and standoffs. Admittedly the hand drilling and screws aren’t aesthetically pleasing, but I wasn’t going for looks in this project. The relay didn’t have mounting holes, so I used double-sided Velcro to mount it to the side.

I used some Arduino-shaped perfboard (sometimes called a Proto Shield) to mount the RTC and potentiometer for LCD brightness adjustment. Since it was inside, the LCD wouldn’t be user adjustable, but I really just needed to put it at a good set point once. I didn’t have a full ribbon cable for the LCD which made the wiring messier than desired, but all the connections were made following the above diagram without issue.

I wanted the pump wired so that it could be disconnected to move easily. I soldered the leads of the pump itself into a barrel plug and fitted the side of the project box with a barrel connector. With that it was ready to go!

Completed box with pump (left) and USB power (bottom) connections.

Code

The encoder knob was straightforward to work with using the encoder library. I found the knob quite sensitive so I adjusted the read logic to require four clicks to change a value.

int incrimentEncoder(int inc)
{
  long newPosition = enc.read();
  if (newPosition != oldPosition) 
  {  
    if ((newPosition-oldPosition)>=4)
    {
      oldPosition = newPosition;
      return inc;
    }
    else if ((oldPosition-newPosition)>=4)
    {
      oldPosition = newPosition;
      return -inc;   
    }
  }
  return 0;
}

Settings were applied by pressing the encoder knob down, which was measured by a digital input (buttonPin). I just had to implement a simple debounce routine.

/*  Check state of rotary button
 *  Return TRUE if button has been pressed
 */
bool buttonPressed()
{

  // No press detected, by default 
  bool returnState = false; 
  
  // Get current reading 
  int reading = digitalRead(buttonPin);

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) 
  {  
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  // Debounce 
  if ((millis() - lastDebounceTime) > debounceDelay) 
  {
    if (reading != buttonState) 
    {
      buttonState = reading;
      
      // Push is low, so register if pushed 
      if (buttonState == LOW)  
      {
        returnState = true;
      }
    }
  }
  
  //Store variable 
  lastButtonState = reading;
  return returnState;
}

The majority of the logic in the code has to do with moving through the screens to configure watering time and duration. The Liquid Crystal library helped here.

Finally, I needed to set up the sleep routines. This started by configuring the RTC in the setup routine, by using the RTC library.

  rtc.deconfigureAllTimers();
  rtc.enableCountdownTimer(PCF8523_FrequencySecond, 10);  // 10 seconds

An interrupt was attached to the 10 second timer from the RTC as well as the encoder button press, so the user could wake the unit up at any time.

void enableSleep()
{
  // Attach interrupts and make sure they have time to register before sleep
  attachInterrupt(digitalPinToInterrupt(sqwPin), timerIsr, FALLING);
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonIsr, FALLING);
  delay(100);

  timerFired = false;
  buttonFired = false;

  // sleep_mode() is a blocking call
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(sqwPin));
  detachInterrupt(digitalPinToInterrupt(buttonPin));
  Serial.println("morning.");
}

The variables timerFired and buttonFired are set in their respective interrupt service routines (ISRs) and checked in the main loop to take action. Each time the timer interrupt fires, we compare the current time against the time of the next watering and switch the relay on if it’s time to water.

void checkTimer()
{
  DateTime now = rtc.now();
  if (now > nextWatering)
  {
    Serial.println("WATERING");
    // Water now
    triggerRelay();
    delay(1000);
    lcd.begin(16, 2);
    lcd.clear();
    lcd.print("Done.");
    delay(1000);
    // Update timer for next watering interval 
    setNextWatering();
  }
}

The full code is available on GitHub.

The Test

After some checkout tests, the setup was ready for primetime. We connected the pump output through a small section of tubing into the pot. After two weeks away, the Bird of Paradise was well-watered and doing great when we returned!

The watering setup and a happy BoP.

Making my dumb air conditioner smart with Alexa and Adafruit IO

New “smart” air conditioners are internet-enabled allowing control anywhere via smartphone or voice assistant. Using a microcontroller, infrared (IR) LED, and several plug-and-play frameworks for the backend I was able to replicate the same functionality on my 10-year-old “dumb” air conditioner. I can now power it on/off with my voice and even turn the unit on from my phone so it is cool when I arrive home!

Major components used in this project were:

In short, the IFTTT skill for Alexa was used to relay my voice command to the Adafruit IO platform. My Arduino, connected to the Internet via the WiFi board and running the client software for Adafruit IO, sent the IR signal to power on the AC when the command was received.

Block diagram of connections between components.

Duplicating the Remote

My AC came with a small IR remote. First order of business was decoding the signal it sends when the power button is pressed so it can be played back from my custom circuit. Unlike other remotes that use a rolling code for security, the AC remote simply sends the same sequence each time.

A simple circuit with a TSOP382 IR receiver diode is connected to a digital input pin on the Arduino. Air conditioners tend to use longer control sequences than other IR devices, which was a problem for several decoder libraries I tried. I was able to decode the full sequence using this sketch from AnalysisIR.

I added a IR LED connected to one of the digital outputs through an NPN transistor to send IR signals from the Arduino circuit. The IRremote library was used to play back the raw sequence, which turned the AC on as expected!

Original air conditioner remote and IR receiver diode circuit to read its signal.

Connecting the Remote to the Internet

I created an account on Adafruit IO and set up a Feed called "Air Conditioner". The companion Arduino library uses the ESP32 WiFi module to connect to the Adafruit IO servers, listens for messages from that feed, and triggers a handler function in response to an incoming message.

// Set up the Air Conditioner feed 
AdafruitIO_Feed *acFeed = io.feed("Air Conditioner");

void setup() {

  // Start serial and connect to io.adafruit.com 
  Serial.begin(115200);
  while(! Serial);
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // Hanlder function for the "Air Conditioner" feed from Adafruit IO. 
  acFeed->onMessage(handleMessage);
}

I then created a Dashboard button on Adafruit IO to publish to the Air Conditioner feed. Since I only cared about the trigger, the button sets the feed’s value to ‘1’ each time. With everything connected, I verified I could power the AC on by pressing the dashboard button.

Plumbing the Back End

Just a few more setup items were required to connect commands from Alexa to Adafruit IO. I mostly followed this guide which outlined:

  • Installing the IFTTT Alexa skill and assigning a trigger phrase (I used "air conditioner")
  • Adding Alexa and Adafruit IO services to my IFTTT account
  • Setting up the "Send Data to Adafruit IO" action in IFTTT.

With everything in place, I was able to use voice commands to trigger the AC unit, as shown in the above video! As always, the code is available on GitHub.

Full circuit.

An Arduino-Powered Xbox 360 Costume

I recently picked up an Arduino Uno from Sparkfun with my last order. For years I’ve been using the MSP430 Launchpad as my microcontroller of choice mostly because they’re incredibly cheap and low power to boot. The Arduino and it’s user-friendly libraries make it easy to throw together a project very quickly.

That is exactly what I needed when I found myself the night before Halloween with no costume ready for the next day. Luckily I had almost all the materials I needed to build my Arduino-Powered Xbox 360 costume. With a little programming the “power button” lights up and flashes to mimic the Xbox 360 power up sequence. This project exemplifies the phrase “quick and dirty” but I think produced a good result!

The Finished Product

The Finished Product

 

The Supplies

I already had most of the components used in this build, the rest were easy to find at my local Radio Shack. Everything should also be readily available online.

Electronics

  • Green LEDs (x10)
  • 150 Ohm – 200 Ohm Resistors (x5), anywhere in that range works
  • NPN Transistors (x5) in TO-92 package such as 2N2222 or 2N3904
  • Arduino Uno
  • Protoshield for Arduino Uno, essentially just a big piece of perfboard with headers that plug into the Uno
  • SPST switch. I found this cool one at RadioShack.
  • 9V Battery Connector
  • 9V Battery
  • Assorted hook-up wire

Materials

  • Pizza Box. Dominos should give you one for free if you ask nicely.
  • Nylon Cord (what I used) or any type of thin rope.
  • Wax Paper, to diffuse the LEDs
  • White Paint
  • Plain White T-shirt

The Circuit

There are five segments to the power button. The center with the power logo and four quarter circle sections. Each is controlled separately by the Arduino. Each segment has two LEDs, though adding more LEDs is definitely a possibility.

The power supply for the circuit is a 9V battery. Each LED has a voltage drop of about 3V. I bought my LEDs in bulk on eBay, so I don’t have any exact specifications on the maximum current rating, but I would guess it’s in the neighborhood of 20mA. That means there must be a 150 Ohm current limiting resistor in line with the LEDs. I only had a few 150 Ohm resistors so I used 200 Ohm for a few of the LED segments, better to allow too little current than too much.

Furthermore the LEDs need to be switched on and off using the 5V I/O pins of the Arduino. For that an NPN transistor operating in saturation mode is used as a voltage-controlled switch. There will be five copies of this circuit, all tied into different pins of the Arduino.

LED Circuit

LED Circuit

The last part of the circuit needed is a power switch. This will be tied in series with the battery to turn the Arduino on and off. The other end of the switch is soldered to the VIN port of the Arduino which can handle a supply voltage in the range of 6V-20V.

Battery Circuit

 Switch Circuit

The Build

I started with a medium-sized pizza box for the housing.

Blank Pizza Box

I then cut out the center and four sides

Stenciled Pizza Box Cut Out Pizza Box

In order to wear the box I added a length of Nylon cord tied in a loop. I threaded this between two holes cut on the top of the box. I also threaded another length of cord through the back so I could tie the box to my waist and prevent it from flopping around. Lastly I painted the box with some white paint.

With String

The circuit was put together on an Arduino protoshield, I picked up one made by Seeed Studios but there are quite a few out there. The shield comes with pin headers that fit the Arduino Uno.

Uno with Shield

I assembled the transistors and resistors on the protoshield. The base of each transistor is connected to a pin on the Arduino through a piece of jumper wire. A resistor is connected between each emitter and a point on the board where wire leading to the LEDs will be attached.

Transistors Soldered In

Not The World’s Cleanest Layout, But It Works

I then wired in the battery snap connector and push button switch. The button turns the Arduino on/off by connecting/disconnecting power to the VIN pin. I gave the switch about two feet of wire so I could feed it out the side of the box and tuck it away in my pocket.

Board with Switch

I then needed pairs of two LEDs that could be positioned inside the box to light up each segment. I ended up cutting a few rectangles of cardboard, poking two holes through each, and taping two LEDs in place. The LEDs were connected to the board with some spare wire and heat shrink.

LED in Cardboard

I wanted each section to be lit up as smoothly as possible. The LEDs I got do a good job of lighting up the area directly in front of them but don’t allow much light out their sides. I wanted to light up each section as smoothly as possible so I took an extra step to help the light diffusion. I used some fine grain sandpaper (about 400 grit) to rough up the plastic housing around each LED. This helped quite a bit to diffuse more the light to the surrounding section

Sanded LEDs

With five LED sections made I just needed to tape them down in the correct spot in the box and connect each to the proper place on the protoshield. I programmed a quick Arudino sketch to turn on all the LEDs to make sure everything worked.

Center Lit

 

Lots of Duct Tape

Closeup Of Board Taped

 

Close Up Of The Arduino In Place

The last step of the box assembly was to tape a few sheets of wax paper on the inside of the lid of the box in order to help diffuse the LEDs and better hide the wiring and tape on the inside.

All LEDs OnSide View

 

Side View With Switch

The Software

I connected each quarter circle to a digital I/O pin on the Arduino. The center LEDs were connected to a PWM pin which allowed me to control the brightness. This was used to make a fade in and out effect for the center button.

The code runs through a set of functions to mimic the Xbox 360 startup sequence. Mostly this was just flashing various LEDs. To create the “chasing circle” effect the Arduino flashes the quarter circle sections one after the other for several revolutions around a circle.

The main loop switches between running the startup sequence, waiting with the “Xbox” on, turning everything off and waiting, fading the center LED, waiting, and running the startup sequence again. The delays make it so that your costume isn’t constantly flashing in peoples’ faces. It’s also cool when someone initially doesn’t realize the costume lights up and then it starts flashing like crazy.

The Arduino code is available on GitHub.

Finishing Touches

The last thing I needed to sell the costume was the rest of the Xbox. I used a sharpie and a blank t-shirt to draw out the rest of the front and back of the Xbox.

Tshirt Front

 

Tshirt Back

 

All that is needed is to throw on the shirt and pizza box power button and press the switch. The project looks okay in well lit rooms, but even better in the dark! Check out the completed project in action below.

 

 

 

Building A Home Lab: The Power Supply

The Motivation

Electronics labs at our universities and workplaces can have good sides and bad sides. Mine, for example, is filled with great equipment and knowledgeable people. However, it has a sum total of zero windows to the outside world. Occasionally it is nice to work on side projects at home at your own leisure. As a graduate student, funds for personal electronic equipment aren’t always plentiful so I’m trying to outfit myself with as much homemade equipment as possible. This is the start of what I’m hoping will be several posts about that process. I’ll be starting with one of the most basic pieces of equipment an EE needs, a power supply.

The Supplies

We’re going to be starting with a desktop computer power supply and convert it into something more friendly for electronics work. They look something like this:

Supply With Lid Off

Mine was salvaged out of one of those black Dell computers that universities like to buy (and later throw away) by the dozens. Inside they have a fan, transformer, regulator and some accompanying circuitry, and a rainbow of wires leading to some Molex connectors.

Warning: The power supply contains two very large capacitors that can hold a charge for long after the unit is unplugged. Let the power supply sit unplugged for several days before trying to open it up.

We’ll be wiring in 5 binding posts, 4 for our regulated voltages and 1 for ground. Sparkfun sells individuals for a few cents. I made each of the voltages red and the ground black. You can also choose different colors for each of the regulated voltages.

I also used an SPST switch I had laying around (I’m pretty sure I bought it from RadioShack at one time) as well as an LED and accompanying resistor as an indicator. You’ll also need a 10Ω 10-Watt power resistor to ensure our supply operates correctly.

I also gathered some other supplies for the build:

Build Supplies

  • Soldering Iron and Solder
  • Solder Helping Hands
  • Multimeter
  • Superglue
  • Heat Shrink Tubing
  • A Good Beer (not required, but highly recommended)

The Build

The first order of business is mounting the binding posts. I drilled five holes in the top of the power supply case. The posts pop right in and are held in place with a washer and nut. Next, a hole for the switch is drilled in the front of the case and the switch is mounted. Be sure to position the switch such that the case fits back on the power supply without bumping into anything.

Case With Hardware

Inside the power supply there will be many different colored wires. Most of these power supplies have a standard color scheme, but make sure to check with a multimeter to make sure yours follows it:

  • Orange: 3.3V
  • Red: 5V
  • Yellow: 12V
  • Blue: -12V
  • Black: Ground

In addition there will be three additional wires:

  • Green: Turns on the supply when shorted to ground
  • Purple: Puts out +5V when the supply is plugged in and off
  • Gray: Puts out +5V when supply is plugged in and on

We’ll connect one terminal of an SPST switch to Green and the other terminal to ground. When the switch is closed the power supply should turn on. The purple wire won’t be used, but could possibly drive a second LED to let us know that our supply is plugged in but the switch is off. The gray wire will be connected to our status LED that shows the supply is on and running. Connect the gray wire to a resistor. Connect the resistor to the anode of an LED and connect the cathode to ground. The value of the resistor can be sized depending on the LED voltage drop and current maximum. I used a 330Ω resistor which might have been overkill for a blue LED with such a high voltage drop, but we don’t need the LED to be very bright.

There’s one more thing to add to the case. Most of these power supplies expect a certain minimum load while they’re operating. If there’s no load on the supply sometimes the ±12V rails won’t be regulated to the correct voltage. In order for the power supply to behave properly we’ll connect a 10Ω resistor to the 5V rail to give the supply a constant load. Since there will be quite a bit of power dissipated through this guy, I chose a 10-Watt sandbar resistor. The resistor is superglued to the side of the case and connected between 5V and ground.

External Components Diagram

 

The step is fairly straightforward. Solder the four regulated voltages and the ground to the binding posts we attached to the case. We only need one wire per voltage so we can get rid of the rest to save some room inside the case. We could desolder them all from the board but I found that cutting them off was much easier. If there is any exposed metal where the cuts have been made we can cover the ends with a small bit of heat shrink to prevent any accidental shorting.

External Components WiringBefore plugging the supply in check that all the connections have been made correctly. Wrap all connections between wires or use heat shrink to make sure nothing is exposed. When the device is first plugged in all the posts should be at 0V. When the switch is turned ON the LED should light and each post should read the correct voltage. Each post should be labeled. I used a few zip ties to tame the remaining wires and put the case back on the unit. The wires should fit nicely in the space in the front of the unit.

Finished Case