OPEnSampler Update, Bertha

Abstract

Our efforts over the past moths have culminated in a robust lab-tested prototype of the OPEnSampler we endearingly call "Bertha." We've determined this will be our in-house lab prototype that we will use as a testing bed for integrating new features and hardware. Lessons learned experimenting with Bertha will directly translate into field-deployable OPEnSampler versions to be distributed for use. This post details the technical specifications of Bertha, features, Serial Commands, and use cases.

Technical Specs

  • Frame dimensions are 24in x 12in x 12in and made out of 40mmx40mm extrusion.
  • 2 12VDC Peristaltic pumps (250ml water pumped in 2min)
  • 24 250ml aluminum-lined Mylar bags (spout packs)
  • 25 12VDC valves (24 valves attached to bags, 25th valve is used as a system flush outlet valve)
  • Arduino Uno, Microprocessor
  • Custom PCB with TPIC power-shits registers for handling valve actuation
  • Motor driver board
  • High Precision, Temp-compensated Real-Time Clock, for microprocessor sleep/wake(sample) scheduling.
  • Mode switch toggles between Sampler operation modes: standard operation mode, serial command mode.
  • EEPROM saves configuration of sampler parameters (sample duration, flush duration, next valve to sample, etc).
  • Serial command set for configuring the sampler's behavior out in the field and for sending discrete commands (puppet-string) to turn on/off discrete components of the sampler. e.g. turn pups on/off/reverse and open/close specified valves.
  • Power-save Sleep mode, for ling battery life in the field. At the moment, drawing 24 250ml samples should require just 1 Amp Hour of a 12VDC battery. In standard operation mode, sampler stands by in low-power sleep in between taking samples. In serial command mode, electronics remain awake and stand by for configuration commands from computer.

Modularity

In consultations with many different researchers hoping to use this OPENSampler, we identified that the technical specifications of the sampler will vary depending on the context of use. This includes: What kind of water source is being sampled, what is being tested or analyzed, and environmental conditions and considerations in the field. To this end, we decided to make a "core" system that would be extensible using attachments for particular deployment contexts. This architecture is not dissimilar with many vacuum cleaner systems, where the core remains immutable but changes utility based on the attachments used.

Packaging: The frame is designed to be dropped into a variety of different "packages" depending on the field requirements. In many instances, a waterproof duffle bag may suffice for carrying the device into back-country environments. Rigid stack-able boxes made from corrugated plastic may be desirable for other deployments. For field deployments requiring samples be temperature protected (from wither extreme heat or cold), dropping this into a rolling lockable travel cooler such as the Pelican 80qt Elite.

Use

Switch the sampler into "serial command mode." Not required, but should be done for best practice. After programming the Uno over USB, you may either switch the sampler directly into standard operation mode or send serial commands to configure your sampler's parameters. Switching modes back and fourth may be done at anytime. In operation mode, a sample cycle is initiated whenever the specified time has elapsed.

Each sample cycle consists of the following states:

  1. System Flush
  2. Sample Draw (in next bag in sequence)
  3. System Sleep/standby

Samples may be removed from the device without manually removing bags. This is achieved by switching the sampler into serial command mode and typing commands into the Arduino Serial Monitor window to draw samples out one by one in any desired order. See commands below. This process may be automated (and should be) using a program to send a sequence of timed commands. A sample python script can be found on the project GitHub site.

