Tag Archives: Arduino

A Design for a Remote Fuel Oil Gauge III

My previous post on this subject dealt with the fuel oil level sender unit which sits atop the fuel oil tank in the garage. It has a look only its creator could love. On the other hand, the receiver unit needs to reside in the kitchen, so it has to be, at worst, presentable, and at best, a work of art.

The result is something in-between.

I wanted my receiver box to have an art deco-retro look, something like this or this. Most commercially-available project boxes are utilitarian in design. They lack the curves and finish of early 20th century North American manufactured goods (to say the least), so I designed my own.

I was constrained by lack of access to a complete range of wood- and metal-working machinery, so compromises had to be made. I decided to build the box out of medium density fibreboard, sandwiching together several layers to build depth. MDF is relatively easy to work, although it’s not a good idea to breathe in the dust.

One other aspect of the look relates to my fascination as a child with gas stations and large signs. I remember visiting my grandparents in Wakefield, MA in the middle of the summer; late at night I could part the sheer curtains in the second floor bedroom and look through the trees at a large neon “Pegasus” Mobil Oil gas station sign. I remember being rather disappointed several years later, not being able to see the sign and realizing that it had been replaced by a more modern fluorescent sign that didn’t blink on and off. So I wanted to have the pegasus represented somewhere in my design.

My design uses 5 layers of MDF, with thicknesses ranging from 1/8″ to 1/2″. The different layers needed to be cut differently to accommodate the electronics, which included the SMCC-547 stepper motor and an Arduino controller.

When I designed the box, I used Cinema4D to work out how the parts would all fit together in 3D. I also used Adobe Illustrator to work out the measurements. Once I had the plan I gave it to my son Daniel, a NSCAD sculpture major, to cut the MDF and clear acrylic. Unfortunately there was a misunderstanding regarding dimensions. I won’t go there, except to say that even NASA has made this mistake.

It took some time to mitigate the effects of the misunderstanding, but in the end the result is satisfactory.

Electronics Hardware: The Receiver

Oil Level Receiver
Internal view: Oil level receiver

The receiver has an Arduino brain and uses an On Shine RX A27 receiver (the pair of the transmitter in the sender unit). The received code is received by a Holtek HT12D decoder which passes along three bits of data to D6-D8 of the Arduino chip. My original design used an Arduino Mini Pro, but instead I installed the Arduino bootloader onto a virgin ATMEGA8 chip and set the fuses to run with the internal oscillator at 8 MHz. This was a much more economical choice than using the Mini Pro: $5 versus $30. The Mini Pro runs at 16 MHz and has 16kb of program storage while my minimal ATMEGA8 runs at around 8 MHz and has barely 7kb of program storage, but since I did not need the speed and the firmware fit easily into the 7k space, the ATMEGA8 was completely adequate.

Circuit for the receiver
The receiver circuit

The Arduino receives the 3-bit information from the decoder and uses D10-D13 to drive the SMCC-547 stepper motor module. In addition, the Arduino’s D2 pin is configured as an input from an hall effect position sensor: at power-up, the initialization routine in the software rotates the pointer counter clockwise. The pointer has a tiny magnet on its underside and when it approaches the sensor which is mounted on the motor, the rotation stops, effectively ‘zeroing-out’ and initializing the pointer position.

 

The Software

The actual work is accomplished by two routines: rotateRight() and rotateLeft(): The level of the oil tank is expressed as a three-bit binary number (binary 000-111 or decimal 0-7). The current level is compared to the previous level. If the current level is higher than the previous one, rotateRight() is invoked, which moves the pointer higher. If the current level is lower than the previous one, rotateLeft() is invoked which moves the pointer down.

A function called getLevel() converts the binary coded data into decimal.

As mentioned above, on power-up, the last state of the pointer is unknown, so the pointer is set to the zero point on the gauge. Once this is done, the main loop can commence.

/*
Stepper Motor SMCC-547 for Oil Tank Level Indicator v. 1.0

 by Michael LeBlanc
 NSCAD University
 mleblanc@nscad.ca

 It receives a binary value from 0 - 7 and moves the pointer
 accordingly.

 March 30, 2010
 */

/*
**************** N O T E **************************************
 This unit does not work with the stepper.h library.
 It works by setting one pin high and the others low.
 To rotate clockwise, set inputs high in order A-B-C-D,
 and D-C-B-A rotates counterclockwise.
 ***************************************************************
 */

int activePin = 1; // which of the 4 pins to the motor is high
int outputPin[5] = {
 0,10,11,12,13};  // stepper motor pins
int level;  // the current level of the oil tank
int oldLevel; // the previous reading of the level
int motordelay = 10; //standard stepper motor delay

void setup()
{
 pinMode(10, OUTPUT); // to A input on motor
 pinMode(11, OUTPUT); // to B input on motor
 pinMode(12, OUTPUT); // to C input on motor
 pinMode(13, OUTPUT); // to D input on motor
 pinMode(6, INPUT); // 1's digit of oil level
 pinMode(7, INPUT); // 2's digit of oil level
 pinMode(8, INPUT); // 4's digit of oil level
 pinMode(9, INPUT); // 8's digit of oil level (not required)
 pinMode(2, INPUT); // position sensor

 // step the pointer two to the right
 rotateRight();
 delay(motordelay);
 rotateRight();
 delay(motordelay);
}

void rotateLeft()  // rotate counterclockwise routine
{
 if (activePin == 4)
 {
 activePin = 1;
 digitalWrite(outputPin[4], LOW);
 digitalWrite(outputPin[1], HIGH);
 }
 else
 {
 digitalWrite(outputPin[activePin], LOW);
 activePin = activePin + 1;
 digitalWrite(outputPin[activePin], HIGH);
 }
}

void rotateRight()   // rotate clockwise routine
{
 if (activePin == 1)
 {
 activePin = 4;
 digitalWrite(outputPin[1], LOW);
 digitalWrite(outputPin[4], HIGH);
 }
 else
 {
 digitalWrite(outputPin[activePin], LOW);
 activePin = activePin - 1;
 digitalWrite(outputPin[activePin], HIGH);
 }
} // end rotateRight routine

int getLevel()
{
 int L0 = digitalRead(6); // read 1's digit of level
 int L1 = (digitalRead(7)*2); // read 2's digit of level
 int L2 = (digitalRead(8)*4); // read 4's digit of level
 level = ( L0 + L1 + L2 ); // convert to decimal
}

void loop()
{
 // initialization routine to set pointer to zero //

 if (digitalRead(2) == LOW)
 {
 //digitalWrite(3, LOW); // for debugging
 while (digitalRead(2) == LOW)
 {
 rotateLeft();
 delay(motordelay);
 }
 //digitalWrite(3, HIGH); // for debugging
 }
 else
 // set the pointer to the level //
 {
 getLevel();
 for (int i=1; i<=level; i++)
 {
 rotateRight();
 delay(motordelay);
 }
 oldLevel = level; // set oldLevel to equal current level

 /*-----------------------------------------------
 now manage incremental changes up or down //
 --------------------------------------------*/

 for (int looop=0; ; looop++)  // endless loop
 {

 getLevel();
 //Serial.print("Old Level: ");
 //Serial.print(oldLevel);
 //Serial.print(" Level: ");
 //Serial.print(level);
 //Serial.println(" ");

 if (oldLevel == level) // if there is no change, do nothing
 {
 delay(motordelay);
 }
 else if (oldLevel > level) // if level goes down, rotate left
 {
 rotateLeft();
 //Serial.println("rotate left");
 oldLevel = oldLevel - 1;
 delay(motordelay);
 }
 else
 {
 rotateRight();  // level has gone up; rotate right
 //Serial.println("rotate right");
 oldLevel = oldLevel + 1;
 delay(motordelay);
 }
 }
 }
}

Creative Commons License
Remote Fuel Oil Tank Gauge by Michael B LeBlanc is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 Canada License.
Contact the writer for permissions beyond the scope of this license.

A Design for a Remotely Readable Fuel Oil Tank Gauge

Last summer when I unpacked my electronics hardware (after 25 years) and began to learn about the Arduino microcontroller, I started on a project that would help be pick up where I had left off. I chose to tackle the problem of remotely reading the level in our residential fuel oil tank.

In Atlantic Canada, residential heating is limited to electricity and fuel oil. Our tank is in the garage, in the far corner from the household access door on the lowest level of our four-level backsplit home. In other words, it’s an inconvenience to determine the level of oil in the tank. This might be a non-issue except for the fact that we are not on a more expensive fuel plan where the company regularly tops off the level. If I don’t keep an eye on it, we’ll run dry. It hasn’t happened–yet.

I did some initial research to get a sense of what was already out there. Google Patents had many filings that were interesting, such as “Residential fuel tank oil level” “Remotely readable fuel tank indicator system” and “Hall-cell liquid level detector“.

One design limitation that I had imposed from the beginning was that I did not want to change anything on the tank itself. The level detector had to be completely passive and unconnected in any way from the tank itself. My reasons were twofold:

  1. I did not want to change the status of my house insurance by affixing a non-standard item to the oil tank
  2. I wanted to be able to easily disconnect the hardware from the oil tank for maintenance of the unit

The above-mentioned patents were interesting to me because they used hall-effect sensors. Used as proximity switches, these devices can detect the change of a magnetic field without being mechanically coupled to the item being sensed. They are very inexpensive and solid state, so they are very dependable and have a practically infinite service life.

There is a commercial product available which already does some of what I was looking for. Syba Systems in Connecticut markets several devices such as the “LED at a Glance” which fits over top of the mechanical tank level guage and shows the level using an array of LEDs. “Oil Alert” is similar except that when a low oil level is detected, the unit beeps.

One last example of ‘prior art’ is Tom Laureanno’s “Oil Level Indicator Project/Idea” where he describes placing a magnet on top of the mechanical level, and effecting a change of state of a reed switch.

The Remote Oil Fuel Level Gauge
The Remote Oil Fuel Level Gauge

Reed switches are mechanical devices, and they tend to be rather large. Rather than actuate just one switch (resulting in an ‘idiot light‘ scenario, I want to get a sense of the level in several stages, which means that I would need several sensors along the length of the float level. I would be able to watch over time the level go down as we use the oil in the tank.

So this is my idea: To build an array of hall-effect sensors and affix them to the outside of the mechanical float level.

  1. On the float level, a small rare-earth magnet is glued to the float indicator.
  2. As the float indicator rises or falls, the magnet field changes are sensed by the hall-effect sensors.
  3. These sensors are read and interpreted by the Arduino, which transmits the float level information by radio to a receiver elsewhere in the house.
  4. The received information is decoded and another Arduino microcontroller drives an indicator, which in the case of my first prototype, a stepper motor, but it could also be an LED array or an LCD display.

In subsequent posts I’ll outline the design and implementation of the system.


Creative Commons License
Remote Fuel Oil Tank Gauge by Michael B LeBlanc is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 Canada License.
Contact the writer for permissions beyond the scope of this license.

Seeed Studio Visit – Shenzhen, China

(Wuhan, China) On Monday I visited Seeed Studio, a small but growing tech startup in Shenzhen. They specialize in open source hardware, and are known for the Seeeduino, an Arduino microcontroller board. Seeed makes open source “brick” addons that allow sensor and actuator connections to the Seeeduino without soldering and they provide economical starter kits that are perfect for our students at NSCAD University.

They generously provided me with a sample Seeduino, and two kits: the “Electronic Brick Starter Pack” and the “Catalyst” kit that they have prepared for Make magazine for my lecture at Shenzhen Polytechnic that afternoon. I’ve used their bricks before and find them very convenient for learning how to use the various sensors, motors, LEDs and other actuators, though I have to admit that I broke a light sensor early on when I plugged it into the brick the wrong way around. Apart from that silly mistake, the brick system is robust and well-designed.

Two of the principals, young engineers Eric and Fan, were my hosts. They showed me a beta version of their soon-to-be-released DSO nano, a small handheld digital storage oscilloscope for people like me. It looks like an iPod Touch, but with a button rose at the right. They tell me that they would like to use a complete ‘glass interface’ like the iPod with their next version of the product.

Eric brought out a development prototype of their Rainbowduino called the 3D RGB Cube, a 3D matrix of RGB LEDs that connect smartly to the Seeeduino. With this system there are no worries about current requirements, all you need to do is plug it into the microcontroller and ensure that you give it enough juice.

Now, off to Beijing!