Home Heating Oil Tank Level Transmitter to Xively

Hello All!!

Just joined the forums to share my weekend project.

I have only a few weeks into Arduino programming. No other programming experience with any other language. But I did happen to pull this off in only a short amount of time.

The project uses:

  • Arduino Uno
  • Ethernet Module
  • Ultrasonic Sensor Module HC-SR04
  • DHT22 (Optional)
  • 2''NPT to 2" Pipe Adapter (McMaster-Carr)
  • Piece of Plexiglass
  • Hot Glue Gun
  • Misc. Tools

Instead of paying 80-200 dollars for a level transmitter made for specifically for heating tanks, I decided to make my own.

From the pictures below, you can see how I made it. It is Revision #1 and there are some finishing touches that need to be done before I consider in complete. For starters:

  • Add a cap over the top to keep it clean
  • Add a quick disconnect to the lid and solder the wires directly to the pcb of the Ultrasonic
  • Fill the cup with a layer of hot glue just high enough to cover the pcb. Even with hot glue around the sender/reciever, they tend to leak a little bit of air and you can actually smell the fuel oil fumes when you stand close

Of course leaving the breadboard and Arduino aren't the permanent solution. I will be running a cable from the quick disconnect over to where the Arduino is to be permanently mounted.









Code Used:

/*Arduino Humidity + Xively Feed*/

//Declare headers
#include <SPI.h>
#include <Wire.h>
#include <dht.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

//Set log period
#define LOG_PERIOD 15000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch
#define DHT22_PIN 3       //DI pin with sensor data
#define trigPin 6
#define echoPin 7

dht DHT;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0A};  //Assign MAC if one was not assigned to shield
char xivelyKey[] = "API_KEY_HERE";

char sensor0Id[] = "Temperature";
char sensor1Id[] = "Humidity";
char sensor2Id[] = "Oil_Level";

XivelyDatastream datastreams[] = {
    XivelyDatastream(sensor0Id, strlen(sensor0Id), DATASTREAM_FLOAT),
    XivelyDatastream(sensor1Id, strlen(sensor1Id), DATASTREAM_FLOAT),
    XivelyDatastream(sensor2Id, strlen(sensor2Id), DATASTREAM_FLOAT)
};

XivelyFeed feed(FEED_ID_HERE, datastreams, 3);  

EthernetClient client;
XivelyClient xivelyclient(client);

//Variable declaration
int Humidity;        //variable for humidity value
int Temperature;    //variable for temperature value, sensor output in Celsius
int OilLevel;
unsigned long previousMillis;  //variable for time measurement

void setup(){
  Ethernet.begin(mac);
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop(){                                 //main cycle

//--------------Begin DHT22 loop--------------//
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis > LOG_PERIOD){
    previousMillis = currentMillis;
    int chk = DHT.read22(DHT22_PIN); //Change for DHT type
    Humidity = DHT.humidity;
    Temperature = ((DHT.temperature*9)/5)+32;
    
    datastreams[0].setFloat(Temperature);
    datastreams[1].setFloat(Humidity);
    int ret = xivelyclient.put(feed, xivelyKey);
  }
//---------------End DHT22 loop--------------//

//------------Begin Ultrasonic loop---------//
//Code for Ultrasonic  
  int duration, distance, X;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  X = ((duration/2) / 29.1) / 0.40727272; // Divide by 0.40727272 becasue 0-44" (tank height) equals
                                          // 0-112cm (inches to CM). 112 CM divided by 275 Gallons. 
  
  if(X >= 275)
   {X = 275;}          //Filtering
  
  if(X<=275)           //Inversing of the distance for Liquid Level Measure
   {OilLevel=275-X;}
  
   
  datastreams[2].setFloat(OilLevel);
    int ret = xivelyclient.put(feed, xivelyKey);
//------------Begin Ultrasonic loop---------//

    
//---------------Debugging-----------------//
 Serial.println(OilLevel);
    delay(10000);
}

Let me know if there is anything I can do to clean up my code. I am having a problem with serial monitoring. It doesn't work very well. Not sure what the problem may be.

Any insight/recommendation/improvements, let me know!!

Thanks guys!!
-Dave

I saw your post highlighted on freetronics blog and just had to share my project because it is so similar. My tank is outside so I have the additional difficulty of keeping things watertight. I have the sensor in a PVC cap on the tank quite similar to yours and the arduino is inside with CAT5 connecting it. From there, it communicates over wireless serial using an X-Bee to a computer where it is logged to a database. I have thought about trying xively, but I haven't gotten around to making improvements to my setup since getting it started. My blog post on this project is here: Home Heating Hacking Part 1 or How to Measure an Oil Tank | alaskanshade

I do get a number of bad readings (essentially reporting the tank as full) from time to time and I am curious if you have any similar issues. I have algorithms in place to clean some of it out and I can manually ignore obvious outliers. My issues might be due to the tank being outside in a rather humid environment.

How about swapping them out for pressure transmitters on the discharge line as long as your port is on the bottom of your tank.

You could also try an air pressure sensor spun on the end of a piece of pipe and stick it down into the tank. As long as no air escapes and the pipe end does not become exposed, the pressure acting on the sensor should be the same as the head pressure of the fluid.

Alaskanshade:
I saw your post highlighted on freetronics blog

That's pretty kool. Thanks for letting me know.

Ya know the other thing to. If you only have one tank.
Use a pressure transmitter "T'd" into the oil line. But do it inside before your burner. That way you could move all your gear inside.

I have thought about other methods, but each seems to have it's negatives. I think I might also get odd ultrasonic echos. I have a Maxbotix sensor with a super narrow beam, but I don't think I can get quite the same accuracy out of it. After getting this running, I have hooked up sensors on my boiler to detect when each heat zone is on (detailed in another blog post). I figure if I can determine how much time it is actually burning and the rate it burns, I can measure that instead. This part is all connected to a raspberry pi with a web interface but still need to find time to tinker with it some more.

Alaskan,

If you do end up wanting to post online to a server go with Thingspeak instead of Xively. I have been playing around with Thingspeak the last couple days and I think I am going to change over. A ton of more options for your graphs. Plus easy exporting of your data directly to an excel spreadsheet.

I'll update my above code after I get It transferred to Thingspeak.

I'll keep that in mind for when I get back to tinkering with this project.