Skill level:     Intermediate
 

Tweeting Kegerator

by Devlin  |  
September 10, 2009  |  

A pint of beer fresh from the SparkFun kegerator.
Mmmm SparkFun Beer

Follow the SparkFunKeg on Twitter

A Need


When I was first given the duty of making sure the SparkFun kegerator had beer for the SparkFun employees I was excited about getting to choose beer for my colleagues. My excitement quickly waned when I got a knock on my door while in the middle of a panelizing session for BatchPCB. The keg was out. It turns out the SparkFun drinking habits vary and the keg never goes out at a convenient time. People never like going to the break room to grab a cold pint of beer only to get the dreaded fweessssssh of an empty keg. I needed a solution. I wanted something that I could monitor remotely that could tell me when the keg was about to run out.

Kegerator leg with force sensor.
The force sensor sits inside the furniture coaster sandwiched between a scrap PCB and the carriage bolt going up to the kegerator

The most well known method of determining the fullness of a keg is to try to pick it up. If you can pick it up and not feel the mass of the liquid swishing around inside, the keg is out. The more difficult it is to lift the keg, the more full it is. This is just not feasible when it's carefully wedged inside the keg fridge and is not the most accurate method around, plus it shakes up the beer. Weighing the keg would work well and four 100 pound force sensors would work for weighing the whole kegerator. I replaced the casters on the kegerator with carriage bolts that rest on the force sensors that rest on leftover PCBs that rest on furniture coasters. Hot glue was added to give some support that was needed for the lateral forces of moving the keg in and out of the kegerator.

Temperature sensor attached to the kegerator door.
The temperature sensor taped to the inside of the kegerator door

What other useful information would be useful for the keg? Temperature would be great, no need to go get a beer if it was warm for some reason, and would also give some indication of a problem. The Lily Pad Temperature Sensor was then added to the parts list because it was easy to interface with an analog output and did not require anything but three wires leading from the main unit to the sensor.

Talking to the outside world




The Arduino Ethernet Shield used in the keg monitor

So, I have these five sensors and need a way to read their outputs remotely. I wanted to show some cool things one could do with an Arduino. But how do I remotely access the Arduino variables? Connecting the Arduino over USB to a PC sitting next to the kegerator would be massive overkill and a waste of power. I saw that we carried the Arduino Ethernet Shield and I decided to play around with it to see what it could do.

I started by studying some code from the Arduino Ethernet example sketches and code. I decided to leave out the checking for the "GET" that is sent by a web browser asking to display the page. If the Arduino got anything on port 80 (the common port for HTTP), it output the text for the web page. This made it easy to diagnose problems by telneting the Arduino at port 80 and hitting enter at the prompt. I got the Arduino serving up "Hello World!" web pages and moved on to integrating the sensors.

The keg monitor shield on the Arduino stack.
Top to bottom: the Keg Monitor shield, the Arduino Ethernet shield and the Arduino Duemilanove.

The sensors would need to be somewhat more permanent than wires just sticking into the Ethernet Shield's header. I put together a "Keg Shield" that had six Three Pin Screw Terminals each three pin screw terminal would have a power, ground and analog input that connected to one of the Arduino's analog inputs. Near each terminal, there were empty places for resistors to bias individual analog inputs. This was needed for the force sensors, as they were only two terminal resistive devices. The Keg Shield was designed and sent off through BatchPCB, work could get started on getting the Arduino serving up the analog measurements. Here's what the webpage looks like:

http://www.sparkfun.com/tutorial/kegmonitor/KegPage.jpg

Not too shabby for a 8-bit microcontroller! We would post the live link to the shield, but with all the traffic, we don't want it to go down.

The script below, when called from a computer that has access to the local SparkFun network and an SSH key setup with a remote server would be able to post the keg monitor's web page remotely.

#!/bin/sh
#This script will get a web page and post it to a new site with scp.
#Note: the computer running this must be setup with proper ssh keys
#to access the destination site automatically.
sourcePage=$1
destinationPage=$2

echo Copy: $sourcePage to $destinationPage.

wget $sourcePage -O tempFile
scp tempFile $destinationPage
rm tempFile

Just Add Twitter


One day, I was discussing the Keg Monitor with the IT department, when Prashanta, one of the purchasing people, walked by and suggested I make it update to Twitter. I groaned at the thought of adding more to this project. Yet everyone agreed that we should have a Twitter feed. I jumped on board with the idea and decided it would be fun to see how much stuff we could cram into the little Arduino.

At that time, I was using the Arduino Duemilanove with an ATmega168 instead of the ATmega328 because my distribution of Ubuntu (8.04LTS for AMD 64) had some libraries that needed to be figured out before I could even compile for the ATmega328. Well, adding Twitter to the ATmega168 was rather taxing on its RAM given the amount of strings that had to be handled. I massaged the code as best as I could, I tried to use PROGMEMs and the string library, but to no avail. I could not get the chip to properly work, it would Twitter something unintelligible for a variable that was supposed to represent the fullness of the keg. I gave in, the code for this tutorial needed to be understandable to the common Arduino user and should not be obfuscated because I did not want to upgrade my computer's AVR libraries and compiler. With the help of Google and some luck, I was able to get the ATmega328 compiling and running. You can follow the Twitter feed here.

When to Twitter?


The initial twitter code had the Arduino only twitter every time it was reset. This was nice for debugging or knowing when the power went out, but not really twittering. I added a Reed Switch and some Magnets to sense the pulling of the tap handle. To the code, I added the ability to read from and increment the value of a location in the ATmega's EEPROM. Now, every time the tap handle is pulled, the Arduino twitters and increments a count that will not be erased when the power goes out.
The tap switch schematic.
The schematic for the reed-based tap switch

The reed switch for sensing the presence of the tap handle.
The long blue-green piece of glass is the reed switch which closes when a magnetic field is near by.

The back of the tap handle with the magnets.
When the tap is in the closed position, the group of magnets creates a large enough magnetic field to close the reed switch.

The tap handle pulled and lighting the LEDs. The tap handle not pulled and not lighting the LEDs.
When the tap handle is pulled the reed switch opens, the LEDs are lit and the Arduino twitters its status.

The Gritty Part: Code


The code for this project can be found here and is released as beerware.

I have done my best to attempt to comment the code as best as possible, so below are some parts that are good to see without downloading a zip file.

One of the first things you will notice when you look at the code is:
#include "password.h"
password.h was created so that you do not have to have your Twitter passphrase in your main code. That way you can share your .pde file but not the password.h file. To generate the passphrase, go here and enter your twitter username and password like this:
username:password
Don't trust this site? You can use GNU coreutils' base64 command the same way.

The next thing you will see is:
//Comment out the following line if the device is using a test network configuration
//#define LIVE_NETWORK_CONFIG

This was setup so that I could use multiple Arduino and ethernet shield pairs, just switching out the Arduinos. When the #define line is commented out, the Arduino is using settings for working at my desk. When the line is not commented out, the Arduino uses the live settings. This was useful once I got the code to the point that people could see the monitor's web page and I did not want to discourage them or answer questions when it was not working. If you only have one shield, then you can, but don't have to, get rid of the code that corresponds to the #ifdef and #ifndef of the LIVE_NETWORK_CONFIG definition.

In the line:
byte aryTwitterAddress[] = { 168, 143, 162, 100 };
We make an array that corresponds to the IP address of www.twitter.com. We will use this to send updates to Twitter.

You will notice in these lines that I do not check to see if a valid HTTP GET command was sent.
  //...
  //Get a client
  Client objClient = objServer.available();


  //If there is a cleint connecting, then send the web page
  if (true == objClient)
  {

    //Send the header information
    objServer.println("HTTP/1.0 200 OK");
    objServer.println("Server: arduino");
    objServer.println("Cache-Control: no-store, no-cache");
    objServer.println("Pragma: no-cache\nConnection: close");
    objServer.println("Content-Type: text/html\n");

   //...

We assume that anything connecting to the Arduino is wanting a web page and that is what they are going to get. The five lines starting with "objServer.println" send the HTTP header file information to the assumed web browser. If one were to check for a proper GET, it would be before these five lines.

The twitter code is pretty straight forward. I needed to use the String library to form the Twitter status that was then passed to function Twitter where it was formed it into the tweet. These three sites were very helpful in getting the Arduino to twitter:
http://pratham.name/post/39551949/twitter-php-script-without-curl
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234028200/1
http://www.mats-vanselow.de/2009/02/08/arduino-lernt-twittern/

Eventually, it became apparent that we would need more than 8 bits to store the pull count in the EEPROM. According to this page, we would overflow an 8 bit counter early into the third keg. There were many ways to store the data, but this way was the easiest and actually worked. When the count is incremented, the EEPROM is read four bytes at a time and pieced together to make a 32 bit number, incremented, broken into individual bytes that are then written back into the EEPROM. The EEPROM will cease to properly write before this counter overflows.

Things to do


The values read from the weight sensors are quite a bit off. This is probably caused by a number of factors such as worn out sensors, the hot glue transmitting too much force around the sensors, the sensors not being directly under the kegerator legs and that the values read from the sensors are not linearly related to the force through the sensors.

The sensors had originally been underneath the keg legs without anything keeping the stack together when a shearing force was applied such as when a full keg is loaded into the kegerator. This allowed the kegerator legs to slide around or off of the force sensors. The force sensors were not changed out when we fixed this problem.

We may have created more of a problem by filling up the furniture coaster cups with hot glue to keep the sensor stack from sliding around. This additional hot glue may be transmitting too much force around the force sensor on each stack and would vary from stack to stack.

The final issue is a known issue with the way the force sensor is read. The resistance of the force sensor is linearly related to the force through the sensor. However the force sensor makes up one half of a voltage divider circuit that creates a voltage readable by the Arduino's ADC. Due to the nature of the voltage divider:

Vout = 5V x R1 / (Rforce + R1)

We will not have a linear relationship between Vout and Rforce. This further complicates things when we just add the voltage measurements together to get a total force reading. We can fix this one of two ways, change the math in the Arduino or we can change the circuit we use to relate the force sensor's resistance to a voltage.

Conclusion


Thanks goes out to Brennen in IT for the assistance with webpages and IP help. This was my final project at SparkFun, and I hope I have left a meaningful and maintainable contribution with this project. I wish you all the best in your lives' journeys.

Back to Tutorials

 

Comments

12 comments


Log in to post comments.

billbristol's rank:
+1.2
|   September 10, 2009 at 12:03 AM
Comment rating:
0
amazing.....just amazing, i must have
by
ScottS's rank:
+6.8
|   September 10, 2009 at 12:22 AM
Comment rating:
0
i like what you guys have done here. i use a custom built out freezer with a johnson controls thermostat on it, but i want to get a one wire temp sensor and some relays to control it instead. having that plus what you guys have done would be freakin' awesome.
by
ScottS's rank:
+6.8
|   September 10, 2009 at 12:23 AM
Comment rating:
0
also you could have the arduino just post updates to a webapp which could graph the data, instead of hosting the webserver on the arduino.
by Nate is a SparkFun employee
|   September 10, 2009 at 1:00 PM
The Arduino is arguably posting to a webserver - twitter in this case. I get what you're saying though. Posting to a mySQL box would allow us to do all sorts of neat graphing, but for our purposes, we need simple updates.
by
mik3y's rank:
+6.6
|   September 10, 2009 at 1:22 PM
Comment rating:
0
Nice job, guys! I love the use of non-invasive force sensors. Maybe your keg and mine can be twitter-buddies? :-)

http://twitter.com/kegbot

Arudino (and SparkFun) powered, to boot :) All drinks are logged to a database, and authentication/access control is supported.

I'm still working on improving the documentation, but if you are interested, you can find an overview of the firmware below. It supports reading from two flow meters, as well as DS18B20 temperature sensors.

http://kegbot.org/docs/kegboard-guide/index.html

cheers,
mike
by
Phelps's rank:
+1.6
|   September 10, 2009 at 10:53 PM
Comment rating:
0
How about a spring and a linear pot instead of a force sensor? If all you are looking for is a percentage, you really don't need it down to the ounce.
chansuke's rank:
+1.4
|   September 13, 2009 at 2:22 PM
Comment rating:
0
What about putting the pressure sensors in between pieces of particle board?

You could sandwich them in between two pieces, with the kegerator itself sitting on the top piece, and the bottom piece on the floor. This would give a more accurate reading I think.
by
mattd's rank:
+1
|   November 25, 2009 at 7:47 PM
Comment rating:
0
Awesome! Especially for in an office.

chansuke: What about putting the pressure sensors in between pieces of particle board?

I was thinking about this too, although particle board might be a bit soft/flexible. I was thinking some perspex or simular discs inside the fridge as I would need to measure up to 2 kegs and a CO2 bottle. All to be displayed on a 20x4 LCD with temp, beer names and % left, and CO2 % left. Next project idea - an autonomous vehicle to deliver a beer to any location in the office?
by
Ryan's rank:
+1.4
|   September 16, 2009 at 7:30 AM
Comment rating:
0
Have you thought about “Pinging” your keg to check the contents? I own a gas grill that has a neat idea for checking the gas left in the tank. The tank sits on an ultrasonic transducer that pings the tank and then derives the amount of the contents from the return pulse. It also gives a very (surprisingly) accurate estimation of how much “burn” time is left at the current rate of consumption. I don’t imagine they have a powerful processor in there for what I paid for the grill. I just know the manual says there has to be a tight mechanical fit between the tank and the sensor for it to work right, but the tank just simply sits on the sensor, nothing fancy. I would imagine that the tank offers a different resonance depending on the level of fuel in it, and being that is LP or liquid petroleum, the same idea would work for beer. I suggest someone with access to an ultrasonic sensor (maybe one of the maxbotix models) with a proportional output give it a try. I’d do a little averaging of the return data to get rid of any spurious errors. Just in case
pmgeahan's rank:
+1.2
|   October  2, 2009 at 2:39 PM
Comment rating:
0
I am in the process of trying to do exactly this...can you post circuit diagrams or pictures of your setup? I'm working on the Flexiforce part of this and would love to see exactly how yours was set up.
Austin908tr's rank:
+1
|   February  2, 2010 at 10:10 PM
Comment rating:
0
is this hard to do. Would a beginner be able to do this?
e12pilot's rank:
+1.1
|   February  3, 2010 at 3:08 PM
Comment rating:
0
I just finished my own version of this, check it out here:

http://keg.maager.com

It uses the reed switch to calculate the volume left in the keg. It isn't 100% accurate, but is less expensive than ~$100 in flexiforce sensors :-)

Thanks for the inspiration guys!

Feedback

What's on your mind?

Please include your email address if you'd like us to respond to a specific question.

submit


If you would like to tell us more, you can fill out our form if you need some psycho-suggestive questions. Go to the form.