Sampler Configurable Parameters and Factory Defaults Are:

  • IsDaily = True (Take a sample either daily or at a set periodic rate throughout the day)
  • 8:00 (default daily time to take sample)
  • Sampler Duration = 100 seconds (takes 120 seconds to fill 250ml)
  • Flush Duration = 30 seconds (this will need to be set based on the length of tubing away from main sampler - longer tubing requires longer flush duration for full system purge)
  • Sample volume = 250 (in ml, this isn't being used right now, but there in case features need in the future)
  • Sample Valve Number = 1 (next bag to draw sample into)
  • Sample Period = 3 (if the IsDaily flag is FALSE,

The above parameters may be changed at anytime by switching into Serial Command Mode. Parameters are saved in EEPROM and are preserved even if the sampler looses power. Sampler operation will proceed with the new configuration behavior when switched back into operation mode.

Serial Command Set

  • CLK, Checks the current RTC time, Hr:Min:Sec - useful for checking before using SA to set sample alarm
  • SAD (int)X (int)X, sets "Daily Sample Alarm" Hr:Mn to take samples daily at time. Uses 24hr format.
        ex: SAD 9 30 sets sample alarm to 9:30AM daily.
        ex: SAD 16 22 sets sample alarm to 4:22PM daily.
        Also sets Is_Daily flag for initialization if power-down restart, clears Is_Hourly flag
  • SAP (int)X, sets "Periodic Sample Alarm" to take samples at specified period duration in Min.
        ex: SAH 30 sets sample alarm to go off every 30min.
        ex: SAH 47 sets sample alarm to go off 47min.
  • FD (int)X, sets "Flush duration" period in ms, should be about 20sec, but will change with the length of tubing you use to get from sampler to water source
  • SD (int)X, sets "Sample Duration" time that pumps run water into each bag in milliseconds
      ** removed for this version : SV (int)X, sets "Sample Volume" in ml, a transform of Sample Duration, may not be 100% accurate, 2min per 250ml,
  • VN (int)X, Sets the next valve/bag to place sample. Sampler saves curent valve number during operation in EEPROM in case of power failure, it picks up where it left off. This ensures you can reset the valve count before each new deployment, or manually skip to next available bag should the sampler malfunction
  • RST, Full system "factory" reset - set default sample period, sample duration, reset vlve counter, writes defaults to EEPROM (over-wirghting previous settings)

Pupet-String Commands:

  • Vx (int)#, Turn valve on/off where x is valve number (starting at 1, V0 is flush valve). # is 1 for on (open) and 0 for off (close) example: V1 1 opens valve 1. V1 0 closes it.
  • M #, turn motor on/off and direction. #=0 for off, #=1 for draw water into sampler, #=-1 for draw water out of sampler    example: M 1 will begin drawing water into sampler.

From here, you may use Arduino IDE, Python, or other software to send timed sequences to sampler. For example: V0 1 followed by M 1will begin flush.  The sequence (press return where you see / ) V0 0 / V1 1 / M 1will disable flush and draw water into bag1
    You could also make a "macro" or timed program in something like Python for drawing water out of the sampler sequentially into your analysis machine without removing bags! Example of this is on the project GitHub site.

Features to be integrated for Zurich Version

The Zurich version is underway, with frame being constructed out of much lighter 15mmx15mm extrusion. This will make the total sampler weight (without filled with water) about 10lbs!

Packaging: The frame is designed to be dropped into a variety of different "packages" depending on the field requirements. The package for Zurich is intended to be a waterproof duffle bag. However, for field deployments requiring samples be temperature protected (from wither extreme heat or cold),

Currently, all sampler status messages are reflected on the Arduino IDE Serial Monitor window when sampler is attached to host computer. We're evaluating an OLED display that will show all status information during sampler operation.  There will also be a wake button for the display that will show the status of the sampler at anytime during its sleep cycle.

Features for future versions

One major issue is not knowing the operational status of your sampler when left out in the field. Instead of being forced to check in on the sampler in person, we plan to integrate a GSM extension for the core, which will send updates over texts or emails using any 2G SIM card.

A Simpler Pump Test: No SD

Introduction

This is a follow-up to the previous post, "A Simple Pump Test". There were several complications with storing the pump data on an SD so this post will describe a new method that stores data on the Arduino's own memory.

Background

In the field, the pumps will be run for 2.5 minutes per sample for 24 samples, resulting in one hour of total runtime. As described in the previous post, the pumps used in the sampler are poorly documented and information on their lifespan and behavior under long periods of use is needed. 

The SD breakout board used in the previous test was a 3.3v board and was not compatible with 5v arduino logic without some voltage conversion in between. While it worked some of the time, it resulted in corrupt data after a few points. Rather than using a 5v board or something to step down the signal voltage, the Arduino's own memory can be used to store a small amount of data.

Arduinos have a small amount of available memory that doesn't get reset between power cycles, known as EEPROM. A single byte can be stored per register, and an Arduino Uno has 512 available registers.

Setup and Method

A 12v peristaltic dosing pump is wired such that the positive end is connected to a 12v source and the negative end is split between a .85 Ohm resistor and the Arduino's A0 analog input pin. The Arduino's GND is connected to GND on the power source and VIN is connected to 12v. The other end of the .85 Ohm resistor is connected to GND.

A jumper wire connects GND to the Arduino's digital pin 3, which is initialized to INPUT_PULLUP.

When powered on, the Arduino continuously checks that pin 3 is LOW. If it is, the voltage across the .85 ohm resistor is effectively measured via an analog read of pin A0 and the value is stored in a register of EEPROM. The register address is incremented and the loop resets.

If pin 3 is HIGH, data collection is turned off and the Arduino checks for a serial input of "p". If the user inputs in the serial monitor "p" then it prints all the data from the registers separated by spaces. This data should be copied and pasted into a text file, but can be reprinted as long as pin 3 is HIGH.

Code

// A simple voltage logger that is 

#include <EEPROM.h>

const int sensorPin = A0;
const int startPin = 3;

long sTime = 0; // last sample time
int maxPoints = 240; // maximum number of points to store
int sDelay = 30000; // delay between samples
int addr = 0;

void storeData();

void setup() {
  pinMode(startPin,INPUT_PULLUP); // if grounded, enable recording
  pinMode(sensorPin,INPUT);
  Serial.begin(9600);
  Serial.println("Initializing...");

  
  analogRead(sensorPin);
  delay(1000);
  analogRead(sensorPin);
  delay(1000);
  analogRead(sensorPin);
  delay(1000);
  analogRead(sensorPin);
  delay(1000);
  
  Serial.println("Initialized.");
}


void loop() {
  
  //If datalogging is enabled, store data in a new address
  if(!digitalRead(startPin)){
    if(millis() - sTime > sDelay){
      Serial.println("reading data point " + String(addr));
      storeData();
    }
  }
  else{
    Serial.println("Enter 'p' to print out data");
    
    while(digitalRead(startPin)){
      int input = 0;
      
      if(Serial.available() > 0){
        input = Serial.read();
      }
      
      if (input == 112){
        for(int i = 0; i < maxPoints && i < EEPROM.length(); i++){
          Serial.print(EEPROM.read(i));
          Serial.print(" ");
        }
        
        Serial.println();
      }
    }
  }
}

/*
 * store the sensorPin voltage and increment the address. If the address has
 * reached the limit of number of the points or hit the last address of
 * the EEPROM, don't store data and return from the function.
 */
void storeData(){
  if(addr == EEPROM.length() || addr == maxPoints){
    Serial.println("Max addr reached");
    sTime = millis();
    return;
  }
  EEPROM.write(addr, analogRead(sensorPin)/4);
  sTime = millis();
  addr++;
}
 

Python Code

# This code will take in data via a text file that was collected using
# the pumptest arduino code. Data points should be separated by spaces.

import matplotlib.pyplot as plt

data = []
splitter = []
voltage = []
current = []
average = []
avg = 0

with open('pumplog_2_p1t2.txt') as f: #file name for test data to be graphed
    reader = f.readlines() #read in the data

for line in reader: #split up the data. Could be conbined with converting to int but is more readable this way.
    splitter.append(line.split())

for point in splitter[0]:
    data.append(int(point) * 4) # turn each point of data into an int. Data values were divided by 4
                                # to fit into EEPROM.

for point in data: # calculate the voltage at each point.
    voltage.append(point * 5 / 1024)

for point in voltage: # calculate the current at each point.
    current.append(point / .85)

for point in current: # calculate the average current.
    avg += point
avg = avg / len(data)

for point in data: # turn average into a plottable list
    average.append(avg)

plt.plot(current)
plt.plot(average)
plt.title("Pump 1 Test 2") #rename based on test
plt.xlabel("time (minutes)")
plt.ylabel("current (A)")
plt.show()

 

Initial Results

Conclusion

Three tests have been run so far. They were graphed using Python 3 and matplotlib.pyplot. Another test is currently being run on the second pump. The data between the two pumps will be compared using a two-sample T test to check if the two pumps perform the same. The same method will be used for the pumps under condition of pumping water.

The initial three tests might suggest that there is a long term decrease in the pumps' current draw. Future tests should be conducted for a full day and a linear regression analysis should be performed. More importantly, such inconsistency in the current draw suggests the flow rate though these pumps is not constant. A test should be conducted to observe the trend and variance in the mass flow rate of water through the pump via a logging scale. A better conclusion can be made once the first round of testing is finished and statistically analyzed.

 

A Simple Pump Test

Introduction

Peristaltic 12V dosing pumps are cheap and provide a large enough volumetric flow rate for our needs. Unfortunately there is not much information available on the type we are using. This post will discuss the method we are using to test the reliability and consistency of these pumps over a period of two hours. It is the first of several tests we will be conducting on different components of our water sampler.

 

Setup and Method

A pump is held in a clamp and powered from a 12v source. A .85 ohm, 1.4 watt rated resistor connects the pump to ground. The voltage across the .85 ohm resistor is measured over time using an arduino and this data is stored in an SD card. 

The arduino reads the voltage on an analog pin and stores that, along with the time since starting in milliseconds, in the SD card. Initially there is a delay of one second in between data points and after sixty points the delay increases to one minute. This data will be transferred to a computer where it will be used to show the current through the pump over time.

 

Code:

// A simple voltage logger that is heavily
// based on the SD Datalogger example sketch.

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;
const int sensorPin = 0;

int n = 0;

void setup() {
  Serial.begin(9600);
  while(!Serial){
    ;
  }

  Serial.print("Initializing SD card...");

  if(!SD.begin(chipSelect)){
    Serial.println("Card failed, or not present.");
    return;
  }
  Serial.println("card initialized.");

}

void loop() {
    String dataString = makeDataString();
    File dataFile = SD.open("pumpLog.txt", FILE_WRITE);
    if(dataFile){
      dataFile.print(dataString);
      dataFile.close();
      Serial.println(dataString);
    }
    else{
      Serial.println("error opening pumpLog.txt");
    }

    if(n<60){ 
      delay(1000);
      n++;
    }
    else delay(60000);
    
}


String makeDataString(){
  return String(analogRead(sensorPin)) + ", " + String(millis()) + "; ";
}
 

Conclusion

Once the pump has run for two hours, the power will be turned off and the data from the SD card will be transferred to a computer. Using Ohm's Law the voltage across the resistor will show the current through the system. The data will show what kind of trend, if any, the current draw has through the pump. It will also show if the current draw varies with a resolution of one minute.

This test will be repeated for two other pumps. Then it will be repeated with water flowing through the pump tube.

New Design: Water Sampler 4040

Abstract

I finished the new design of the 24-bottle water sampler which will be fabricated within the next week before the electronics PCB gets here. The new design is made entirely out of 4040 (a 40 mm x 40 mm profile) extruded aluminum, common store-bought joints, and 3D printed components.

water sampler 40404 render

Objective

This redesign solves several issues with the original foam enclosure:

1. The 4040 frame does not require a laser cutter to manufacture

2. The frame is rigid

3. Mounting objects rigidly to the frame is very easy

Materials and Methods

This design uses 2 primary materials at the moment: 4040 extruded aluminum, and 3D printed ABS plastic. All of the printed parts could be replaced with machined mounts and brackets in the absence of a 3D printer. 4040 was chosen for the frame material because of its ease of use and because we have tons of it here at the lab, but future designs will most likely use slimmer extrusions like 2020 to save cost and weight.

Explanation of the Design

Four long extrusions make up the outer corners of the frame. They are 600mm long, roughly corresponding to the 24 inch length of the original design. The short outer-frame pieces are all 210 mm long to provide enough space for the bags to hang. A 600mm length piece of 4040 runs across the top and provides channels to mount the valves, pumps, and electronics. Two 520mm lengths of 4040 across the sides, offset from the top by a few centimeters, provide the channels for the bag caps which the sample bags hang from.

The orange brackets are 3D printed and connect the central channel perpendicularly to to the frame. Other brackets are store-bought and aren't included in the design. All mounting is done using t-nuts and/or t-bolts that slide in to the 4040 channel to limit the amount of machining required to assemble the sampler. A thin sheet of PETG plastic will cover the top of the assembly and protect the device from rain but could easily be replaced with a large trash bag or tarp.

New Water Sampler Electronics Board

After lots of struggling with the current perf board electronics, we decided getting a PCB made was the way to go. The electronics have changed quite a bit since the last version so I started this one from scratch.

 

Changes include many more connections to the arduino, headers to connect the H-bridge and RTC breakouts, and removing the MOSFETs. The PCB includes a proper ground plane, our logo, and holes for mounting!

 

The primary benefit of moving to a PCB is the ability to use a rectangular connector on the board and insulation-displacement-connector for the ribbon cable, which means that we will be able to snap the 50-wire cable on and off the board. The quantity of connections made for a messy perf board and caused a lot of headaches while troubleshooting malfunctions. Despite the current setup working, it wouldn't be reliable in the field.

WaterSamplerBoard_v1

There are a few changes I need to make to the design, such as optimizing the sizes of the VCC traces, but it should be sent out to be manufactured soon!

Reversing The Motor Direction To Drain A Sample

I've attached a video of the nearly finished water sampler's ability to drain a sample without disconnecting the bag from the system. The current system is not proven to be air-tight and should not be expected to be so, but this will help to reduce error and eliminate the need to disassemble the tubing. Instead, the user can specify which bag to sample and run the pumps in reverse through serial commands through a computer console.

A Successful Test

After about a week of waiting, the Adafruit DRV8871 H-bridge motor driver breakouts were delivered. They will replace the MOSFET circuit driving the pumps, which were allowing all kinds of noise and voltage spikes and caused the TPIC shift registers to reset every instance the pumps were switched on. Additionally, the previous electronics setup was mysteriously allowing the valves to leak water through to the sample bags when switched off. With the pumps being driven by the H-bridge, this problem has completely disappeared. The original cause was most likely related to the valves "soft resetting", where each valve was neither completely off nor completely on after the pump was powered.

We just received an email today letting us know that the rest of the valves have finally shipped, which will allow us to completely assemble our 24 bag sampler! While we wait for that, I'll be working on translating the electronics to a PCB and getting that printed. I'll also be reviewing the design and adding more functionality to the code.

I recorded of a video of the system in action, included below, which is the first recorded successful test of our water sampler!

Pumps and Pump Mounting

Several design decisions were made based on our pump parameters needed. For example, we need at least one meter of pump head and we need to be able to move water through roughly 5 meters of 3/16'' (.476 cm) tubing (most likely there will be less tubing involved, but this is a good number to start with).

Through observation, I found that the throughput of a single pump at 1m head and room temperature was 50mL/min, or .83 cm^3/s, and the maximum suction head is greater than 1.5 meters, which was the highest I could place the pump without creating a more complex setup. 

With a tubing cross sectional area of .71 cm^2, the velocity of the water in the tube being moved by the pump is about 1.2 cm / s. With such a small velocity, the head loss directly resulting from the 26 tee joints is about .76 cm, and the head loss from the friction of the tubing is even less than that. 

Because we don't have to worry about head loss, and the max head one pump can provide exceeds our requirements, I decided that the design should combine two pumps in parallel to improve throughput rather than in series to improve head. 

Now I could design the dual pump mount! I went with a design that mounted on the inside of the C-Channel spine, with the colinear, top-to-top facing pumps sticking out perpendicular to the c channel. The first 3D Print should be finished tomorrow! Pictures below.

twopumpmount.jpg
twopumpmount2
twopumpmount3

Schematics!

I've completed two schematics for this project. The first is the base unit schematic (above). This is the main unit we will develop first. The schematic includes 8 valves (shown as inductors on the schematic) and one TPIC power shift register for controlling them. 6 lines are connected to a header: 5V, 12V, GND, SCK, DATA, and RCK. Because the base unit will have 24-31 bags for sampling, rather than 8, we will be using 4 TPICs in series on a single board to control a corresponding number of valves. The 3 additional TPICs will be connected in the same way shown in the extension unit schematic (below), only without headers in between sequential TPICS and only using one waste valve at the end. 

Screen Shot 2017-01-24 at 4.04.53 PM.png

Eventually, extension units will allow additional samples without adding complexity to the process. 6 wires and one water line will connect the base unit to subsequent extension units, each with 24 bottles and an output line themselves. 

 

The dummy switch, which is meant to represent a water probe that will be located at the end of each unit to check that water has flowed to the end. This is critical to the system's sampling process: if the system tries to sample a specific amount of water based on the time the pumps are running, then it needs to know when to start timing. The probe will "short" like flipping a switch (though with much much more resistance) and send a low signal to a digital pin.

OPEnS Water Sampler Debut @ AGU 2016

The OPEnS lab contributed a demonstration of the new water quality sampling system they are developing as part of a “Rube Goldberg” water machine that passed water from unit to unit.  This was organized by Rolf Hut as a collaborative effort between institutions (each one contributing one or two units to the Rube Goldberg machine), and was widely seen by conference participants as “street art” immediately outside the conference.  This was the first time such an effort had been tried, and brought many smiles, and much publicity for the OPEnS initiative.