Showing posts with label Arduino. Show all posts
Showing posts with label Arduino. Show all posts

Grow Bed Controller Coming to Tracker

You asked and we delivered - the first of the new distributed controllers is coming to Tracker:  the Grow Bed Controller.  Unlike the Aquaponics Controller, where the grow beds needed to be above the fish tank, the new Tank Controller and Grow Bed Controllers are intended for distributed systems, where the grow beds are a distance away.


Arduino Aquaponics: Grow Bed Controller
Grow Bed Shield.

A number of enhancements have been made.
  • The new ambient light sensor can calculate LUX to a high degree of accuracy with functions to prevent sensor saturation.
  • A new Ethernet board has been integrated to reduce costs and footprint of the original Ethernet Shield.  It uses the same chip as the Arduino Ethernet Shield means you can use the standard Ethernet library, thus no software change.
  • The on-board real-time clock now uses a bigger battery that can last around 20 years.
In addition, the kit itself has changed.  This will be a shield kit only (it comes with all sensors); you will need to provide your own Arduino Mega/ Mega equivalent - a highly demanded feature considering the price difference between official Megas vs SainSmarts and others.  Additionally, there will not be any mains electrical wiring & outlet combo for the 20-amp relay, in order to both extend to international client requirements and to not limit your wiring options (15-amp vs 20-amp wiring and outlets).

Grow Bed Controller features:

  • Tracker key
  • Ethernet
  • Grow Light control, 20-amp relay
  • Ambient Light (LUX)
  • Air Temperature
  • Relative Humidity
  • Waterproof Root Temperature
  • On-board real-time-clock (RTC) with battery backup to keep time if power is lost.






Real-Time Clock - Part II: Grow Light Controller

In Part I of this tutorial, you learned how to set up the ChronoDot  with the Arduino and use it to track time.  Part II continues the discussion by creating a timer that can be used to control grow lights.

In a previous post we talked about the importance of light for plants and the role grow lights play in Controlled Environment Agriculture either by monitoring current light levels and providing supplemental light, or by providing all of the light for a fixed time every day.  Part II focuses on the latter, creating a timer which toggles a light on at a certain time of day, toggles it off at another and uses the ChronoDot to track the time.


Parts List
1 x Arduino Uno R3 (IDE 1.0.3)
1 x ChronoDot
1 x PowerSwitch Tail II Relay
6 x Jumper wires


Fritzing Diagram


Figure 1.  Grow Light Timer diagram.

Arduino Libraries
In addition to the libraries from Part I, you will need two new libraries for this sketch:  Time and TimeAlarms.  The Time library is used to set the Arduino's system time as well as to compare times during the initial setup.

TimeAlarms is used to create two alarms, one for the time each day the light is turned on, and a second alarm for the time of day the light is turned off.

Download both zip files, extract them and move a copy into your Arduino's libraries directory.


Arduino Sketch
This sketch takes two times, given as hour, minute and second and creates an alarm for each.  When you first launch the script, the start time and end time are compared to the current time.  If the current time is between the two times, the relay is toggled ON.

During each operational loop, the current time is retrieved from the ChronoDot, the system time is reset and the current time is displayed.


Real-Time Clock - Part I

A fundamental necessity of any controls system is the ability to track time.  As far as we are aware, the Arduino has three methods it can employ:
  1. Serial.  Repeatedly get the time over the Serial connection.
  2. External Hardware.  Real-time clocks, like the ChronoDot from Macetech, establish a base time when the Arduino sketch is compiled.  When you request the current time in the sketch you actually receive a time based on the time that has elapsed since compilation.
  3. Ethernet.  Access time using the internet NTP service.
This tutorial set focuses on option 2.  In Part I we explain the basics of getting the ChronoDot set up and displaying the current time over serial.

The ChronoDot

