loading

Many industrial processes require chemical analysis of a fluid and sometimes just knowing it's density is all that is necessary to know what it's main constituents are. This is particularly true in whiskey production, for example.

Here, I am using a very accurate pressure sensor which is connected to some elaborate looking copper pipework to measure the weight of a column of fluid of set height. As long as the ambient pressure and fluid temperature does not change, the density of the fluid will be directly proportional to the pressure generated by the column of fluid. Simple?

Step 1: How It Works

The distillate or 'alcohol' from the condenser enters the top chamber of the gadget and pours down a small internal pipe drawn in green. If this pipe were not here, the alcohol would just flow straight out of the overflow and not circulate into the main body of the device and there would be a large error in the readings.

So, once the device is full of liquid, the flow of fresh liquid down the green pipe causes the 'old' liquid to be pushed out so that we are always measuring the fresh stuff.

The small bore sensor tube is attached to a vertical 'anti capillary' tube, which runs parallel to the main pipework and goes to the HSCDRRN005NDAA5 pressure sensor in the control panel which has barbed fittings on it for very small pipes. If the small flexible pipe was connected directly to the bottom of the gadget it would fill up with fluid and not empty properly due to the forces of capillary action keeping it in the pipe. This capillary action is not a problem in a bigger bore pipe and all we see is a meniscus.

Just to make things even more complicated, there's a solenoid valve at the very bottom of the device which can be automatically opened to dump the contents of the device at different stages of the process.

As the process continues, the 'alcohol', which is actually composed of mostly alcohol and water with a few other weird and wonderful liquids in much lower concentrations, becomes weaker and weaker with more and more water and strange oily chemicals called 'fusils'. It's really useful to be able to measure the concentration of the distillate being produced at all stages of the process as we don't want too much water or too many other heavy chemicals as some of these can give us a bad hangover! (But an interesting taste).

Step 2: Parts

  • 1DS18B20 1-Wire Temperature Sensorpart # DS18B201
  • ADS1115 16-bit ADC Breakout1
  • HSCDRRN005NDAA5chip label HSCDRRN005NDAA5; pins 8; true; hole size 1.0mm,0.508mm; package DIP (Dual Inline) [THT]; pin spacing 300mil1
  • Piezo Speaker1
  • LCD screenpins 16; type Character1
  • Arduino Nano (Rev3.0)type Arduino Nano (3.0)1
  • Rotary Potentiometer (Small)maximum resistance 100kΩ; track Linear; type Rotary Shaft Potentiometer; package THT; size Rotary - 9mm1
  • 100Ω Resistor tolerance ±5%; bands 4; package THT; pin spacing 400 mil; resistance
  • 100Ω14.7kΩ Resistor tolerance ±5%; bands 4; package THT; pin spacing 400 mil; resistance
  • 4.7kΩ11kΩ Resistor tolerance ±5%; bands 4; package THT; pin spacing 400 mil; resistance 1kΩ

Step 3: Arduino Setup

As can be seen, the setup features a ADS1115 16-bit ADC, an Arduino Nano and a HSCDRRN005NDAA5 chip. The 16-bit ADC gives better resolution than the normal Arduino 8 bit, particularly as the pressure sensing chip measures both positive and negative pressures.

Step 4: Arduino Code

There's nothing too fancy about the code, except that I've made a custom LCD character for a delta sign and the nano takes 30 readings from the pressure sensor before calculating an average.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_ADS1015.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 12
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress pipeProbe01 = { 0x28, 0x1E, 0x28, 0x08, 0x00, 0x00, 0x80, 0x00  };
float tempC;
float previousTempC =0;
float deltaTempC =0;
Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
// Adafruit_ADS1015 ads;     /* Use this for the 12-bit version */

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
byte delta[8] =
{
  B00000,
  B00100,
  B00100,
  B01010,
  B01010,
  B10001,
  B11111,
  B00000
};
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

long sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int outputValueMin = 1000;
int outputValueMax = -1000;
int i=0;
int c=0;
int x=0;
int z=0;
int y=0;
int tempCount=0;
float av=0;
long totalAdjustedOutputValue=0;
int adjustedOutputValue = 0;
float hrs=1;
void setup() 
{
  lcd.createChar(1, delta);
  lcd.begin(20, 4);
  lcd.setCursor(2,0);  
  lcd.write(1);
    // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  if (!sensors.getAddress(pipeProbe01, 0)) Serial.println("Unable to find address for Device 0"); 
  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(pipeProbe01, 12);
 
  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(pipeProbe01), DEC); 
  Serial.println();
  delay (2000);
  
    pinMode(8, INPUT_PULLUP);   // Momentary switch
    ads.begin();

    
  // initialize serial communications at 9600 bps:
    Serial.begin(9600);
  sensors.requestTemperatures(); // Send the command to get temperatures
  printTemperature(pipeProbe01);
  previousTempC = tempC;
}

