DIY Plantduino

Basic essence of this project was to let me know when I need to water my plants and to ensure I don’t over water them. I’ll put the code up in a bit. This early version is a very ugly prototype with lots of wires running around for sake of quick development (so please don’t judge).

Made with Femtoduino. Connections are uber simple. Moisture sensor is available on eBay for really cheap. All you do is run your normal VCC and GND lines. Add analog read input on microcontroller A0 to sensor and you’re off and away. Entire project cost about $35 and took about 2 hours to completely assemble. LEDs are running through D5 and D9. You can skip the LEDs if you want and just use serial monitor as feedback but then it’s not very portable.

Next version would be to add WIFI and have each plant in my home tweet me when it needs water. I’m waiting for my Spark Cores to arrive (which have been delayed due to manufacturing issue) so I’ll have to be patient.

20140324-064350.jpg     20140324-064401.jpg

20140325-182732.jpg

Quick disclaimer on the code below: it is messy. I was looking to make it graphical like a dashboard which is why there’s value repetition. The sensor gives you a reading like 983 (for example) and rather than deal with massive ranges, I was going to have it display as just 9. Anyways, I’ll fix it later, I just didn’t want any confusion.

/*
  # Example code for the moisture sensor
  # Connect the sensor to the A0(Analog 0) pin on the Arduino board

  # the sensor value description
  # 0  ~300     wet soil
  # 300~800     humid soil
  # 800~1000    dry water
  # D5 Red LED for water
  # D9 Green LED for no water
*/

int nowaterPin = 9; //initializes green LED
int waterPin = 5; //initializes red LED
int analogPin = A0; //initializes sensor analog input

void setup(){
  pinMode(waterPin, OUTPUT);
  pinMode(nowaterPin, OUTPUT);
  Serial.begin(57600); //make sure your serial monitor is set to this baud rate. 

}

void loop(){

  digitalWrite(waterPin, LOW);
  digitalWrite(nowaterPin, LOW);
  int analogValue1 = analogRead(analogPin);
  int analogValue = analogValue1; // putting this here for future value manipulation
  Serial.print("Water Priority: ");
  Serial.println(analogValue);  

  //if sensor reading is greater than 700, time to water, turn on redPin as water needed
  if (analogValue > 700){
    digitalWrite(waterPin, HIGH);
    digitalWrite(nowaterPin, LOW);
    Serial.println("Water Immediately");
    Serial.println("");
  }
  //if sensor reading is less than 700, it is moist enough, turn on greenPin as ok
  else {
      digitalWrite(nowaterPin,HIGH);
      digitalWrite(waterPin, LOW);
      Serial.println("No Water Needed");
      Serial.println("");

  }

  //1000 milliseconds is 1 second, modify as needed. 60000 ms is 1 minute
  delay(1000);

}
Tagged , ,

Simple home automation: WIFI enabled light switch

They say “necessity is the mother of all invention” and this post proves that point for me. For the longest time, the power switch on my lamp at home has been broken. To turn it on, I would have to plug in the power cord. Sure, I could have just replaced the lamp or re-wired the socket to turn on with a light switch, but what fun would that be?

Instead, using an older Arduino Uno, WIFI shield and a single channel relay, I can now turn the lamp on and off using a web browser or my iPhone. This is the same principal behind Nest – the popular home thermostat that is web based (after all, a thermostat is just a bunch of solid-state relays).

My new WIFI light switch connects to my home network and creates it’s own IP address that can be accessed only from the same network. Once you upload your code, you can debug using the serial monitor to ensure it’s all working properly. It will also show you the IP address it created. Point your browser to that IP and you’re in! Then you just need a 5V power supply and you can plug this in anywhere – on reset, it will just run the code you previously uploaded. It also has a keep-alive loop so it remains connected.

I used a scavenged Sainsmart 5V single channel relay module I had left over. To connect the lamp to the relay, I cut one line of the power cord and just put the relay in between. One of the simplest and easiest to understand tutorials on relays can be found here. I love it when people make things simple to understand!

There is a really great new product on the market that would make this project pretty cheap. I ordered a couple Spark Core from Spark.io which is an Arduino clone with WIFI built in. This avoids the cost of an Arduino Yun or WIFI shield to really automate it.

IMG_3824 Slide1

I am thrilled. Imagine the possibilities – I can now automate anything in my house using a local IP based menu. Add voice recognition to this project, and you can literally talk to your appliances!

IMG_3826


#include <SPI.h>
#include <WiFi.h>