The ChronoDot is a high precision real-time-clock (RTC) and boasts a number of features needed for Aquaponics. The V2.1 release introduced the DS3231SN chip, which has an industrial temperature range of -40C to +85C and outputs a temperature compensated time - important for aquaponic control systems that reside outdoors in the heat and direct sun.  
Figure 1.  The ChronoDot V2.1, credit Macetech.

The ChronoDot includes an onboard battery cell for a CR1632 battery, allowing the clock to keep track of time should the Arduino lose power, regain power and restart. Anyone in aquaponics can appreciate the ability of a control system to automatically reboot and resume operation in the event of a power glitch. The disadvantage of the ChronoDot, and RTCs in general is the inability to handle Daylight Savings Time.

The Environment DAQ can be configured with the ChronoDot using the prototyping area, which is exactly wide enough to handle the RTC (coincidence?). If mounting to the shield, you can access the pins from the bottom.
Figure 2.  Environment DAQ Shield with ChronoDot.

Parts List
1 x ChronoDot
1 x Arduino Uno R3
4 x Jumper Wires

Mounting the ChronoDot
The Fritzing diagram below shows how to connect the ChronoDot to the Arduino. Note that the RTC connections are on the right-hand side - the pins on the other side are not used.


Figure 2.  Connecting the ChronoDot.

Arduino Library
The ChronoDot requires two libraries
  1. Wire.h - Included with the Arduino
  2. RTClib.h - Download here.
Download the zip file and extract it. If necessary, rename the extracted folder "RTClib", and then move a copy into your Arduino libraries directory.

Arduino Sketch
Part I of this tutorial simply outputs the current time from the RTC to Serial; part two shows how to set create a toggle time.


Environment DAQ Update 2.2

Version 2.2 brings the new overview container as well as some updates to the CSS files for Firefox.


You can download Version 2.2 here.

Arduino Aquaponics: EnvDAQ with Water Temperature Sensor

Introduction
The Environment DAQ is an open source Arduino shield used to track air temperature, relative humidity and light in aquaponic and hydroponic grow beds.  An equally important parameter to track is root temperature and with the new prototyping area on the v2 Environment DAQ boards, it is easy to add a new sensor.

The goal is to add the water temperature sensor to the other sensors on the Arduino  shield.

This tutorial requires that you have already completed the tutorials: Environment DAQ and Water Temperature.  You can download the complete source code here.

Part I:  Arduino
In Figures A and B you can see the Fritzing diagrams.  Figure A shows the full Environment DAQ with the DS18B20 integrated in and Figure B shows it solo.

Figure A.  Full EnvDAQ with DS18B20 to digital pin 5.

Figure B.  DS18B20 solo to digital pin 5.

To start upgrading the Arduino sketch, include the one-wire libraries and the sensor information.

Figure C.  Include statements and assignments.
The DS18B20 is a one-wire sensor, meaning you could run more than one sensor to the same digital port and differentiate the values using the device address.  At the bottom of the highlighted code in Figure C you will find the device address for our DS18B20 used for the this tutorial.  The link above it is a tutorial for finding the address of your specific sensor.

 Figure D shows a miscellaneous string used to temporarily hold the water temperature reading.

Figure D.  Temporary string for holding the water temperature reading.

In setup(), we need to add the commands to begin the sensor and set the resolution - Figure E.

Figure E.  setup() commands for the DS18B20

Each sensor in the main loop resets a string to blank, requests the data string from its function and outputs the new string to Serial.  You can comment out the Serial when you put this into operation.

Figure F.  DS18B20 loop() code.

 Next, add the string from Figure F to the end of the GAE request - Figure G.

Figure G.  Add the water temp string to the end of the web request.

Finally, create the function that gets the root temperature and converts it from Celsius to Fahrenheit and finally, to the string the web request uses.





Part II: App Engine
To make this process as easy as possible, cut and paste the temperature code and add a "w" or "W" in the places shown.  This will dramatically decrease the chances of typo errors and the time this upgrade takes.