void loop() 
{ 
  y=5;
  z=10;
  if (adjustedOutputValue > 1000)
  {
    while (y<z)
    {
    tone (11,200*y,50);
    y++;
    delay(50);
    }
  }

  sensors.requestTemperatures(); // Send the command to get temperatures
  printTemperature(pipeProbe01);
  
  int pushButton = digitalRead(8);
    if (pushButton == HIGH) 
    {
      Serial.print("Switch Off");
    } else
    {
      Serial.print("Switch On");
      x = outputValue;
      outputValueMin = 10000;
      outputValueMax = -10000;
      c = 0;
      totalAdjustedOutputValue =0;
      av=0;
      hrs=0;
    }
      Serial.println(" ");
  int16_t adc0, adc1, adc2, adc3;

 // adc0 = ads.readADC_SingleEnded(0);
 // Serial.print("AIN0: "); Serial.println(adc0);
 // Serial.println(" ");
     
 i=0;
 c++;
 sensorValue =0;
 while (i<30)
 {
  adc0 = ads.readADC_SingleEnded(0);
  i++;
  sensorValue = sensorValue + adc0;
  delay (50);
 }
  sensorValue = sensorValue/30;
 // sensorValue = adc0;
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 21879, -2008,  2000);
  adjustedOutputValue = outputValue - x;
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);

  // print the results to the serial monitor:
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t output = ");
  Serial.println(adjustedOutputValue);

if (adjustedOutputValue > outputValueMax)
{
  outputValueMax = adjustedOutputValue;
}
if (adjustedOutputValue < outputValueMin)
{
  outputValueMin = adjustedOutputValue;
}
  
  totalAdjustedOutputValue = adjustedOutputValue + totalAdjustedOutputValue;
  av = 1.000*totalAdjustedOutputValue/c;
  hrs = c*2.00/60.00/60.00;

if (tempCount ==5)
{
  deltaTempC = tempC - previousTempC;
  previousTempC = tempC;
  tempCount=0;
}
  lcd.setCursor(0,0);  
  lcd.print("                    ");   
  lcd.setCursor(0,1);  
  lcd.print("                    "); 
  lcd.setCursor(0,2);  
  lcd.print("                    ");   
  lcd.setCursor(0,3);  
  lcd.print("                    ");  
   
  lcd.setCursor(0,0);    
  lcd.print("P:");     
  lcd.setCursor(2,0);         
  lcd.print(adjustedOutputValue);  
    lcd.setCursor(11,0); 
    lcd.write(1);
    lcd.print("T:");    
    lcd.setCursor(14,0);    
    lcd.print(deltaTempC);         
  lcd.setCursor(0,1); 
  lcd.print("Max:");  
  lcd.setCursor(4,1);       
  lcd.print(outputValueMax);     
  lcd.setCursor(0,2); 
  lcd.print("Min:");  
  lcd.setCursor(4,2);        
  lcd.print(outputValueMin);    
  lcd.setCursor(0,3);    
  lcd.print("Secs:"); 
  lcd.setCursor(5,3);            
  lcd.print(c*2); 
  lcd.setCursor(11,3); 
  lcd.print("hrs:");  
  lcd.setCursor(15,3);            
  lcd.print(hrs,2);  
  lcd.setCursor(11,1);    
  lcd.print("A:"); 

  lcd.setCursor(13,1);  
  lcd.print(av,3);

  lcd.setCursor(11,2);    
  lcd.print("T:");     
  lcd.setCursor(13,2);    
  lcd.print(tempC);  
  lcd.setCursor(18,2);    
  lcd.print("\337C"); 
     
  delay(2000);
  tempCount++;
}
void printTemperature(DeviceAddress deviceAddress)
{
  tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}  

Step 5: Real Life Testing

The hydrometer was tested by hooking it up to my Air Still. It worked fairly well and was very reliable, producing results to +- 5% accuracy. Based on these results, eventually it was eventually incorporated into a fully automatic NanoStillery™. Want to know what a NanoStillery is? Next instructable coming soon!

