Came upon this bike plan while browsing this evening. Pretty excited to see that more off-road bike trails are on their way. Also a good resource for existing paths.
Some Awesome Dogs For Adoption
August 7th, 2011 · Photos
These are just a few of the dogs available from A Different Breed and Pup Your Ride Animal Rescues. I take pictures of their dogs every weekend for their posts on Petfinder.com. If you are interested in any of these dogs, just let me know and I’ll direct you to the right people.
→ No CommentsTags:ADB
An Arduino-Based Weather Widget
August 7th, 2011 · Arduino, Electronics, Science and Engineering, Useless Stuff
My project for this weekend was to develop a internet-connected weather station. I call it GWeather. Here is some of the latest data from GWeather. A picture of the hardware is shown below. On the right is the Arduino board. The sensor is the little board with the yellow wires. There wasn’t much to the hardware… just plug it in to the Arduino.
Instead, this turned out to be a very software intensive project. It covered a lot of languages I am only roughly familiar with including: C, C#, php, javascript, and html. I learned a lot. Here’s a summary…
The following schematic illustrates the major components and data path of the weather station. A barometric pressure sensor senses both pressure and temperature and communicates this data using an I2C protocol to the Arduino prototype board (microcontroller). The Arduino processes this data and writes it to serial line. This information is communicated to a computer, where a C# reads the data and adds the data to a MySQL database online. The final step is for a webpage to request the data from the database and display it to the user.