UserPrefs Model & Settings Template
Open settings.py and edit the UserPrefs model.  Add in the properties for water temperature minimum and water temperature maximum preferences - Figure 1.  This is the first example of the suggestion above about copy and pasting the temperature property data; here, copy and paste and a "w" to the beginning.


Figure 1.  Water temperature min and max preferences.

Scroll down settings.py and add the form variables below the light properties.

Figure 2.  Water temperature variables for settings form.

The water temperature preferences are in a template (which we will create in a minute).  First, add the code from Figure 3 to render the (yet-to-be-created) water temperature template and pass in the preferences.

Figure 3.  Render the water temperature template.

The water temperature template is loaded into the /templates/settings/content.html template - the main settings template.  Edit the template rendering code to pass in the water temperature template - Figure 4.

Figure 4.  Pass the water temperature template into the main template.

Next, edit /templates/settings/content.html by adding in the template variable for the water temperature template from Figure 4.

Figure 5.  Edit content.html for the new water temperature template.

Finally, create the water temperature template: water_temp.html.  Again, this is easily done by copying and pasting the original temperature.html code and add the "w" in places.  The full template is in Figure 6.

Figure 6.  Water temperature template.

Launch the web application in the sandbox and go to Settings to check the templates are loading correctly.

Figure 7.  Water temperature template rendered in Settings tab.

Saving Water Temperature Preferences
To save the preferences for water temperature, start by creating the onclick handler in javascript.  Open settings.js, copy the original saveTempSettings() function and edit for water temperature - Figure 8.

Figure 8.  Onclick handler for water temperature save button.

The onclick handler makes an asynchronous request to the server, so we need a request handler to process the request.

Figure 9.  Request handler for water temperature form.

Add the new request handler to the bottom so the request is properly routed.

Figure 10.  Request handler link.

Finally, reload the settings page in the sandbox and save water temperature settings.

Environment.py:  EnvData Model
In environment.py, amend the data model to include the water temperature parameter.


Figure 11.  EnvData water temperature property.

Adacs.py:  Arduino Request Handler
The request handler for the Arduino is in adacs.py.  Start by getting the water temperature argument passed from the Arduino and assigning it to WTemp.  Optionally, you can add a logging command to spit out the data that is passed.

Figure 12.  Arduino argument.

Next, assign the WTemp argument to the WTemp property of the EnvData model created in Figure 11.

Figure 13.  Assign the new argument to the WTemp property  of the EnvData entity.

One of the major upgrades to the EnvDAQ cloud application is the use of memcache.  Memcache stores data in system memory for a limited time and is specifically used here to hold the current parameters sent by the Arduino in order to reduce datastore read operations.  The original ~17,000+ read operations have been cut by a third, reducing the system load (and the potential for the server to instantiate new instances) and speeds up response times from the browser to the server.  Similarly, user preferences are stored in memcache.

Append the EnvNow assignment to include WTemp, before it is put in memcache.


Figure 14.  EnvNow with water temperature reading.

Test the Arduino request handler by typing in the following url in your browser

localhost:8080/adacs/arduino?Temp=84.1&Humidity=69.8&AmbientLDR=850&WaterTemp=75.0

If everything is working, the application will return "Connected".  To confirm the data was saved, open the Admin Console (localhost:8000/)  and then open Datastore Viewer.


water_temp.js
Just as we have JavaScript files for temperature, relative humidity and light, we need one for water temperature.  Create a new file: /static/scripts/water_temp.js and add the following

// Shared Aspects
var WTData = [['Time', 'WaterTemp', 'Min', 'Max']];       // Data for all water temp visualizations
var wtempChartData;

// Main Table
var wtempTable;

// Chart
var wtempChart;
var wtempChartOptions;

// Gauge
var wtempGauge;
var wtempGaugeData;
var wtempGaugeOptions;



