Battery powered plant watering using sleep mode

Getting Started

Watering a plant isn’t too hard, there are plenty of moisture sensors on ebay and you can get a small pump easily enough also.

A few things I wanted to do:

  • Program ADC outputs to be a power supply to the moisture sensor so I could plug it straight in the UNO
  • Operate an external pump
  • Power down the whole system periodically to save energy and allow it to run off a 9V battery

The hardest issue is the last one, I wanted to have a good battery life when running on a PP3 to make it viable anywhere in the house, not just near a plug socket, so after searching around on the web, I have included some basic functions  to manage power.

Moisture first

Reading the moisture is straight forward, although you might need to adjust the watering level and time according to your plant and pump. Setting up the analog pins to supply power is done as follows:

// so we can plug sensor module straight in to UNO analog connector
#define  VCC_PIN      A5
#define  GND_PIN      A4
#define  DLEVEL_PIN    A3
#define  ALEVEL_PIN    A2
pinMode(VCC_PIN, OUTPUT);
digitalWrite(VCC_PIN, HIGH);

pinMode(GND_PIN, OUTPUT);

digitalWrite(GND_PIN, LOW);
pinMode(DLEVEL_PIN, INPUT);

Pumping Water

The pump is connected through a L293NE  driver chip, just using 1 quarter of the chip as we only need to run forwards – so really just acting as a big power transistor to switch the pump power supply on and off.

Chip enable – Pin 1 is unconnected – it could be pulled high to be sure to enable the chip but floats there anyway. The motor is connected between 3 (the Y output) and ground. Y output passes whatever voltage is connected to pin 8, when the A input (pin 2) is pulled high. This is connected to Arduino digital output 13 – and so this turns the motor on and off.

Piuns 4 and 5 are connected to Gnd always and the chip takes it working supply from pin 16 which is connected to Arduino regulated 5V.

I use the VIN output from the Arduino to get an unregulated supply to the pump – this gives a bit more power.

So the upshot of all that is that raising pin 13 on the Arduino truns the pump on and lowering it turns it off.

Saving Power and Sleeping

A normal 9V battery provides about 600mAh of power, the pump needs up to 3W at 5V which should give 5/3 = 0.6A consumption, so about 1 hour of pumping. We turn the pump on for 3 seconds at a time which gives us 1200 waterings. At 3 a day that would last a year. The power used by the Arduino is low – maybe 40m

The chip is put into sleep mode for 8 seconds at a time and woken by the watchdog timer – which continues to run even in the lowest power down mode of the chip. There are numerous articles on this all over the web, so I just tried to encapsulate a few useful bits:

Here’s all the source code

Clock using 3.5 Digit Seven Segment Display and no extra hardware

Its been a while since I wrote anything here, but today’s post is how to run a common cathode multi digit seven segment display without extra shift regs or buffers.

I software multiplex the segments and use the INPUT_PULLUP mode of the digital pins to ensure only one digit is written to at a time.

I have actually used an RTC module for the time, but you don’t need one if you keep the power on and add a bit of setting logic :)

All the docs are in the code.

Nunchuck Controlled 3D cube on TV

This is pretty cool – I took the TVout library, the Wiichuck library and wrote a 3D library. Put them all together and got a nunchuck controlled 3D shape on TV. Movement in the nunchuck is detected by the arduino, then the cube is redrawn according to new angle of the controller.


At this point I ran out of memory but it wouldn’t be too hard to set up the shapes in FLASH instead of RAM. The hardware isn’t too complicated, just a few resistors and a pot for the speaker.

Driving a TV and speaker and reading a nunchuck
The circuit - just a few resistors

3d wireframe library header and source

Code to tie everything together

Analogue Clock on an 8×8 LED

OK so this is tiny but it implements the Bresenham line drawing algorithm and draws a clock…

The code is pretty simple.

Its running about 100x faster in this video so I can show how it works.

[[Schematic soon]]

Analogue Clock on an 8x8 LED
Analogue Clock on an 8x8 LED
Analogue Clock on an 8x8 LED
<object width=”425″ height=”344″><param name=”movie” value=”http://www.youtube.com/v/8JVI-0b46Wc?hl=en&fs=1″></param><param name=”allowFullScreen” value=”true”></param><param name=”allowscriptaccess” value=”always”></param><embed src=”http://www.youtube.com/v/8JVI-0b46Wc?hl=en&fs=1″ type=”application/x-shockwave-flash” allowscriptaccess=”always” allowfullscreen=”true” width=”425″ height=”344″></embed></object>

More POV

Got some POV code working….

Problem is sync – not synched at all, so you can see what it says but it has no idea when to start the sequence relative to the user waving it about.

We’ll investigate a switch with a weight on as a synch pulse soon.

Here’s some pictures of the board so far. The LEDs are mounted on some strip board and a length of old CAT5 connects it to a small shield board which plugs into the Arduino. The CAT5 supplies power and the three control lines for the shift reg.

A photo of LED wavy end bit and another of the whole lot

The bit you wave about
Both ends of the cable...

How the code works…

Its really simple… I wrote a C++ application to generate the alphabet. I’ll post that for download.

Then a message is simply an array containing a list of pointers to smaller letter arrays. Each letter array holds a length byte followed by the binary for the letters. Binary is nice because you can tell by looking whether its right.

So the code that really matters is:

int* iMsg[] = {H,E,L,L,O};
int iMsgLen = 5;

void loop()
{
  // send the next column for the current character
  sendByteOut(iMsg[iMsgIndex][iCharIndex]);

  // wait a moment
  delay(1);

  // move to the next column
  iCharIndex++;

  // have we run out of columns for this letter?
  if (iCharIndex == iCharLen)
  {
     // start at first column - 1 because 0 is length byte
     iCharIndex = 1;
     // and move to the next letter
     iMsgIndex++;
  }

  // now see if we have got to the end of the message
  if (iMsgIndex == iMsgLen)
  {
     // start at first letter again
     iMsgIndex = 0;
  }

  // set the length  - this could be in an if statement - but it really doesn't make much difference
  iCharLen = iMsg[iMsgIndex][0];

}

All the code is in the download area.

Doing the synch things seems like it will be fiddly. Might come back to that after a play with TV output.

Win32 .net application to generate Arduino font source code is her :  Adruino 8 bit font creator for POV

Thermometer and Clock

Schematic view - click for full sized version

So, for our first trick we thought we’d try and conjour up a thermometer, and then we added a clock as well – just for good measure.

Pretty much all the parts came from Cool Components or Maplin. I got a cheap 2 line display on sale which was the starting point, then wondered what we could create to educate…

The LCD interface is through 3 wires and a 4094 shift register. I’ve taken the example 3 wire LCD code from the arduino playground at http://www.arduino.cc/playground/Code/LCD3wires and modified and extended it a little to provide some positioning functions and improve the number drawing code.

Schematic and Breadboard

The breadboard version

Explanation

The thermometer functionality comes from TMP102 module which is connected through an I2C bus, implemented with the Wired library. The I2C interface is very easy to use, call

Wired.begin

in setup() to initialise it, then its a simple case of reading the latest temperature values. The addressing here assumes that the ADD0 line on the module is pulled to ground:

// Temperature module commands and registers
int  TMP_RD = 0x91;
int  TMP_WR = 0x90; //Assume ADR0 is tied to VCC
int  TEMP_REG = 0x00;
int  TEMP_ADDR = 0b1001000;

int ReadTemperature()
{
 int  val_h = 0;
 int  val_l = 0;

 Wire.requestFrom(TEMP_ADDR, 2);
 val_h = Wire.receive();
 val_l = Wire.receive();

  //  calc temp in C
 int tempint = ((val_h << 8 ) | val_l) >> 4;      // combine and shift
 float tempflt = float( tempint ) * .0625; // calculate actual temperature per chip doc
 return int(tempflt);
}

The clock works by using the millis() function  to establish a base time and a corresponding millisecond count – then we can update the display anytime by calculating the time since a known base. If the millis() wraps we adjust the base to the last known good value and go from that. There will be a little bit of creep there but only once every 1193 hours ish…  Clock adjustment is through two switches which pull digital inputs to ground – if they are low we increment the base Hours or Minutes value depending which button is pressed. The internal pull up resistors are used to ensure the inputs don’t float about when the button isn’t pressed, here’s an extract:

// set up input
 pinMode(HOURS,INPUT);
 digitalWrite(HOURS, HIGH);       // turn on pullup resistor

//Adjust the clock
 boolean    bRet = false;         // was an adjustment made
 if (digitalRead(HOURS) == LOW)   // read the input switch
 {
   iBaseH++;
   if (iBaseH > 23)
   {
     iBaseH = 0;
   }
   bRet = true;
 }

After that all you need to do  is just get data for the temperature or the time and then call the display routines.

The code for the whole thing is here.