Let’s walk through how the system stores the data to the MySQL database. First, the user launches a C# program on the computer. A screenshot of this software is shown below. The user selects the time interval between sensor measurements (e.g. 10 minutes). After clicking the “Collect and Upload Data”, the program starts a timer. After 10 minutes, the timer sends a message to the Arduino requesting a new weather measurement (temperature and pressure).
The following code shows how the C# software sends the message to acquire new sensor data through the sensor port. For the message, I chose to use the “A” character for simplicity. This code executes in a timer tick event every 10 minutes (or whatever interval the user selects).
// Setup and open the serial port to the Arduino
SerialPort sp = new SerialPort("COM4");
sp.BaudRate = 9600;
sp.Open();
// Send the message to the Arduino to acquire new sensor data
sp.Write("A");
// Sleep for 100 msec to give Arduion time to make measurement and return through the serial line
System.Threading.Thread.Sleep(100);
The Arduino is constantly checking the serial line to see if it needs to acquire the sensor data. Once the Arduino sees the “A” command on the serial line, it starts the data acquisition from the BMP085 Temperature and Pressure sensor. I am using the BMP085 breakout board from Sparkfun electronics . I shamelessly used most of the code from another Bildr tutorial. When the program initially starts, it loads calibration data stored on the BMP085 sensor. These data values are required to calculate the temperature and pressure output from the sensor.
The Arduino then enters the loop method, which I have included below. It runs through this method continuously. First, the Arduino check to see if there is any data available on the serial line. If the incoming byte is A, it records the temperature and pressure and writes these values to the serial line, which will be collected by the C# program.
void loop()
{
if (Serial.available() > 0)
{
// read the incoming byte
int incomingByte = Serial.read();
if (incomingByte = 'A')
{
float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
float pressure = bmp085GetPressure(bmp085ReadUP());
Serial.println(temperature, 2); //display 2 decimal places
Serial.println(pressure, 0); //whole number only.
}
}
}
At this point, we jump back to the C# program. The C# program reads the two lines from the serial port and stores these data in the variables “temperature” and “pressure”. The work with the serial port is done in a try catch statement to capture exceptions (that is, errors).
The next step is to open a connection to my MySQL database. I have this database with my hosted website plan. I created a table specific to this project. I have placed generic placeholders in the code below. A command is then sent to insert the recent time, temperature, and pressure measurements into my table (called “history”). The connection is opened and this command is executed inside a try catch statement. Again this is to catch errors that may occur if my internet connection or webserver go down. At this point, the new measurement data is now stored in my online database. The next step is to write code to get data from the server.
try
{
// ...
temperature = System.Convert.ToDouble(sp.ReadLine());
tbTemp.Text = temperature.ToString();
pressure = System.Convert.ToDouble(sp.ReadLine());
tbPressure.Text = pressure.ToString();
sp.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
this.Invalidate();
string MyConString = "SERVER=myhostaddress;" +
"PORT=3306;" +
"DATABASE=mydatabasename;" +
"UID=myuserid;" +
"PASSWORD=mypassword;";
MySqlConnection connection = new MySqlConnection(MyConString);
MySqlCommand command = connection.CreateCommand();
command.CommandText = @"insert into history (Datetime, Temperature, Pressure) values(UTC_TIMESTAMP()+0, '" + temperature.ToString() + "', '" + pressure.ToString() + "') ";
try
{
connection.Open();
command.ExecuteNonQuery();
lblTrouble.Text = "";
}
catch (Exception ex)
{
lblTrouble.Text = ex.Message;
}
this.tbUpdate.Text = System.DateTime.Now.ToString();
connection.Close();
this.Invalidate();
To get the weather data from the database, the first snippet of code is a php script. This is included below. The php script creates a connection to the mysql database called “gbonnem_weather”. I then perform a query were I select everything from my “history” table, where the table entries are ordered by the keyid (the record number) descending where I limit the number of results to the input variable $num.
The data from the MySQL database is converted to more familiar units (deg F and inHg) and stored in the $temp_array variable. Towards the end, this variable is encoded to JSON (Javascript Object Notation) for the javascript function that calls this php script.
<?php
$num = $_GET["num"];
$con = mysql_connect("mydatabase_address","myusername","mypassword");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
else
{
mysql_select_db("gbonnem_weather", $con);
$result = mysql_query("SELECT * FROM history ORDER BY keyid DESC LIMIT " . $num);
date_default_timezone_set("UTC");
while ($row = mysql_fetch_array($result))
{
try
{
$temp_array["Datetime"] = strtotime($row["Datetime"])*1000;
$temp_array["Temperature"] = $row["Temperature"]*1.8 + 32;
$temp_array["Pressure"] = $row["Pressure"] / pow(1 - 0.0065 * 200 / 288.15,(9.80665 * 0.0289644 / 8.31447 / 0.0065)) * 0.0002952998;
$return[] = $temp_array;
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
$output = json_encode($return);
mysql_close($con);
echo $output;
}
?>
So now we look at the code for the webpage. I am using both jQuery and Flot (a jQuery plotting library) and I incorporate those in the <head> section of the html document. I create to <div> with id’s called tempPlot and presPlot for the temperature and pressure graphs, respectively. The next section is another chunk of Javascript code where we get the information from the MySQL database. First, I call the php function (ab0ve) to return a JSON array with the data. Right now, I requested 1000 measurements – a generic number of data points. I’ll update this to be user-selectable at some point in time. The for loop loads the time and temperature data into the temps array and the time and pressure data into the press array.
Note: the datetime information was a little tricky. I ended up using Unix Timestamps as it is needed for the flot plotting library. These are the number of seconds after January 1, 1970 at 12:00am. The subtraction I am doing is converting the UTC time record to my local timezone. The flot library likes these timestamps to be in milliseconds rather than seconds, which is why I have the additional factor of 1000.
The last part of the javascript is calling the plot method of the flot class.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="javascript" type="text/javascript" src="http://www.gtbonnema.com/Javascript/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="http://www.gtbonnema.com/Javascript/jquery.flot.min.js"></script>
<title>The GWeather Station</title>
</head>
<body>
<h1>GWeather</h1>
<div id="tempPlot" style="width:600px;height:400px;"></div>
<div id="presPlot" style="width:600px;height:400px;"></div>
<script type="text/javascript">
$.get("http://www.gtbonnema.com/test.php",{num:"1000"}, function (data) {
var data2 = eval( data );
var temps = [];
var press = [];
for (var i=0; i<1000; i++)
{
temps.push([data2[i].Datetime - 5*60*60*1000, data2[i].Temperature]);
press.push([data2[i].Datetime - 5*60*60*1000, data2[i].Pressure]);
}
$.plot($("#tempPlot"), [{label: "temperature", data:temps}], {series: {lines: {show: true}, points: {show:true}, color: "red"}, xaxis: {mode: "time"}});
$.plot($("#presPlot"), [{label: "pressure", data:press}], {series: {lines: {show: true}, points: {show:true}, color: "blue"}, xaxis: {mode: "time"}});
});
</script>
</body>
</html>
This is essentially it. To see the final product, follow this link to the GWeather Site. If you are feeling too lazy to click the link for the most recent weather data, here are some screenshots from the two plots.
So what’s next? Well, depending on if I can find the time, I’d like to do several things:
1. Work on the website. Maybe use AJAX to give the visitor the ability to control the plots like select time ranges, etc. I’d also like to place some statistics like the maximum, minimum, and average temperatures over the plotted range. Maybe include the most recent temperature as well.
2. Make this thing wireless. Right now, I have a USB cable going through the door and my Arduino and breakout board sitting on my patio.
→ 1 CommentTags:Arduino·csharp·pressure·software·temperature·weather
Camping with Jade
July 31st, 2011 · Jade, Trips
For the past few weeks, I have been slowly building a collection of camping gear using a website called steepandcheap.com. The website offers deeply discounted outdoor gear. I have purchased a tent, a sleeping pad, and clothes among other things.
With this new gear, I decided to head out Saturday evening to Ray Roberts Lake State Park. More specifically, I chose to camp in the Hawthorn campsite which has around 30 primitive camp sites (no electricity). My campsite in comparison to my apartment are shown in the Google Map below.
View July 30 Camp Site in a larger map
I arrived at the campsite around 7:30pm. The temperature was hovering around 100 F as I pulled into the parking lot. I threw on my pack, which was surprisingly heavy, and walked the 0.25 miles to my campsite with Jade. Once at the campsite, I quickly assembled the tent, which you can see below. The obvious question is “a white tent?” So steepandcheap.com offers heavily discounted outdoor products one at a time. After watching the website for several days, this was the first 2-person tent so I jumped for it. I got a great deal but a white tent wasn’t my first choice. Anyhow, it will surely turn a nice tan color after a few more trips.
You can see the lake between the trees. After setting up camp, I took Jade for a short walk along the shoreline. We saw a large heron but no other signs of wildlife. After the sun had set, there were some fish jumping out of the water which got Jade excited.
One of my main goals from the trip was to capture some nice star trails. To do this, you set your camera up on a tripod and point it towards the sky. With a long exposure, you can capture the trail of light from each star as the earth rotates. For digital cameras, the electronic noise of the sensor significantly degrades the photo for these long exposures. Instead, a series of photos are taken and then digitally combined later on a computer. My camera has settings to take pictures at regular intervals. I chose to do 20 second exposures with a 1 second interval. This would result in roughly 3 pictures / min or 180 pictures / hour. I set up the camera, got it working, and went back to the tent to get some sleep. When I woke up the next morning, my camera stopped for some reason so I didn’t get to capture a full star trail but I was able to put the following photo together.
Getting to sleep in the 90+ temperatures was difficult. Even though I had a little battery powered fan, I was very uncomfortable. Based on the amount of panting and flying slobber, my guess is Jade was having a difficult time sleeping as well. I tried to beat the heat by constantly drinking water and squirting it on my forehead and chest. Slowly but surely I fell asleep. I was awoken a few times mostly for the temperature and once for some commotion outside the tent. I suppose we had some raccoon or possums passing by in the night. I had hung all of my foot above the ground using a pole provided at the campsite. Jade gave a few hesitant barks and the rustling in the forest slowly subsided. I tried to peek out the tent to see what animal was around but I never saw it.
Morning finally came and the temperature was much nicer (around 80F). Although the temperature was the worst problem of the night, I was very comfortable using my memory foam, self-inflating sleeping pad. I was really surprised by how well it worked. Anyhow, Jade and I got up and meandered around the shoreline. I would guess Jade was enjoying the morning more than I was.
I snapped a few photos but nothing too amazing came from it. I packed up camp and headed back to the car in a rush back to civilization, particularly a McDonald’s breakfast.
Overall, it was a tough night. It was really hot both for me and the dog. However, I think I can be more confident that future camping trips will be more enjoyable, especially as things start cooling off as we move toward Autumn.
A Different Breed Animal Rescue
April 17th, 2011 · Photos
I got an opportunity to play with some dogs at a local rescue called A Different Breed Animal Rescue. I also got to snap some photos during the time to help the dogs find a home on Petfinder. Here’s one of the rescue’s – Dolly.
→ No CommentsTags:
Kingkiller Chronicles – Book 1 and 2
April 3rd, 2011 · Books
Just finished the first two books by Patrick Rothfuss: The Name of the Wind and The Wise Man’s Fear. Simply awesome.
→ No CommentsTags:
What $500 courtside seats look like
March 24th, 2011 · Useless Stuff, Videos
Untitled from Garret Bonnema on Vimeo.
→ No CommentsTags:
The Supermoon
March 19th, 2011 · Photos, Science and Engineering
This weekend marks a unique day in the astronomy world. The moon is at its closest distance to the Earth within the past 20 years. I marked the occasion by taking a few snapshots this evening from atop my apartments parking garage. The following photo is a combination of 4 photos taken in 4 min increments. Notice how the moon changes color as it rises from the horizon. This happens cause of Rayleigh scattering, which causes shorter wavelengths like blue to be scattered (“bounced around”) more readily than longer wavelengths, like red. When the moon is at the horizon, the light has to travel through a lot of atmosphere to get to your eye. By the time the light gets to your eye, a lot of the shorter wavelengths have been scattered away – that’s why the moon has a redish tint. As the moon rises further from the horizon, the light travels less through the atmosphere meaning less blue light is lost. That’s why the moon starts looking “whiter” as it gets higher in the sky.
Here’s another simple black and white photo of the moon.
→ No CommentsTags:









