-
Notifications
You must be signed in to change notification settings - Fork 7
project3 team2
- Austin: Model, Arduino Code, Qt
- Travis: Model, Arduino Code, Simulation Code
- Blade: Rig Stuff, Calibration Code
- Anthony: PCB
- Keaton: Rig Stuff, Calibration

This problem involves a single rig, and finding the volume of an object dropped into the top portion. The top portion of the rig is a "leaky bucket", where water is flowing out of the rig into a reservoir at the bottom. The water pump pulls water out of the reservoir and pumps it into the top portion. The water pump is controlled by a PID controller, which pumps water into the top reservoir to set the water to a set height.
We will call the flow rate into the bucket, with respect to time, fin(t) and the flow rate out fout. The volume of water added in the top chamber from ta to tb:

If this integral has a negative value, then that volume of water was removed from the bucket in that time interval. If an object is added into the bucket, it will displace water equal to it’s volume in the bucket. Thus, the PID controller will react and remove that volume of water from the bucket, so that the height goes back to the setpoint. This allows for a simple way to calculate the volume of an object: The value of the above integral with ta = time that object was dropped in, and tb = time that water level steadies (or any time after).
Because we may not be able to (or want to) measure various values, we can perform some tests to find these values.
First, we can find the flow out of the leaky bucket. To do this, we can set the PID controller set point to any height, and wait for the water level to become steady. At this point, the flow into the system will be equal to the flow out. Then, measuring the flow in will give the flow out of the system. To get even more accurate values, we can perform this test at a number of set heights, and derive a function from height to flow out.
Similarly, we can find the area of the top portion of the system by measuring the flow out at different heights. For example, we can set the Setpoint to height 5, and wait for the water level to steady. Then, we can set the Setpoint to height 10, and use the above mentioned function to get the amount of volume added to the top chamber by increasing the height 5 cm. From here, we can divide this volume by the height change and find the Area and Diameter of the top portion.
//Calibrate to find flow out of bucket
Calibrate PID
PID setpoint = 5
loop while not steady:
compute PID output
PID input = read height
pump rate = PID output
//Set outflow equal to flowrate in steady state
outflow = read flowrate
//Find volume of object
loop while not steady:
PID stuff
//Drop object in
obect volume = 0
loop while not steady:
PID stuff
object volume += (outflow-read flowrate)*time_per_step
//take negative of this "integral" to obtain object volume
object volume*=-1
##Implementation In order to test our code we started the rig and waited for our PID to achieve a steady state. Once in a steady state we carefully poured water into the reservoir to simulate the dropping of a predetermined volume object. During the first few test our values were highly inaccurate. We determined the problem to be with our PID being unable to achieve a steady state again quickly enough. The way our code was originally designed we waited for a steady state and recorded the current flow rate once the steady state was "broken" we had the teensy internally time how long it took to re-achieve the steady state and then integrated or essentially multiplied the flow rate by the amount of time it took and were then able to determine a volume. Since the PID took too long to achieve a steady state our values were off. In order to correct this problem we modified our code so that once in a steady state it recorded the current flow rate as well as the current height. After dropping in our object we calculated the volume once the infrared sensor read the recorded steady state height value. Our values were much more accurate. Still due to the noise from the infrared sensor our values were not as accurate as we would like. To counteract the noise we implemented a simple filter by averaging the infrared sensor values in rolling sets of 10 where the first value is removed when the last value is added.
Our Qt visualization was very much similar to the Qt visulization for the earlier projects, with an added text box for displaying estimated volume, and removal of the Solenoid graph.

Depicted above is the set up of two reservoirs that are hooked up to two pumps a flow rate sensor and two IR sensors all of which are connected to screw terminals on the PCB. During testing the infrared sensor gave us some extraneous values. We noticed even though our set point had not changed the water level in the reservoir was at a different point than the previous time we ran it. After draining it and restarting, the IR sensor seemed to behave correctly again. Whenever we dropped an object into the reservoir the IR sensor gave some inaccurate readings possibly due to the plate used as a reflective surface tilting while pouring water into the reservoir. There were also some discrepancies with the PCB and components not working as intended. Once that problem was solved our code ran quite well although not with extreme accuracy.
##PCB Design and Testing
Each team was tasked with submitting a PCB design to the rest of class that was to be voted on and used for the main project rigs. Our initial PCB submission was incomplete in that the second pump was left out of the design. Hence, our design was not in the running for main rig use. Our PCB, however, was updated for the sake of project completion and to compare our design to the PCB voted on by the class. The completed PCB is pictured below.

The dimensions of the design are 6cm x 6cm. Each pump set up is separated to easily distinguish between pump 1 and pump 2, especially if only one pump is needed for use. IR sensors are also grouped together. Computer input to the Teensy and external power source input are opposite one another in the event that both power sources are used simultaneously. It it a very simple design based off a successful project 2 design.
Team 4's PCB design was chosen by popular decision to be printed and integrated into our system. The board is smaller, more compact, and includes an I2C bus LED driver.


Initial testing of the PCB resulted in the pump running a full 12 volts with no PWM. We determined, by inspection, there was no connection between the MOSFET transistor and pump. We were forced to solder an external wire to complete the connection. This proved to be the issue as further testing resulted in successful calibration and control of the system.

##Simulation and Experimental Results Since our simulation is deterministic, the estimation for a given initial height and object volume will always be the same.
| Initial Height | Object Volume | Estimate |
|---|---|---|
| 6cm | 200 ml | 201.26 ml |
| 6cm | 100 ml | 100.77 ml |
| 3cm | 200 ml | 231.88 ml |
| 3cm | 100 ml | 99.32 ml |
As time became limited, we were only able to run one initial height/object volume test. However, we were able to get a few data points to better understand our system's accuracy:
| Initial Height | Object Volume | Estimate |
|---|---|---|
| 8cm | 200 ml | 196 ml |
| 8cm | 200 ml | 225 ml |
| 8cm | 200 ml | 158 ml |
#Problem 2
The second scenario we are modeling is the two-bucket water height control. This involves two connected leaky buckets, each of which needs to maintain its own setpoint.
In order to create a mathematical model, we have to define relevant variables, and functions that define the values that those variables take over time. In our case, we have the flow into each of the buckets fin1 and fin2, the flow out of each bucket (assumed to be contant) fout1 and fout2, the set points SP1 and SP2, the water heights h1 and h2, and the flow from bucket 1 to bucket 2 (which can be negative) fb. From these variables, we also define error variables e1 and e2, which are useful for simplifying the PID equations. Everything other than S P1 , S P2 , fout1 , and fout2 is a function of time, 2 and can be defined as follows for each bucket:

In real life, and in our simulations, all of these calculations will be done in discrete time. This simplifies the equations to the following:

For this problem, the main value to find (that is not covered in problem 1) will be the flow between the two cylinders. To find this, we can set one rig to be at the max height, and the other to be at the min height, and wait for both water levels to steady. Then, take note of the difference between the flow in rate to each system. For rig 1, Flow in - Flow out - Flow between = 0, and for rig 2, Flow in - Flow out + Flow between = 0. By doing a flow out measurement similar to the one described in problem 1, it becomes easy to find the flow between the two rigs given that both water levels are steady. Then, we can simply take these measurements for many values of different heights for the two rigs, and derive a function of flow between given the heights of each system (we suspect that this function will really just be a function of the difference of the two heights).
//Calibration
Calibrate PID1 with side 2 empty
Calibrate PID2 with side 1 set at half height
Recalibrate PID1 with side 2 at half height
set PID1 setpoint = PID2 setpoint = half height
loop while not steady:
PID1, PID2
outflow 1 = read flow 1
outflow 2 = read flow 2
//Find flow between buckets as a function of h1, h2
FlowLUT = array(10, 10)
for i, j in range(1, 10):
PID1 setpoint = max_height/10*i
PID2 setpoint = max_height/10*j
loop while not (steady1 and steady 2):
PID1, PID2
//Take average of the "unaccounted for" flow in each bucket
FlowLUT[i, j] = (read flow 1 - outflow 1)/2-(read flow 2 - outflow 2)/2