function drawWTempTable() {
     // Chart data
     wtempChartData = google.visualization.arrayToDataTable(WTData);
     
     // Assign new visualization to DOM element
     wtempTable = new google.visualization.Table(document.getElementById('wtempTable'));
     
     // Draw Table
     wtempTable.draw(wtempChartData);
}     

function updateWTempTable(Time, TempValue, MinTemp, MaxTemp) {
     // Get the last row number
     var lastRow = wtempChartData.getNumberOfRows();
     
     // Get the value of the last row
     var timeStamp = wtempChartData.getValue(lastRow - 1, 0);
     
     //alert(timeStamp + ' ' + TempValue);
     if (timeStamp == 'Now') {
          wtempChartData.removeRow(0);
     }
     
     
     wtempChartData.addRow([Time, TempValue, MinTemp, MaxTemp]);
     wtempTable.draw(wtempChartData);     
     
}

/////////////////////////////////////////////////////////////////////////////////////////////////

function drawWTempChart() {
     wtempChart = new google.visualization.LineChart(document.getElementById('wtempChart'));
     wtempChartOptions = {         
       animation: {duration: 1000, easing: 'out'},
       backgroundColor: { fill: "none" }
     };
     wtempChart.draw(wtempChartData, wtempChartOptions);          
}


function updateWTempChart() {
     wtempChart.draw(wtempChartData, wtempChartOptions);
}



///////////////////////////////////////////////////////////////////////////////////////////////
/* Draws Water Temperature Gauge Using Water Temperature Chart Data */
function drawWTempGauge() {    
     var lastRow = wtempChartData.getNumberOfRows();
     var lastTemp = wtempChartData.getValue(lastRow - 1, 1);
     var minTemp = wtempChartData.getValue(lastRow - 1, 2);
     var maxTemp = wtempChartData.getValue(lastRow - 1, 3);
     
     //alert('MinTemp: ' + String(minTemp) + ' ' + 'MaxTemp: ' + String(maxTemp));
     
     
     wtempGaugeData = google.visualization.arrayToDataTable([
       ['Water'],
       [lastTemp]
     ]);
     
     wtempGauge = new google.visualization.Gauge(document.getElementById('wtempGauge'));
     wtempGaugeOptions = {          
       min: 0,
       max: 100,
       redFrom: 0, redTo: minTemp,
       greenFrom: minTemp, greenTo: maxTemp,
       yellowFrom: maxTemp, yellowTo: 100,        
       minorTicks: 5       
     };
     wtempGauge.draw(wtempGaugeData, wtempGaugeOptions);
}

function updateWTempGauge(TempValue, Threshold) {
     wtempGaugeData.setValue(0, 0, TempValue, Threshold);           
     wtempGauge.draw(wtempGaugeData, wtempGaugeOptions);
     
}

The new script needs to be loaded with the others.  Open /templates/main/scripts.html and insert the new script below light.  Do not put this script first - temp.js must be first.


Figure 15.  Include water_temp.js with the other JavaScript  for main.

Next, add the GCT elements referenced in water_temp.js to /templates/main/content.html.

Figure 16.  Div elements for water temperature GCT.


Main.js:  getChartData()
The AJAX request to the server to get the chart data on load is in /static/scripts/main.js. The function getChartData needs to amended in two places.  The first creates dummy data in the event the Arduino has not uploaded any data from the aquaponic/hydroponic system.

Figure 17.  Dummy placement data.

The second place pushes data to the WTData array created at the top of /static/scripts/water_temp.js.

Figure 18.  Add data to WTData array.

Finally, edit drawCharts() to include calls to water temperature.

Figure 19.  drawCharts with new water temperature function calls.


Environment.py:  GetChartData
The request handler for getting chart data is in environment.py.  Edit GetChartData so that it returns the water temperature data and preferences.

Figure 20.  GetChartData returning water temperature data and preferences.

Test
At this point you should be able to reload the main page of the webapp and be presented with the new charts for water temperature.

Figure 21.  New water temperature container.

Main.js:  UpdateChart
The second to last App Engine upgrade is getting the chart data for real-time graphing.  There are four places we need to edit /static/scripts/main.js.  First, add the lines from Figure 22 to include the new water temperature data from the JSON object.

Figure 22.  Get water temp data from JSON.

The next edit deals with resetting the charts should a new day roll over - this way, you are always view the current day's data and reducing the browser load.

Figure 23.  Reset charts if a new day is detected.

The code in Figure 24 adds the data to the original data array as a redundant measure should your browser window change size and automatically redraw the charts.

Figure 24.  Add new data to original data array.

Finally, add the function calls that update the water temperature charts.

Figure 25.  Update water temperature charts.

Environment.py: UpdateChart
In environment.py we need to edit updateChartData().  The request handler is a conditional that tries to get the EnvNow data (as Environment) from memcache.  The first condition occurs if the memcache has expired.


Figure 26.  No memcache of current data.

The second condition returns evaluates the timestamp against the current data in memcache and returns the data only if the timestamps are different.

Figure 27.  Memcache is present and timestamps are different.

That's it!  The DS18B20 in this tutorial is meant for the grow beds, but the code would work if you put it in the stock tank as well.  If you want to take this a step further, you can plot both air temperature and water (root) temperature on the same chart for comparison.

Related Projects:
Environment DAQ
Pump Controller

Related Parts:
Water Temperature
Temp and Humidity
Light
pH
Dissolved Oxygen

First Batch of Environmental Shields

Update: 6/5/2013
For those who emailed about purchasing the blank PCBs, you can find them above:  Blank PCBs.

The new Arduino Environment Shields came in today.  The major improvements are the use of screw terminals, which allow for the replacement of parts, a new prototyping area for customization and a new connection for a relay bi-color LED indicator.

Arduino Aquaponics Environment Shield.
More significantly, the new layout takes the two old boards (DAQ and Controller) and combines them into a single board - you may start out only interested in data acquisition and decide to add the control components later.


Environmental Controller mid assembly.

Obviously, hardware wasn't the only area we expanded upon, in fact, the software improvements are where the real changes can be seen.

The new timezone module streamlines the handling of time transitions and comparisons as well as Daylight Savings Time.

The real-time data visualizations in the cloud application now include context by plotting data against preferences, specifically minimum and maximum values for parameters.  Below is a gauge of the current temperature.  Instead of hard-coding red/green/yellow ranges, the ranges are set by user preferences and can be changed on the fly in the Settings tab.

Preference Range:  65 to  95 degrees Fahrenheit. 

The Environment Shield can be set to one of seven different modes: one for data acquisition only and then six for controlling grow lights, foggers, dehumidifiers, portable heaters, fans, etc.  All seven modes feature the data acquisition.  Changing modes is as easy as pressing a button and plugging in your device.

Memory cache has been implemented reducing datastore requests to one-third the original number and increasing service speeds.

The final two upgrades are perhaps the most important.  First, we have implemented Responsive Web Design, giving you an optimized interface across any device and screen size.  No more pinch-to-zoom on your mobile smartphone or tablet, the visualizations and layouts dynamically adjust.  The visualizations themselves are SVGs and built using AJAX; by including RWD practices we have removed the platform barriers separating iPhone, Android, Blackberry and Windows.

Lastly (but most exciting) the new cloud applications for the Environmental Controllers can sync with Aquaponics Tracker, providing a means of interfacing multiple controllers across a number of systems into a single screen with water quality and grow bed tracking.

Arduino Aquaponics Multi-Controller UI Overhaul

A new feature we are rolling into the Aquaponics Multi-Controller UI is graphing data with on-demand thresholds - in other words, if you change the minimum or maximum threshold for air temperature, the data is re-plotted against the new thresholds; the gauges will also reflect the thresholds.  




You can see the change in the line chart above.  And no, the data controls and quick alert icons haven't moved, we just removed them here for testing.

Aquaponics: Arduino Email & Text Messaging

Background
With all of the lauded benefits of aquaponics, there are a number of drawbacks and they primarily lie in the need for electricity.  Typically there is at least one pump, but if you also use grow lights, water heaters and other electronics, you'll inevitably increase possible points of failure.  Wouldn't it be nice if you knew right away when pumps fail, grow lights burn out or don't come on, water heaters die, water temp plummets, a grow bed or fish tank springs a leak or overflows, humidity gets too high/low or the summer sun roasts your greenhouse?

Automation can immediately act to correct some of these conditions but sometimes you don't have a backup pump, grow light or stock tank heater.  Leaks, especially in basement systems, can ruin property if it's not addressed quickly.

What you want is a way to know what's going on as it happens and a very good way of doing that is through text message or email.  That's what this guide is all about and it's not unique to aquaponics or hydroponics - it can be used any time the Arduino needs to alert you of a sensor reading.

The Arduino Data Acquisition and Control System (ADACS) projects in Automating Aquaponics with Arduino use the mail API to notify owners of failed/blocked pumps, when environmental conditions move outside of user-defined ranges, and when grow lights fail or don't turn on.  Additionally, you'll be notified when the Arduino has failed to connect to the webapp for a set period of time to indicate a potential power loss or loss of an internet connection.  Knowledge of what is happening in your system is the most powerful tool of all and when you combine the Arduino in your aquaponics or hydroponics system, you get an inexpensive means of acquiring that knowledge.

How It Works
Like all of our web-based projects we'll use Google's cloud infrastructure, App Engine.  We'll set up an Arduino Uno with two push buttons, which, when pressed, will send a web request to App Engine and prompt either an email or a text message.  The client consists of a very basic form to collect the designated email address and text address.

Hardware
1 x Arduino Uno R3
1 x Arduino Ethernet Shield R3
2 x Momentary button or switch
2 x 10k ohm resistor
1 x Small breadboard
Breadboard jumper wires

Software
Arduino-1.0.3 IDE
Google App Engine Python SDK: 1.7.4
Python 2.7
Ubuntu 12.04*

*These instructions are probably very easy to translate for Windows or Mac, but as we have neither I can't help you there.

Step 1:  Create a New App Engine Application
The first step will be to create a new application on App Engine.  As all of our web application use App Engine, we've created a standalone tutorial to cover it: Creating a New Application.

Step 2:  App Engine - Configure app.yaml
  • The email alerts reside in a file called alerts.py.  We need to add that file to our app.yaml file, Fig 1.
Fig 1.  Add alerts to app.yaml
Step 3:  App Engine - models.py
  • In the typical MVC (Model, View, Controller) pattern, we need to create a model of our data, which resides in models.py and is imported to the files that need to access it.
  • We have one class to create, the UserPrefs class, which has three properties
    1. Time zone offset - not used in this tutorial
    2. Email Address - string property
    3. Text Address - string property
Fig 2.  models.py
 Step 4:  App Engine - main.py and Templates
  • Open main.py and add the import statements, Fig 3.
Fig 3.  main.py import statements
  • The first three imports are used to display the templates and run the application.  The users import is used to get the email address of you (the email address you used to create the application).
  • models is used is the file containing the UserPrefs data, which we covered in step 3.
  • main.py consists of just two classes: MainPage and SaveAddress. You can see MainPage in Fig 4.  
Fig 4.  MainPage class.
  • The title of the page is sent to the header template, which you can see in Fig 5.  This is how data can be passed into generic templates, reducing redundant programming.
Fig 5.  The first part of header.html
  •  In order to send emails or text messages you'll need to provide an address, so we add a very simple form to header.html.  You can see the complete file in Fig 6.  The form consists of two text fields and two buttons.  Each button is given a JavaScript onclick handler discussed in the next step.
Fig 6.  Full header.html file
  •  footer.html is a truly uninspiring file and only consists of closing tags
