Introduction: STEAMPUNK STEAM GAUGE, POWERED BY ARDUINO

This was created to be some eye-candy for my kitchen. I wanted something unique for a special blank space on my wall, and adding movement, blinky lights and interesting mechanical “guts” made it even better.
Ultimately, this project ended up requiring the following range of skills:
1. Basic mechanical skills
2. Light metalworking and fabrication
3. Graphic design – for the new dial face
4. Circuit design
5. Arduino programming
6. Woodworking- for mockups and decoration
7. Drywall and 120V wiring – for mounting and permanent power supply

Step 1: Video

HERE IT IS IN ACTION.

Step 2: IN THE BEGINNING: a FIRST LOOK INSIDE

This project started with a beat-up Ashcroft 10" pressure gauge bought cheap on ebay. The glass dial cover was cracked and the valve was frozen, but that didn't matter. The main priority was size, because ideally I would want to add stuff inside it. If the mechanical guts of the instrument were "interesting" enough, then I would also want to make those visible as well.


Fortunately, the three screws holding the brass outer ring were not frozen or stripped. The pointer came off with just a little persuasion, as it was simply press-fit onto the shaft. The faceplate was also held in with three screws, all of which came out as well. The insides had the standard "C" shaped Bourdon tube, which flexes open under pressure. The mechanism was in good shape overall, but it would need some cleaning up and polishing. So far so good....

Step 3: THE BASIC MECHANISM

A closer look at the mechanism.

Step 4: THE CHALLENGE OF MOTION - Part 1

It could have been a static decoration, but if at all possible I wanted it to be dynamic, but I had to overcome some issues first………
Without steam pressure to create flex, the Bourdon tube is essentially a stiff "C" shaped spring. While it can be flexed open by hand, and thereby creating the desired dial pointer movement, the force necessary to do so is not insignificant. Adding to the challenge, the space available inside the gauge for mounting some type of actuator is limited. I was able to determine that a continuous rotation servo would fit in the space between the Bourdon tube and case. This shows the servo’s final mounting configuration. Details on how and why exactly that spot are in later steps, but suffice to say that there was just enough room to make it work.


** SEE STEP 12 FOR A VIDEO OF THE COMPLETED MECHANISM IN ACTION**

Step 5: THE CHALLENGE OF MOTION - Part 2

The servo was not strong enough to flex the Bourdon tube through a direct mechanical link, but I eventually found a way around this problem. After much experimentation, I managed to fashion a suitable lever assembly that was strong enough to flex the Bourdon tube by amplifying the relatively meager strength of the servo.

The important parts of the unit are:

1. BRASS BASEPLATE

Fashioned from brass sheet. It is bolted to the inside back of the gauge with machine screws. The two gear shafts are solidly attached to the baseplate, and were positioned to allow the gears to engage.

2. GEARS

The gears are mostly there for show, even though they do mesh and rotate on their shafts. Since I wanted to make the mechanism visible, they simply serve as more shiny moving parts.
The larger gear does have one important mechanical role: in addition to the outer ring, it also has a smaller diameter ring (see second photo) that elevates the pivot of the long lever to just the right position (4).

3. FLEX LINKAGE

This links the long lever (4) to the Bourdon tube. The notch in the end of the linkage fits the curved end of the Bourdon tube. Its position close to the pivot of the long lever gives it enough leverage to flex the Bourdon tube the proper amount.

4. LONG LEVER

This is another brass piece I shaped out of an even larger piece for this purpose. The pivot end is epoxied to the inner gear of the large gear. The flex linkage is connected to the long lever through a bolt secured to a tab of brass attached to the long lever. The end of the lever has a notch filed in it to catch a loop of fishing line, which is used to pull on the lever.

SECOND IMAGE

This shows the long lever by itself.  Under the pivot end of the long lever you can see the glob of clear epoxy used to attach the long lever to the small diameter raised gear. The tab of brass was attached to the long lever with gray epoxy putty, reinforced with two shortened nails inserted through holes drilled through the long lever and tab (the two nail heads are just visible). After the epoxy putty hardened, most of it was ground off, leaving just enough to make a flat, smooth surface and keep it all together. The short bolt the flex linkage pivots on was then attached with a nut to a hole in the tab.

WHERE DID ALL THOSE EXTRA BRASS PIECES COME FROM?
The brass back plate was cut and filed into shape from brass stock from a local hobby shop. The circular polishing was done with a polishing wheel and polishing compound and a drill press. The gears and shafts came from a grandfather clock movement purchased through ebay, just for the purpose of scavenging interesting parts from it. The long lever was another piece from the clock movement that was cut down into the right shape. The brass flex linkage tab was also shaped from brass stock. The gear shafts were attached to the brass back plate by drilling holes in the back plate and extending the shafts 1/8th inch through the back plate and securing them in place with a glob of epoxy putty.

Step 6: THE CHALLENGE OF MOTION - Part 3

This shows the lever assembly installed in among the original mechanism. The arrow points to the notch end of the flex linkage engaging the end of the Bourdon tube. The white block is a mock-up of a limit-switch.

Step 7: THE CHALLENGE OF MOTION - Part 4

This picture of the servo used shows how I was able to get as much leverage out of the servo as possible. By winding some fishing line around the shaft of the bellcrank (arrow) it became a winch that was strong enough to pull the long lever and flex the Bourdon tube open.

Step 8: THE CHALLENGE OF MOTION - Part 5

This shows the lever assembly rigged to the servo.

The important parts are:

1. THE SERVO

The horns of the bellcrank were cut down to allow it to rotate in that position (If the servo was mounted upright, there would not have been enough clearance to put the dial face back in). The position of the servo was dictated by necessity; after fitting all the switches and other mechanical assemblies into the gauge, the size and dimensions of the servo made it impractical to attach it anywhere else.

2. LINE REDIRECTION ROLLER

This lets the fishing line pull the long lever from the most effective angle. The single roller was later replaced with a double roller configuration.

3. UPPER LIMIT SWITCH

A simple button switch that triggers at the upper limit of travel (the wire leads are not attached in this photo).

4. LOWER LIMIT SWITCH

This is a lever action switch signaling the lower limit of travel. At this point, the long lever does not have enough spring force behind it to reliably trigger a button switch. A lever action switch requires much less force to engage.

Step 9: ELECTRONICS - Part 1: Overview

All the electronic components were ultimately connected to an Arduino Uno, which was housed in a plastic enclosure, along with a solder board. The enclosure was attached to the outside back of the steam gauge with Velcro, and all the internal components had their wires terminate in multi-pin connectors which mated to female connections soldered to the circuit board.  All the wiring ran through a hole in the back of the steam gauge.

** NOTE: The circuit diagram does not show the circuit board or connectors!
** NOTE: The "circuit board" is a plug-in breadboard in some pictures. The wiring harness and connections went through MANY variations on it way to a final configuration!

Step 10: ELECTRONICS - Part 2: Arduino Code

This is the arduino sketch that runs everything.

The Arduino sketch generates random movement by having the servo rotate for various lengths of time. The sketch is never ending; it will run until power is shut off to the Arduino.

#include < Servo .h>

Servo  myservo;   // create servo object to control a servo 
int  led1 = 4;    // assign led to pin 4
int  led2 = 5;    // assign led to pin 5
int  led3 = 6;    // assign led to pin 6
int  pos =95;      //initial speed and direction when Arduino starts
int  timer = 0;
int  pause = 100;    //initial pause interval, in milliseconds
int  stoptime = 100;
int  randpause = 100;
int  randspeed = 100;
int  bbuttonState = 0;
int  tbuttonState = 0;
int  hi;
int  lo;
const   int  bottomButton = 2;
const   int  topButton = 1;

void  setup ()
{
myservo. attach (3);     // assign servo control wire to pin 3

pinMode (led1,  OUTPUT );    // pin supplies power to LED 1
pinMode (led2,  OUTPUT );    // pin supplies power to LED 2
pinMode (led3,  OUTPUT );     //pin supplies power to LED 3

pinMode (topButton,  INPUT );    // listen for signal from button
pinMode (bottomButton,  INPUT );   //listen for signal from button
}

void loop ()
{                       // start main loop
    myservo. write (pos);  // set servo speed/direction to the value of pos variable
    tbuttonState =  digitalRead (topButton);  // read the state of the top button
    bbuttonState =  digitalRead (bottomButton);  // read the state of the bottom button
     if  (bbuttonState ==  HIGH )  // if top button pressed
        {newParameters(85, 93);}  //calculate a speed in other direction
     if  (tbuttonState ==  HIGH )  // if bottom buttom pressed
        {newParameters(96, 103);}  //calculate a speed in other direction           
    timer +=10;  // increment timer value by 10
     if  (timer >= stoptime)    //if run time limit is reached,
        {
         myservo. write (95);   //stop servo
         newParameters(80, 105);  //compute new parameters
          delay (randpause);  // pause for a random time
        }
     delay (100);   // pause for 100 milliseconds

if  ( pos < 97)      
   { digitalWrite (led2,  HIGH );}   //power on led2
else 
   { digitalWrite (led2,  LOW ); }    //power off led2


if  ( randpause > 2000)

   { digitalWrite (led3,  HIGH );}
     else  { digitalWrite (led3,  LOW ); }


if  ( timer > 90)

   { digitalWrite (led1,  HIGH );}
     else  { digitalWrite (led1,  LOW ); }

}    // end main loop
void  newParameters( int  hi,  int  lo)   // function to calculate new speed/direction, time and pause
    {
     pos =  random (hi, lo);  //generate new speed/direction, within hi and lo limits
     randpause =  random (1000, 5000);  // generate random pause between 1 and 5 seconds
     pause = 100;
     timer = 0;  //set timer to zero
     stoptime =  random (50, 200);   // generate random time to run servo
    }

Step 11: ELECTRONICS Part 3: Logic Flow and Controlling Components

The Arduino code also went through many variations before it was finished. The flowchart shows the basic logic used to interface the servo, switches and LEDs.



SERVO CONTROL

This uses a stock continuous rotation servo, connected to the Arduino in the following configuration.

**NOTE: The control wire (typically yellow or brown)  can be connected to any Digital Pin, in this situation it is connected to Digital Pin 3.

The top and bottom limit switches are wired in this configuration.

The line “#include <servo.h>” imports the servo library. Continuous rotation servos are connected to the Arduino in the same configuration as standard servos, but the code to control them is slightly different. Standard servos are controlled by supplying an absolute position (e.g. “position = 124”), but continuous rotation servos interpret values of position as speed and direction.  The CR servo was calibrated to interpret 95 as dead stop, with 0 as full speed clockwise and 180 as full speed counter-clockwise. In reality, any value greater than 10 from dead stop in either direction is full speed (i.e., values less than 80 and greater than 100 generally won’t increase the speed of the servo in either direction).
In this sketch, random values for speed and direction are generated in the range of 80-105. This is accomplished in the “newParameters” function (after the main loop).

RANDOMIZING MOVEMENT

In addition to generating a random speed and direction, the code will also generate a random interval to run at that
speed/direction.
The ranges for these randomly generated values are:
Speed/direction: 80 – 105
Pause: 1000 – 5000ms
Run time: .5 - 2.0 seconds, effectively

USING CODE LOOPS AS A TIMER

Arduino code ("sketches") are based on continuously looping instructions (the "void loop()").  In reality, the Arduino will run through the loop almost instantaneously, therefor, a 100 millisecond "delay" command was added at the end of the loop code. This will effectively limit the code to looping approximately 10 times a second.  By incrementing the "timer" value at each pass through the loop, run time can be tracked. With a increment value of 10 and a limit of 50, the code will loop for about half a second. When the max time value is reached, the speed is set to “dead stop” and a pause timer is started. The pause time is another randomly generated value.


LIMIT SWITCHES

The limit switches are connected to Digital Pins 1 & 2. When either limit switch is contacted, the speed/direction value is immediately set to “dead stop”. Then a new set of speed/direction, run time, and pause values is calculated, but the speed/direction range is limited to movement in the opposite direction.

LEDs

The LEDs were wired up based on this configuration. Wiring LEDs is dead simple, the trick is controlling power to  them in the sketch based on a separate event, such as a timer or switch.
The LEDs are embedded in the dial face and are triggered by the values generated for speed/position, pause and run-time.

This code snipped will turn on a LED if the value of randpause is > 2000, else it stays off.

if  ( randpause > 2000)

   { digitalWrite (led3,  HIGH );}
     else  { digitalWrite (led3,  LOW ); }

Step 12: VIDEO: LIMIT SWITCH TEST

To test the basic functionality of the limit switches, I wrote a simple Arduino sketch that simply runs the servo in one direction until it hits a limit switch, which then reverses the direction. It will bounce back and forth this way until I shut off the power. This video also shows all the mechanical pieces working together.

Step 13: DIAL FACE

The original dial face was in OK shape, but not nearly snazzy enough. I also wanted to make the shiny mechanical guts visible, so I was clearly going to have to make my own face. The dial face started out as a piece of acrylic cut to the same shape as the original. Using Paint Shop Pro, I then created this graphic that was printed with a color inkjet printer on heavy matt photo paper.  A rectangular opening was then carefully cut with a very sharp exacto blade. A corresponding opening was cut from the acrylic circle. The four small brass bolts are not just decorative; they also hold the dial face onto the acrylic round. I used small pieces of double-sided Scotch tape anywhere the paper did not lie flat. A piece of balsa wood with three holes drilled in it was hot-glued to the rear of the acrylic, into which the LEDs were also hot-glued. Three small holes were cut in the paper dial face where the LEDs shone through, and the exposed acrylic was colored with a red marker (for the red light). Three brass washers were then carefully glued to the paper face with a small dab of white glue. Another piece of acrylic was cut to replace the cracked glass gauge cover, which sits on the edge of the gauge and is held in place by the outer ring.

ABOUT THE DIAL FACE DESIGN

I used some interesting graphics I found on the web to put on the dial face. UF6 is the chemical formula for Uranium Hexaflouride, an extremely corrosive chemical used in enriching uranium. I also added the logo for the Heinkel Aircraft Company, along with some official looking markings in German that look like serial and model numbers.

Step 14: MOUNTING ON THE WALL

To mount the gauge on the wall, I made a simple mounting ring out of ¼ inch plywood that was sanded and painted with blue Krylon hammered-finish spray paint. The ring was secured to the wall with screws and drywall anchors. I glued three nuts to the ring in holes such that the ring would lie flush with the wall and brass bolts could engage the nuts through the original mounting holes in the gauge. I also had to remove enough drywall to allow for clearance for the Arduino enclosure attached to the back of the gauge. Before mounting the gauge to the ring, the 9V adapter cord was connected to the Arduino. The adapter cord was fed through the wall down to the work box that would hold the power adapter.  A USB cord was also attached to the Arduino USB port and fed through the wall, also terminating at the work box. The USB cord was long enough to hook to a laptop, thereby allowing me to connect to the Arduino without removing it from the wall.

Step 15: DEDICATED POWER

To give the gauge dedicated power, I build an oversized electrical work box out of two standard boxes. The boxes were cut apart with a oscillating saw and reassembled with plastic epoxy. The box was sized to hold a standard electrical socket, but to also recess it enough to attach a 9V adapter and not have the adapter protrude from the plane of the wall. The power was drawn from a nearby electrical socket using standard 14 gauge Romex wiring. The custom box also holds a toggle switch that the 120V power runs through. The objective of this configuration is to connect the power adapter to the Arduino and leave it permanently plugged into the socket and connected to the Arduino, using the toggle switch to power on/off the steam gauge electronics. To make the ugly work box invisible, I attached flat magnets to each side of the box, flush with the edge of the box with epoxy and metal “L” brackets. The box is designed to lay flush with the plane of the wall, and the magnets would hold a metal sign to cover the box.  The box is roomy enough to store the coil of USB cord as well.

Step 16: NOTES AND RESOURCES

The circuit diagram in step 10 was done with FRITZING. Check it out, its very cool, and FREE!

The flow chart was done with Microsoft Visio. Unfortunately, it is not free, but LibreOffice has a close alternative, and its FREE!

Yes I know, the pointer rotates well past 360 degrees. I could have limited it to just between 0 and 100, but that would have been too ordinary, right?

The servo, wires, Arduino, enclosure, multi-pin connectors and switches came from Adafruit.com.

The whole thing took at least 6 months to create.

My next project is a steampunk Arduino powered pay-toilet lock for my guest bathroom