char ssid[] = "XXXXXXXX";      //  your network SSID (name)
char pass[] = "********";           // your network password
int keyIndex = 0;                 // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  Serial.begin(9600);      // initialize serial communication
  pinMode(9, OUTPUT);      // set the relay signal pin

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while(true);        // don't continue
  }

  String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();                           // start the web server on port 80
  printWifiStatus();                        // you're connected now, so print out the status
}

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("<font size=\"24\" face=\"arial\">Home Automation v0.1 alpha - System Online<br><br>");

            client.print("Desk Lamp 1: <a href=\"/H\">ON</a> | <a href=\"/L\">OFF</a></font>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(9, HIGH);               // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(9, LOW);                // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Action executed successfully.");
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}
Tagged , ,

World’s Smallest Arduino Clone w/BLE

After a long absence from the OMF blog, I’m happy to be getting back into the swing of things. I have been tinkering since my last post but there was nothing of note mentioning here…until now.

femtoduino-ble_full

I finally got my FemtoduinoBLE – which is an Arduino clone with on-board low energy bluetooth. The FemBLE uses BlueGiga’s BLE113 module which already meets radio frequency requirements in multiple countries. Additionally, the on-board USB is fully integrated into the ATMEGA32u4, so it can also be used to emulate a keyboard or mouse! How cool is that?

The on-board BLE113 module can be interfaced via the BGLib Arduino library