Please in the competitions - top right - Thanks!
<p>I had great success with your setup. However in my trials I had to add a way to insert air in the the tube leading to the pressure sensor. Over time the fluid would flow into the tube to the level of the overflow. To keep the sensor accurate I had to use a clear tube and a IV port to inject air into the tube. At which point this worked great. My readings range between 22 and 35 (out of 512, 16-bit differential), from water to 90%ABV. I think a shorter height parrot may yeild a broader range of values. Any thoughts?</p>
<p>I can't be sure from your photos, but I think that the clear plastic tube in photo no. 3 going up vertically is too small diameter and you will get fluid trapped in there due to capillary action. 'Injecting air' is a good idea and I had to do this myself with a 3 way valve to get the pressure sensor zero-ed.</p>
<p>I see, I went with the smaller tube because I wanted the highest possible pressure at the the sensor. Now that I've got it working I know that I'm at the top end of the scale for the sensor and I could use a larger tube and be within the range of the sensor. I imagine that's one way to adjust the pressure at the sensor, changing the overall volume of the line from the bottom of the parrot to the sensor that is? You can see the sensor in the center of the first picture, connected to the hose. The second picture is the floating hygrometer(sp?) with the azetrope(sp?) line in dashes. With the larger tube are you still having to inject air into the lines? Someone mentioned in a brewing beer forum that they used an aquarium pump to add air to the lines before they read the sensor. Thanks for sharing this!</p>
<p>The size of the tube won't make any difference to the pressure reading - all it does is remove capillary forces. I don't really know why I had to add my 3 way valve, in theory it should not be necessary but in practice ...... ? I think a pump is a bit of an overkill, but it would work as long as it's isolated afterwards with a single way valve.</p>
<p>Right that makes sense, this is static pressure not a flow...</p>
<p>After the 1/2 NPT elbow, you should add a close nipple and another 1/2 NPT elbow, then a reducer and a longer 1/4&quot; NPT niple so you have another column of liquid and air pointing up. Attach the hose to the top of that column. If the 1/4 NPT nipple reaches higher than the current outlet of the parrot, liquid will never reach the tube. You won't need the air injection, pump, or valve if you do this. </p>
<p>I think I might be in the overkill phase of this project already...</p>
<p>Aha ..... I can see the parrot now. It needs to be 5&quot; tall, but you could use other Honeywell pressure sensors in the same family rather than saw down the apparatus - have a look at the datasheets.</p>
<p>Wow ..... That looks truly sensational! I guess you're not producing whiskey? My automated NanoStillery is a lot simpler and it's designed for making 40 to 60% booze not pure (ish) alcohol.</p><p>I'd be interested to know what kind of heater you're using and where it is positioned? Also, do you neutralise the pH of your wash before distilling?</p><p>Oh, and I forgot, there's a video tour of the NanoStillery here:</p><p>https://www.youtube.com/watch?v=ck-_yTsY5Bo</p>
Eliminating the tube and putting a pressure sensor that is chemical resistant at the bottom where the tube connects will eliminate all need to inject air into your sensor line.
<p>Ah yes ..... Roger that!</p>
<p>I made a device from Motorola air systems back in the 1988 that looks at fresh water and salt water and then turned the salt on if it to little salt. I had to to use 6' towers of salt water and fresh water. They had both tubes with air running at 1 foot a minute. The the differential went to a controller that tuned on the salt water. I used a device for test the weight on the alcohol. </p>
If I were to build this I would eliminate the tube connecting the pressure sensor to the bottom of the unit. Thus eliminating the random innacuracy caused by the random levels of unknown fluids in the tube. Worst case the tube is filled with liquid to the same level as the liquid in the unit causing a zero pressure reading.
<p>I don't see how that would work!</p>
<p>What ABV are you aiming for?</p><p>I guess you can calibrate against sugar solutions for more dense liquids.</p><p>Interesting solution. Is it used industrially? I'm guessing that you're brewing up some water-based cleaning fluid.</p>
<p>Yes calibration is the answer!</p><p>I don't think it's used industrially - I think that a $2,000 inline refractometer would be used.</p>
<p>For us in US 22mm is 3/4&quot; and 15mm is 1/2&quot; CTS (Copper Tube Size) and do not use galvanized or Black Iron as &quot;reducing socket&quot; use Stainless Steel fittings. All threaded pipe has same designation in US as UK, they only call the copper in mm because of EU. And make sure your stand off fittings are brass, copper or SS or you will get galvanic reaction. </p>
<p>Hey thanks for the comment. The UK is going to leave the EU soon so hopefully we'll go back to inches for copper pipe? Don't worry about black iron / galvanised as there's none of these in this design :)</p>

About This Instructable

18,935views

150favorites

License:

Bio: Ugly pirate roaming the seas in search of Treasure.
More by Tecwyn Twmffat:Arduino Cell Phone 4G Signal Booster / Repeater Simple Manual Arduino 4 Axis Stepper Motor / 16 Channel LED Power Controller Full English Breakfast 
Add instructable to: