System for Calibrating Dogbone RFID Moisture Sensors using Decagon 5TM Conductivity Sensor and I2C Communication

Author: Brett Stoddard

Hello  Everyone! 

This last week I’ve been working on getting a system to log data that I will use to calibrate the Smartrac Dogbone RFID moisture sensing tags in soil

Abstract and Objectives

This blog post describes a system to log data that I will use to calibrate the Smartrac Dogbone RFID moisture sensing tags in soil using a Decagon 5TM moisture sensor. The goal of this system is to log both 5TM’s electric permittivity readings (ε) alongside Dogbone’s moisture sensor levels over a long period of time to make a relationship and eventually properly calibrate the Dogbone tags to the current industry standard, dielectric permittivity. 

Using a 2GB SD card, this system will be able to record 82 million data points, more than enough for our system (each data point takes up around 26 bytes and 2*230/(26) = 82*106 ). The period that the measurements are taken at can be changed easily, but is currently set at 10 minutes which gives a solid resolution but is still small enough to analyze easily. Theoretically, measurements could be taken with a minimum period of 5 seconds. The logged data points will be saved as a CSV file because those can be read by Excel which will make analyzing data fairly trivial. 

Materials

Libraries

Description

After encountering a few problems, the system that I settled on was two Arduinos that would communicate over I2C. I was forced to do this because the “SDI Library” that is needed to communicate with the 5TM soil sensor I was using is incompatible with the “SoftwareSerial” that was critical for debugging and testing the code.

I2C communication was originally developed for and is usually used for multiple chips on the same embedded electronic system to communicate over the same bus. It’s useful for when tasks need to be split between multiple Arduinos. I2C is implemented in Arduino using the Wire library. For this situation, the slave Arduino was the one reading data from the TM5 sensor. The nice thing about I2C is that it is relatively trivial to add additional sensors to any sensors to a setup in case we want to make multiple readings at the same time. The code for implementing this setup was written by following this tutorial

One Arduino was set as a slave and read the data from the 5TM sensor. I followed Chet’s Decagon 5TM sensor guide to set this up. The master Arduino had the GPS logger, and RFID reader shields on it to record the values. The RFID reader shield uses pins 2 and 3; the GPS SD logger pins 13, SCL, and SCA; and I2C pins GND, A4 and A5 on the master Arduino. The 5TM sensor used pins 6, 5V, and GND; and I2C pins GND, A4 and A5 on the slave Arduino. The hardware diagram shown below illustrates this.


calibrator-diagram

The code for this system will be posted in the examples folder of my RFID Github library under the title “Calibrator example”.

Results

Last night, the first data set was collected using this setup over the course of 16 hours. Below is the graph (made in Excel) that shows the Dogbone moisture values (units not named) vs the 5TM conductivity measurements (dielectric permittivity, ε). There was a recorded R^2 value of .75 which means there was a moderately high correlation between the two. As one can see from the graph, over time the 5TM’s electron permittivity decreased slowly as the soil slowly dried out. Longer-term tests where the soil has time to go from saturated to dry will be key for properly calibrating the Dogbone tags to the current industry standard, dielectric permittivity.


The x-axis has units of number of 10 minute intervals

The x-axis has units of number of 10 minute intervals

Make it Slide!

Abstract:

After having the first prototype of the hyperspectral camera rotating mount, it was time to start the rail version. We have aluminum extrusion in the lab, but I still need to design the carriage that will carry the camera. One important factor in this design is that it has to be modular, meaning that we have to be able to make it as small or big as needed. Having all this in mind, I set off in search for solutions that would allow me to put together this modular rail.

Objective:

To find the best material that will balance weight, modularity, and precision in order to create the rail version of this product. 

Materials and Methods:

Internet searches were the main method of investigation.

Keywords:

  • Aluminum Extrusion
  • Rails
  • Rollers 
  • Linear Systems
  • Linear guides

Results/Discussion:

After surfing the web, I concluded on 4 potential paths to take in order to commence the build of the rail version of the hyperspectral camera rotating mechanism. The options are: linear guides,  Buy Rollers or 3D print rollers.

In terms of guides, the options were good but expensive. I found T, W, and V style linear guides. I easily found T and W, but I didn’t find V until the end of my search. This was due to the fact that it’s not common among the mass-produced material. The problem with the 40×40 aluminum extrusion that we have in the lab is that there exists almost nothing in terms of rollers, and the ones that do exist are expensive.  I did a couple of test prints for the rollers, but I was not satisfied with the quality, therefore this was not an option. 

As of right now, I think that going with the V style guides is our best option. This is because they are the most economical of all and they are specifically manufactured for linear motion systems. The price is about $6/m, compared to the others this is cheap! The other materials were coming in at $825.82/m, $301.72/m, and $65.55/m; this is for the w and t style rails. 

The website that carries the V style guides also has the necessary components to mount the rails onto the aluminum extrusion and has the plate for the carriage. This way we can get everything from the same vendor and at a  reasonable price. 

Pictures:


3D printed rollers3D printed rollers

3D printed rollers

Links:

W Style guides

T Guides 1

T Guides 2

V Guides

Working with the “Internet” for the Internet of Agriculture

Abstract

WiFi Data Logging

For the last few weeks I have been working on using an Arduino Uno and a couple different ESP8266 WiFi modules for the purpose of  logging sensor data in real time to a Google sheet and develop a network Gateway for all of our sensor devices.

 


The  ESP8266  WiFi Module. The IOA's internet! The  ESP8266  WiFi Module. The IOA's internet! 

The ESP8266 WiFi Module. The IOA’s internet! 


Hazzah!  Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. Hazzah!  Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. 

Hazzah! Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. 

The ESP8266 WiFi Module is a self contained SOC with integrated TCP/IP protocol stack that can give any microcontroller access to a WiFi network. The ESP8266 is capable of either hosting an application or offloading all Wi-Fi networking functions from another application processor. This function is most important for this particular project and will be used as gateway to log data straight to the internet.

Methods

Working around Secure Connections

Google Forms requires a secured connection (SSL) but the Arduino (Or autonomous huzzah board) doesn’t have enough power/memory to create SSL connections. We will use a third party Application program interface, PushingBox to work around this. 

PushingBox API is really simple in concept and in practice.  To launch a “scenario” of notifications you can send an HTTP request . The only argument you should attach is the DeviceID (details on how to find this found below in a link) . This is the unique key that identify the scenario you want to launch. The DeviceID can be found on the Scenario Page.You can also put more arguments to define customs notifications text using your own variables which is what we will do to allow sensor data to be uploaded to a google sheet.

This allows PushingBox to confirm the secure connection needed for google to begin passing on data uploaded from the Arduino. All this in real time. A more indepth explanation of this process can be found in a Hackster.io tutorial found here

Setting up the Google sheet

Another important aspect of this project was to prepare the google spreadsheet for the data it is about to receive. This is done in a google G-script (similar to java) and the instructions on how to do this can be found here.  This step is a bit technical and requires some patience while working through.

Data, Links , Projects, and References

Wiring and other example projects the OPEnS lab has worked on  can be found here.


Original ESP8266 setup running through an Ardiuno Microcontroller.  Original ESP8266 setup running through an Ardiuno Microcontroller.  

Original ESP8266 setup running through an Ardiuno Microcontroller.  

***Important note***

If you are using the older ESP8266 chip it is important to have an external voltage regulator. (This problem was resolved in the Hazzah board which contains an internal voltage regulator)

On Arduino Uno, / Mega the 3.3V regulated output is able to supply 150 mA max. The ESP8266 draws up to 500 mA and could damage the Arduino.
Add a 3.3V Voltage regulator such as LM1117-3.3 to power the ESP.

A helpful diagram to reference can be found here. 


Hazzah Board being flashed using a FTDI cable Hazzah Board being flashed using a FTDI cable 

Hazzah Board being flashed using a FTDI cable 

 

Note: On the Huzzah Breakout Board, the module must be put into bootloader mode described below before you can upload a sketch from the Arduino integrated development environment (IDE). 

  1. Hold down the GPIO0 button, the red LED will be lit
  2. While holding down GPIO0, click the RESET button
  3. Release RESET, then release GPIO0
  4. When you release the RESET button, the red LED will be lit dimly, this means its ready to bootloader

Then in the upload the sketch found here with the appropriate libraries found here.

Specifics on how the pinout and wiring differs for the Huzzah breakout board can be found on the adafruit site here

Conclusions and Results

After much frustration and hours of tweaking code for the ESP modules and G-Script,  I was successfully able to hardline pseudo data from the microcontroller, through the ESP module to Google sheets via the PushingBox API. This ability really opens up an expanded capability for our sensors that are in developed and will prove to be an integral part of the OPEnS lab remote sensing. 


Pseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google SheetsPseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google Sheets

Pseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google Sheets

Extension of Work

The next step in this project is going to be integrating this data logging interface with data transmitted from the LaRo Radio module. This project will continue in the coming weeks in collaboration with Marissa Kwon.


Work on integrating the LoRa radio receiver and the Huzzah ESP8266. Work on integrating the LoRa radio receiver and the Huzzah ESP8266. 

Work on integrating the LoRa radio receiver and the Huzzah ESP8266. 

– Tom DeBell, Beginning Researcher Support Program Researcher
 

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.

 

Low and slow

Abstract: 

Why go slow? We need to take pictures at very slow speeds and at a continuous rate using a hyperspectral camera! With the old electronics board, this was not possible, but the new one works amazing!

Objective: 

Rotate the stepper motor at very slow and steady rates to allow the camera to take pictures. 

Materials and Methods: 

Using the Sparkfun’s EasyDriver Stepper Motor Driver, we are going to drive the stepper motors for this project. We were previously using Adafruit’s TB6612 Stepper Motor Driver but it was not giving us the performance that wee need.  Here is the wired up motor driver:


Results:

Using Sparkfun’s board we are able to achieve the results that we wanted. We are going use the new board instead. It works great at very low speeds and is very steady.

Dependencies: 

https://www.sparkfun.com/products/12779

Nordic RF shields for Adafruit ProTrinket

By: Chet Udell

Abstract:

This post provides an update on the near-range (up to 100m) RF branch of the Internet of Agriculture Project. New PCB design makes an improvement on a general-purpose, opensource, plug-n-play wireless sensor kit.

Objective:

The previous version of the RF IoT sensor kit had some minor layout flaws, and failed to accommodate a ‘handshake’ button for auto synchronizing an RF sensor node with its base station, a power button, and some other small details. A new version adds these features and reduces the overall device volume by one-third.

Methods and Materials:

Eagle CAD was used to modify a previous version of the PCB. A whole new layout was explored that reduced overall device volume substantially and new features added including: power button, handshake button, removing 12VDC power adapter on base receiver (for now), placing LiPo Backpack on the underside of the transmitter, and creating a “stackable” offset for the ProTrinket, should anyone wish to make further shields to extend this devices capacity.

Results:

See below! PCBs are in the fab house now. . .


WASN_HonorsBrd.pngWASN_HonorsBrd.png


Toward Comparing RFID Moisture Performance with Industry Standards: Decagon

Author: Chet Udell

 

 


Abstract:

Our previous experiments have shown the RFID moisture sensor tags are in-fact reading gradual changes in soil moisture content. The next step is to compare the performance, consistency, and resolution of these tags to industry standard equipment to see how it measures up using Decagon Devices soil moisture sensors. In this post, Chet gets a 5TM Soil Moisture and Temperature Sensor chatting directly with an Arduino to deploy in experiments, and eventually integrate into the battery of available Internet of Ag sensors.

Objective:

In order to compare the performance, consistency, and resolution of the RFID moisture tags, we hope to conduct some comparative experiments between these and Decagon’s popular soil moisture sensors, namely the 5TM (soil moisture + temp). Decagon’s readers can be pricey and we want to use these sensors in very specific ways, so the objective here is to get the sensors talking directly with an Arduino. The following method can be used to read any Decagon soil moisture sensor over the SDI-12 serial protocol. For more info on SDI-12, visit here. Why the 5TM? The 5TM determines volumetric water content (VWC) by measuring the dielectric constant of the soil (or other media) using capacitance/frequency domain technology. Signal filtering minimizes salinity and textural effects, making the 5TM accurate in most soils and soilless media. Factory calibrations are included for mineral soils, potting soils, rockwool, and perlite. – from http://www.decagon.com/en/soils/volumetric-water-content-sensors/5tm-vwc-temp/

Materials and Methods

What you’ll need:

  1. Download the above library, unzip. Rename the file “SDISerial” and place in the folder: <Arduinno root folder> / libraries
  2. Following the instructions on the library GitHub page (image included here), clip the 1/8 inch jack off of the Decagon sensor (ouch), strip off the leads to reveal a white, red, and “shield” wires. Solder each wire to a 0.1in pitch male header to use in a breadboard.
  3. Connect your arduino up to a breadboard and the 5TM lines White => 5V, Red => DATA_PIN, Shield => GND
  4. DATA_PIN MUST be connected to a pin with a hardware interrupt (for Uno, P2 or P3).
  5. Use the below code and you’ll get soil moisture and temp readings (in Celsius).
  6. Your output will look like the below screen print

Results

As you’ll see from the below code and printout, the SDISerial library enables the arduino to send commands to the 5TM to procure data. Now, we can employ these sensors in almost any Arduino application! This is done by creating an instance of SDISerial connection(DATA_PIN); and then starting the serial connection using connection.begin();

You can then use the function connection.sdi_query() to send various commands to the 5TM. This function uses 2 parameters: (command, timeout-duration)

connection.sdi_query(“?M!”,1000); This sends a message to query the first device on the bus – which in use seems to refresh the values of the sensor readings, but does not return the sensor reading itself. Instead, it returns a message that tells you the maximum wait before the measurement is ready. timeout set for one second.

connection.sdi_query(“?I!”,1000); will get sensor info and timeout if no response in 1 second

connection.sdi_query(“?D0!”,1000); will query the 5TM for sensor data

 

 


Hookup on a Mega, similar to the Uno

 

 

 


Resulting output
/*
Tested on UNO R3.
Sketch was built with Arduino 1.6.12
Dependency: Joran Beasley SDISerial Library
Accessed May 26, 2017 here:
https://github.com/joranbeasley/SDISerial

download and rename folder "SDISerial" and place in  "<ARDUINO_ROOT>/libraries"

Tested with the with the 5TM Soil Moisture and Temp Sensor:
http://www.decagon.com/en/soils/volumetric-water-content-sensors/5tm-vwc-temp/

Hook-up:
the WHITE wire goed to 5V. however you could also connect it to a pin and drive power only when you wanted it
the RED wire is the DATA_PIN. - you must hook it up to a pin that can process interrupts (see link below)  
the remaining "shield" wire must be connected to ground
*/

#include <SDISerial.h>
#include <string.h>
#define DATA_PIN 2
SDISerial connection(DATA_PIN);
char output_buffer[125]; // just for uart prints
char tmp_buffer[4];
char* resp; // Pointer to response char

//initialize variables
void setup(){
      connection.begin();
      Serial.begin(9600);//so we can print to standard uart
      //small delay to let the sensor do its startup stuff
      delay(3000);//3 seconds should be more than enough
      char* sensor_info = connection.sdi_query("?I!",1000); // get sensor info
      //print to uart
      sprintf(output_buffer,"Sensor Info: %s",sensor_info?sensor_info:"No Response");
      Serial.println(output_buffer);
}

//main loop
void loop(){

   //print to uart
    Serial.println("Begin Command: ?M!");   
    //send measurement query (M) to the first device on our bus
    resp = connection.sdi_query("?M!",1000);//1 second timeout
    //this really just returns a message that tells you the maximum wait before the measurement is ready
    
    sprintf(output_buffer,"RECV: %s",resp?resp:"No Response Recieved!!");
    Serial.println(output_buffer);
    delay(1000);//sleep for 1 seconds before the next command
    
    //print to uart
    Serial.println("Begin Command: ?D0!");
    resp = connection.sdi_query("?D0!",1000);//1 second timeout
    
    sprintf(output_buffer,"RECV: %s",resp?resp:"No Response Recieved!!");
    Serial.println(output_buffer);
    delay(3000);//sleep for 10 seconds before the next read
  
}

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.

3D Printing a Culvert Entrance

Abstract: 

I’ve been working with Desiree D. Tullos to create a 3D printed culvert entrance. The designs are done and are about to be printed. These will help illustrate the flow of water in a real system. The designs were created to simulate an efficient and inefficient culvert. 

Objective:

To simulate the inefficiency and efficiency of water flow in a real culvert using 3D printed culvert entrances and acrylic tubing for the pathway of the water. 

Materials and Methods: 

Desiree’s team sketched the design in 2D and then passed the specifications to me. I then designed the 3D model, in Fusion360, from the 2d design. We will print these on the Fusion3-f400. Here are the designs: 

 

Results: 

I still need to print them, but I did test print the entrance of the piece and it fits well with the acrylic tubing. Here are some pictures of the print:

 


Acrylic Tubing with o-ring&nbsp;Acrylic Tubing with o-ring&nbsp;

Acrylic Tubing with o-ring 


3D printed entrance on acrylic&nbsp;3D printed entrance on acrylic&nbsp;

3D printed entrance on acrylic