</body>
</html>
Step 5:  Email & Text Messages
A word on email addresses.  The email address you put as the sender must be an email address associated with the account you used to make the webapp.  You can also invite other Gmail addresses to be admins.  The email address you are sending to can be any valid email address.
Text messages can be sent through an email client such as Gmail given you format the address correctly.  Here is a link on the different formats carriers use for SMS and MMS.  We have only confirmed the Sprint format so I will use that as the example.

Sprint's SMS email format looks like this:
<your phone number>@messaging.sprintpcs.com
Example:
 
1234567890@messaging.sprintpcs.com
A Sprint user would substitute their phone number in and use this for the text message box.

Step 6: JavaScript and Form Processing
  • With our template and form in place, we will use JavaScript to send an asynchronous request to the server to process the form.  I've separated the JavaScript into two separate files.  The first is utils.js, Fig 7, and contains the function to create a request.  Looking back at Fig 6, you'll see utils.js is loaded before our second JavaScript file, main.js
Fig 7 - utils.js
  • Next, main.js contains the two onclickhandlers we referenced in the form.  I created them separately for readability in this tutorial, we could have easily created a single button to do this work. When a save button is clicked, a series of events takes place and you can read that in the comments.
Fig 8.  main.js
  • The webapp code to process the JavaScript requests is the second class in main.py, SaveAddress.
Fig 9.  SaveAddress in main.py
  • The JavaScript request is parsed and the UserPrefs entity with the email address you used to create the app used as the key_name.  If the entity exists, you will update the emailAddress or textAddress properties, otherwise a new entity is created.  Finally, the entity is put into the datastore and a response is made.
Step 7:  App Engine - alerts.py
  • alerts.py has one class, Alert, used to handle the Arduino request.  There is also one function, SendAlert used to send an email or text message.  First we list our imports
Fig 10.  alerts.py import statements
  • The Alert request handler parses the request from the Arduino to determine the type of alert you want, email or text, Fig 11.
Fig 11.  Alert request handler
  • The request handler for the Arduino parses the request to find out which type of alert you want, text or email.  Then it calls the SendAlert function passing in the type of alert and a message.  This makes the alert function generic and reusable.
Fig 12.  SendAlert
Step 8: Arduino - Fritzing Diagram
  • The circuit for this tutorial is very straight forward and consists of two push buttons.  One push button is used to request an email, the other a text alert.
Fig 13.  Fritzing Diagram
  • In Fig 13 you see a tiny breadboad sitting on an Arduino Uno R3.  In reality, the breadboard resides on an Ethernet Shield, or better yet, a proto shield on an ethernet shield on an Arduino R3.
Step 9: Arduino - Code
  • Start by setting up the Arduino with your assignments
Fig 14.  Arduino assignments and imports
  • The setup loop begins the serial output and the Ethernet.  It sets the pin mode for the pushbuttons to INPUT and finally notifies the user that setup is complete.
Fig 15.  Arduino setup loop.
  • The operating loop monitors digital pins two and three to see if the push buttons have been pressed.  If they have, we call the sendAlert function with the type of alert we want.
Fig 16.  Operating loop
  • sendAlert outputs via serial the type of alert being requested.  Then it creates a GET request to the Arduino and finally outputs the response to the screen.
Fig 17.  sendAlert Arduino function
  • The final two functions in the Arduino program are our normal response parsing and httpRequest functions.
Fig 18.  HTTP response parsing and request functions
And there you have it - two buttons to send either a text message or an email.  While the button format may seem useless think about this - the Arduino read the state of a pin before making the request and the GET request was generalized to allow either button to request the same function.

By extension, the Arduino can read the state of any input pin, analyze the reading via conditionals and send an alert if it needs to.  The Arduino Aquaponics code in the ADACS is rather large, so rather than apply conditionals on the Arduino, the values were automatically sent to App Engine and App Engine applied the conditionals to decide if an alert was needed.  This freed up valuable programming space and extended the number of conditionals that could be applied.