I’ll post a project or two using this board. A couple would have some very interesting applications such as theft control of a tagged item, loss recovery of a phone with bluetooth on board, and an innovative application for peer-to-peer mobile payments with immediate and automatic authentication (patent-pending🙂

Finger Print Scanner (GT-511C3) Library

fps11792-04

The Finger Print Scanner (GT-511C3) compact little module that allows you to register and identify fingerprints. It has a 450 dpi optical sensor and 32-bit CPU built into the board.

This is the updated version of the GT-511 which has an increased memory capacity. The module can store up to 200 different fingerprints and is now capable of 360° recognition.

There are so many projects that can be deployed with a fingerprint scanner. Add a 36V solenoid and you can open your front door with a thumbprint!

Understanding how to use this device can be a bit tricky. It requires a JST jumper cable (unless you want to solder onto the module directly). Pins 1 through 4 are found as follows:

11792-04

Pin 1: TX
Pin 2: RX
Pin 3: GND
Pin 4: VCC (3.3v to 6v)

The library to drive this module is available on GitHub: https://github.com/sparkfun/Fingerprint_Scanner-TTL

The easiest way to demo this would be to connect Pin 1 and Pin 2 to Arduino D3 and D4, respectively and run  FPS_Blink. If your FPS blinks blue, you’ve got it working!

I’ll post a more fulsome example this weekend hopefully. It’s been a crazy week at work so having some hobby time has been difficult to book.

Graphic LCD 128×64 STN LED using GLCD v3 (and buttons!)

This project aimed to work with a graphical LCD interface (20 pin) as opposed to the 2 line standard LCD displays (16 pin). The library used was GLCD (aka Graphics LCD) v.3 which is available here: https://code.google.com/p/glcd-arduino/

Image

KS0108B-hookup-400x511

Here’s an analog clock that can be controlled with a single button for time-setting:

IMG_3431

The cool thing about graphic LCDs is the wealth of new options available…such as menus:

Image

The menu library being used above is M2TIK library which is available here: https://code.google.com/p/m2tklib/

And you can control the LCD through either a direct connections to Arduino (although 16 of 20 connections have to plug into Arduino, your ability to expand further will be limited). With 4 buttons, a 10K trimpot and the LCD, there is only 1 Analog Input remaining on an UNO.

In previous projects, I’ve controlled LEDs using a Maxim 7219 integrated chip, I am wondering if it is possible to also control an LCD using the same chip or similar and reduce inputs from 16 to 4. I will post back here if I can.

The code is available within the libraries themselves. There is no point of repetition. Install the libraries into your Arduino libraries folder and restart your IDE.

Testing out Femtoduino USB

Works perfectly using simple LED blink command on digital output 3 and GND.

The Arduino IDE recognizes the micro controller as UNO so it is fully compatible.

It uses the ATMEGA328p chipset so you get all the functionality of a regular Arduino UNO.

Dimensions are ridiculously small at 2cm x 1.5cm.

Very cool. The possibilities are endless.

20131113-120349.jpg

The LED is direct plug into D3 and GND. And yes…it is blinking.

Buy it here for $19 for USB and $12 for ISP mode: https://www.femtoduino.com/

Updating firmware on Arduino WIFI Shield (for Dummies)

If you’re using Arduino IDE 1.0.5+ (if you downloaded the IDE in 2013, you will be using a version 1.2 or above) and you’ve purchased the WIFI shield from Arduino, you will need to update the firmware on the shield to work with the any IDE that is above 1.0.5.

20131111-062502.jpg

Arduino does have a tutorial for this upgrade, located here: http://arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading

But – if you’re like most new hobbyists, this will make little sense to you and how to go about updating firmware could become very frustrating. Accordingly, I’ve put this post up as an Updating Firmware for Dummies resource. Also – there are SO many resources for Windows but I could find nothing for Mac, so this is all devoted to Mac.

Step by step, I endeavour to make this extremely simple:

Step 1: Connect your WIFI Shield to your computer using the mini-USB and ensure that the Jumper is set to programming mode:

20131111-063201.jpg

The J3 jumper is bottom left corner of the SD card slot on your shield (circled in green below). By default, both pins are separate and there is a jumper on Pin 1 that allows you to connect Pin 1 and Pin 2 together. Setting both pins on the jumper will put your shield into programming mode and will allow you to upload the new firmware:

jumpers

Step 2: Download MacPorts (DFU Progammer):

Go to: http://www.macports.org/install.php#pkg and select your Mac OS version. Download it and install the latest version.

Step 3: Start Terminal (starts to get a little complex for beginners, so read each word carefully):

Terminal is Mac’s It is located in the Utilities folder within the Applications folder. When launched, it provides a line interface to control the underpinnings of the UNIX based operating system.

For some basic instructions on Terminal, click here for a great resource.

Terminal will look something like this:

Ok, now to start entering the required commands to update the software.

Type in the following carefully:

sudo port install dfu-programmer

Then  update macPorts:

sudo port selfupdate

And finally, update dfu-programmer and other ports to the most recent version:

sudo port upgrade outdated

Step 3: Download the most recent firmware from GitHub:

The latest firmware is posted on GitHub, and it’s a bit of a pain to get if you’re not familiar with using GitHub.

Go to: https://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares

Select WIFISHIELD and download the contents of this directory to the  same folder as your Arduino IDE. If you don’t know where your Arduino IDE is installed, you can use the locate command in terminal.

To download the repository from Github to your Mac, you will need to execute the following command from Terminal:

git clone git://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares/wifishield

If the above command does not work, you likely do not have Git installed properly. To install Git, go here: https://help.github.com/articles/set-up-git or click here to download GitHub for Mac in a simple GUI install.

If you installed your Arduino IDE properly, it should reside in the folder /home/users/YOUR_USERNAME/Applications/Arduino.app or just /Applications/Arduino.app depending on how you set up your Mac. If you need help finding files within Terminal, click here for a great learning resource.

Step 4: Rename the folder “wifishield” to “wifi-shield”

Once you download the Git repository, you will need to rename the directory.

It took me a while to figure out what was going wrong with my upgrade, only to discover hours later it was just a simple directory naming error.

The script you are about to execute in Step 6 defaults to the directory /hardware/arduino/firmwares/wifi-shield whereas the firmware you downloaded is /hardware/arduino/firmwares/wifishield. The easiest thing to do is rename the directory to “wifi-shield.”

Step 5: Move the firmware folder into your Arduino folder

You downloaded the firmware from GitHub and it’s now likely in your /Downloads folder. I would recommend moving this new firmware directory into the directory: /Applications/Arduino/hardware/

Within that update, there is a folder called scripts. Within that folder, there is a script called: ArduinoWifiShield_upgrade_mac.sh

Step 6: Execute the update script in Terminal

Type in the following command (which will upgrade your WIFI shield). Make sure your Jumpers are connected as shown above in green circle.

Now you can execute the firmware upgrade script:

./ArduinoWifiShield_upgrade_mac.sh -a /home/users/YOUR_USERNAME/Applications/Arduino.app -f shield

The first part of this command will execute the script called ArduinoWifiShield_upgrade_mac.sh. The second part is the directory where your Arduino IDE resides. And the last part is telling the script to upgrade the firmware for the Shield only. Entering in “all” instead of “shield” would upgrade all the firmwares.

Final Step: Reset your WIFI shield

If your script did the job properly, you should see a prompt in Terminal letting you know the update was successful.

Now, you will remove the Jumper back to its original state of and ensure Pin 1 and Pin 2 of the jumpers are not connected.

Once you have moved the jumper back, press the RESET button on your shield.

Firmware Upgraded! Congrats!

Did it work? Let me know!

Tagged , , , ,

LED Cube from Sparkfun (kit)

This was a soldering nightmare. 9 transistors, 18 resistors, 5 capacitors and 2 chips later…

20131111-061433.jpg

Custom animated characters on 16×2 LCD with potentiometer to control animation

IMG_3366

This is a simple custom character generator for the LCD screen. The trimpot is just for contrast whereas the potentiometer is used to control the speed at which the animation progresses through each “frame” of the animation.

The lessons learned were:

  • Generating any character on an LCD is literally 1s and 0s in the code;
  • A potentiometer can be used to control the speed of a loop in any output;
  • How to design a Fritz diagram (download directly from Fritzing.org)

Here is my first Fritz diagram:

Ohmyfarads1

And finally the code (sorry for the weird output):

/*
 LiquidCrystal Library - Custom Characters
 Demonstrates how to add custom characters on an LCD display.
 The LiquidCrystal library works with all LCD displays that have
 the 16-pin interface.
 This sketch prints "I heart Payfirma!" and a little dancing man
 to the LCD.

The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K potentiometer:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 * 10K potentiometer on pin A0
Created 21 Mar 2011
Original author by Tom Igoe
Modified 5 Nov 2013
Second author OhmyFarads
*// include the library code:
 #include &lt;LiquidCrystal.h&gt;
// initialize the library with the numbers of the interface pins
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// make some custom characters:
 byte heart[8] = {
 0b00000,
 0b01010,
 0b11111,
 0b11111,
 0b11111,
 0b01110,
 0b00100,
 0b00000
 };
byte smiley[8] = {
 0b00000,
 0b00000,
 0b01010,
 0b00000,
 0b00000,
 0b10001,
 0b01110,
 0b00000
 };
byte frownie[8] = {
 0b00000,
 0b00000,
 0b01010,
 0b00000,
 0b00000,
 0b00000,
 0b01110,
 0b10001
 };
byte armsDown[8] = {
 0b00100,
 0b01010,
 0b00100,
 0b00100,
 0b01110,
 0b10101,
 0b00100,
 0b01010
 };
byte armsUp[8] = {
 0b00100,
 0b01010,
 0b00100,
 0b10101,
 0b01110,
 0b00100,
 0b00100,
 0b01010
 };
 void setup() {
 // create a new character
 lcd.createChar(0, heart);
 // create a new character
 lcd.createChar(1, smiley);
 // create a new character
 lcd.createChar(2, frownie);
 // create a new character
 lcd.createChar(3, armsDown);
 // create a new character
 lcd.createChar(4, armsUp);
// set up the lcd's number of columns and rows:
 lcd.begin(16, 2);
 // Print a message to the lcd.
 lcd.print("I ");
 lcd.write(8);
 lcd.print(" Payfirma! ");
 lcd.write(1);
}
void loop() {
 // read the potentiometer on A0:
 int sensorReading = analogRead(A0);
 // map the result to 200 - 1000:
 int delayTime = map(sensorReading, 0, 1023, 200, 1000);
 // set the cursor to the bottom row, 5th position:
 lcd.setCursor(4, 1);
 // draw the little man, arms down:
 lcd.write(3);
 delay(delayTime);
 lcd.setCursor(4, 1);
 // draw him arms up:
 lcd.write(4);
 delay(delayTime);
 }
Tagged , , , ,

Distance measurement display on 16×2 LCD using HC-SR04

IMG_3363

Distance measure using Arduino UNO, Ultrasonic range finder (HC-SR04), LiPo battery and simple trimpot for contrast. Note that the HC-SR04 is only a sonic measurement and as such, you will not get accuracy over 20cm.

The Fritz diagram uses a 9V battery but you can use as little as 3V to power this project:

Ohmyfarads2

Code:


#include LiquidCrystal.h

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

int pingPin = 9;
int inPin = 8;

void setup() {
lcd.begin(16, 2);
lcd.print("testing...");
}

void loop()
{
 // establish variables for duration of the ping,
 // and the distance result in inches and centimeters:
 long duration, inches, cm;

 // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(pingPin, LOW);

 // The same pin is used to read the signal from the PING))): a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 pinMode(inPin, INPUT);
 duration = pulseIn(inPin, HIGH);

 // convert the time into a distance
 inches = microsecondsToInches(duration);
 cm = microsecondsToCentimeters(duration);
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print(inches);
 lcd.print("in, ");
 lcd.print(cm);
 lcd.print("cm");

 delay(100);
}

long microsecondsToInches(long microseconds)
{
 // According to Parallax's datasheet for the PING))), there are
 // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
 // second). This gives the distance travelled by the ping, outbound
 // and return, so we divide by 2 to get the distance of the obstacle.
 return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance travelled.
 return microseconds / 29 / 2;
}
Tagged , , , , , , ,
%d bloggers like this: