Flow/pressure profiling for the La Marzocco GS/3 - Page 2

Equipment doesn't work? Troubleshooting? If you're handy, members can help.
User avatar
Peppersass
Supporter ❤

#11: Post by Peppersass »

AssafL wrote:Arduino is awesome because you actually get to do very little programming. It is actually about taking stuff others wrote and using it in creative ways.
So I discovered:

Image
The first line of the display shows the analog A/D count and calculated input voltage from the pot on the left (range 0-5VDC, as shown on the big meter.) The second line shows the PWM D/A count and output voltage, as shown on the small meter (a little hard to see: it says 5.044V.)

Input and ouput are only off by about 0.02V, which is not material for the gear pump. The error is probably in the mapping numbers I lifted from the example code. But they appear to be pretty standard for 5VDC applications -- I've seen the same numbers in several examples. The conversion from A/D and D/A counts to voltage is based on factors I calculated, and they don't always match the meters due to the setup not being completely linear. Here's what it reads with the pot set to the middle of the range:

Image

It's a little closer because that's where I calculated the conversion factors. That's also a more likely value for the gear pump, which never runs anywhere near max speed. Will revisit the D/A mapping and conversion factors when I connect the real pot.

In the first pass I didn't use an RC circuit to smooth the waveform. My meter deals with that just fine, and I suspect the gear pump would, too. It might even smooth the input signal. The frequency was about 500 Hz because the loop has a 2 ms delay to let the A/D converter stabilize. I extended that to 10 ms and got a more stable reading. Later I added a simple RC circuit consisting of a 15K resistor and a 1uf capacitor (happened to be tantalum.) That reduced the ripple to about 2 Hz. Haven't looked at it on a scope yet.

As you said, virtually all of the code came from two examples. The read/write code is from an example in the intro to using the online IDE. The LCD code came from a Hello World example in the manufacturer's driver library (Adafruit.) The rest was just calculating the conversion factors and aligning text on the display. It's 74 lines of code, most of which is comments, literals, etc. The heart of it is only 30 lines of code, and it could be done in less without the display formatting.

The code is most of what I need to do the gear pump speed limit. Just have to connect the pressure transducer and read it in the loop. When the limit is reached, it'll reduce the motor voltage in steps until the pressure limit is reached. Below that, the pot will determine motor speed and pressure. The display will show current pressure in BAR, the pressure limit, the motor voltage, and the motor RPM. I'll use the buttons to toggle between a limit of 10.5 BAR and 12 BAR, or maybe to set a specific limit (not sure if I can store any parameters in flash -- I do have an SD card interface if not, but that's a little more work.)

What's amazing about this is that I haven't read any books or tutorials about programming the Arduino and I haven't even looked at the I/O and library commands yet. The syntax looks like a simplified version of C, and I know several variants of that language. Yeah, I've been programming for almost half a century and I've done some PIC programming, but this was a lot easier than I expected. I'm pretty sure I can implement the rest without learning any new commands or syntax, though I'll probably Google around for pressure limit code or something similar.

The coding and testing took less than an hour. I probably spent a couple of hours troubleshooting two issues with the IDE. One was a virtual COM port conflict (my fault, but bad error message on their part) and they had a very old version of the LCD driver library that had issues saving/reading files (pathnames were all wrong.) Had to download and import the latest version. This is the kind of stuff that always takes the most time. The coding part usually goes pretty fast. The hardware assembly was straightforward, but I spent some time building a proto board to use it's connectors and breadboard (for the RC circuit.) Ended up removing and reinstalling headers on the LCD a couple of times, but that had to do with changing my mind about how to stack the boards.

I have to admit, it was fun!

User avatar
Peppersass
Supporter ❤

#12: Post by Peppersass »

AssafL wrote:I assume it is okay to use thinner tubes as throughput (water debit) is low at the group.
Yes, the tubes connecting the HX to the boiler are the smallest diameter in the water path.
AssafL wrote: BTW - I can think of an (easy?) way to somewhat simplify the right hand side of the machine: Full Strada conversion.
1. Autofill: Keep the vane pump. Route it to the steam boiler through a check valve or two. Power for the vane pump should come from the autofill solenoid (or a relay replacing the autofill solenoid) - when it needs to autofill the vane pump will work. Throw autofill solenoid out (or use it to bypass the needle valve).
I think a relay might be better. The logic board uses a larger relay for the motor than for the autofill solenoid, probably to deal with startup current. You wouldn't want the autofill relay contacts fusing...
AssafL wrote: 2. Group pump: Control for the gear pump get the excitation from the group solenoid.
Yes, that's how you'd have to do it.

FWIW, my partially-built GS/3 interface board translates those AC signals into 5VDC with optocouplers to safely connect them to the Arduino.

That said, I don't see the necessity of keeping the rotary pump for autofill. My gear pump works fine for that, and the GS/3 is smart about not autofilling while brewing. Removing it frees up space on the right side of the machine, which I need for my steam valve replacement (though I've recently thought that instead of the electronic valve it might have been better to replace the stupid joystick valve with a valve that has a knob -- perhaps slightly wetter steam but no need for the LWW Steam Dial!)

User avatar
AssafL

#13: Post by AssafL »

Okay - now that you are safely bitten by the bug (healing is impossible) - let me throw some stuff out:

1. Remember you can have as many Arduino sketches as you like. So keep an "operational" or "production" one safe - and another one (or many) for fun.

2. I developed the Quest controller heavily based on the work of Jim Galt - MLG properties - code and many other snippets. There is hardly anything similar (moved the entire code to interrupts) by now. Rewired some of his boards to take advantage of Atmel interrupt lines (can't stand polling).

3. Display everything: boiler pressure, Pump voltage %, etc. Makes for excellent learning and over time, better feeling of how pucks react.

4. There is an excellent PID lib. I set up the Roaster controller to switch between PID (setpoint) and %Power (in pump case - voltage). It cannot be flow, because flow is a result of pressure and power. So you can setup the potentiometer to have two functions: 1. Set boiler pressure (not puck!); 2. Set pump voltage.

5. Using the same opto isolator, you can tap the Gicar pulse sensor. You can use that to give the potentiometer a third control: flow (pulses/minute). You would probably want to PID that loop as well). Display that too... BTW - you can power the Arduino from the Gicar 9V supply and not need an optocoupler. But be careful....

That opens up possibilities: Example: suppose you mostly dose 15-18g doses. Assuming a 1:1 puck liquid absorption, you can infer from the flowmeter, at what point you can start ramping up the pressure. Also, some of the video's Jacob did a while back - seems to me the puck breaks and the automated flow control "pulls it back" to behaving well.

Also - you may be able to use the current feedback wire (yellow) from the motor to detect over pressure - e.g. working against a blind puck you will increase voltage but the voltage on the yellow line will drop as the pressure nears 9-10 bar. The ratio between Vin-Vout is an excellent way to detect runaway scenarios. Also, there are many hall effect sensors (Allegro) that can detect current easily. I used one like that for the versalab (had to calculate TRMS voltage for that) to detect when it finished grinding.

BTW - How long does it take you to fill the steam boiler with the MG204?
Scraping away (slowly) at the tyranny of biases and dogma.

User avatar
Peppersass
Supporter ❤

#14: Post by Peppersass »

AssafL wrote: 3. Display everything: boiler pressure, Pump voltage %, etc. Makes for excellent learning and over time, better feeling of how pucks react.
I'll do the best I can with a 16x2 display. Might end up showing just numbers without titles unless I opt for a larger display.
AssafL wrote: 4. There is an excellent PID lib.
I'll look into it. Still not sure I'll need it, though with the pressure transducer readings jumping around (see below) it might be necessary even for enforcing a rough pressure limit.
AssafL wrote: BTW - you can power the Arduino from the Gicar 9V supply and not need an optocoupler. But be careful....
My preference is separate supplies and optocouplers. Not a big deal if I short the Arduino or support circuits. Very big deal if I short the Gicar. Even with optoisolators there's a tiny chance the IC will short. That's why I like monitoring the AC signals rather than the low voltage signals. That said, I haven't committed to full control of the GS/3 yet -- just the pressure limit.
AssafL wrote: Also, some of the video's Jacob did a while back - seems to me the puck breaks and the automated flow control "pulls it back" to behaving well.
This is a matter of opinion/taste. Jacob must be mimicking the rotary pump, the bypass valve of which ensures constant pressure. Without that, and without software intervention, pressure at the puck decreases slowly as the puck offers less resistance. Essentially, it's a slow ramp-down, just like a lever. I can't recall offhand, but I think the min pressure I see at the end of a shot is maybe 7-8 BAR. There are some who feel this is preferable to maintaining the same pressure throughout the shot. Slayer does it that way. They cap the brew pressure, but they don't hold it there.
AssafL wrote: Also - you may be able to use the current feedback wire (yellow) from the motor to detect over pressure - e.g. working against a blind puck you will increase voltage but the voltage on the yellow line will drop as the pressure nears 9-10 bar.
There's no current feedback wire on the MG204. The yellow wire carries a tachometer pulse from which motor RPM can be calculated. When I first built the system, I used that to implement an RPM counter using a n Auber counter. My interface box is wired to pass the tach signal to the Arduino so it can display RPM, but there's not a lot of useful information in that.

Besides, I've already got the pressure transducer installed and working. Wrote and tested the code today. Here's a crude video:
Still a work in progress. Note the mysterious ~1 BAR pressure jump at the beginning, which you and i have discussed offline. I have some new observations not related to the Arduino project I'll send you via email.

This took a little more thought, though not all that many more lines of code. First I connected my good DMM to the pressure transducer and measured the voltage at 0.5 BAR increments from as close to zero as I could get up to 12 BAR. As expected, the pressure transducer isn't linear. It's not too bad in the middle of the range, but the linearity decreases at the lower and upper ends. So I created a conversion table. The code samples the pressure transducer voltage and interpolates between values in the table. Had to slightly adjust the conversion factor between the A/D count and voltage because it's slightly different than the pot (which is why the count is shown in the lower left next to Pre). The pump output voltage is flickering because there wasn't a pot attached to the input. That comes next.

One issue is that the reading from the pressure transducer jumps around a lot. Some sort of noise. I might need an RC circuit to smooth it. Interestingly, my DMM averages the voltage quite well. Don't know what kind of input filtering it's doing for DC voltage. Will have to research all this. Meanwhile the code compensates by averaging 10 voltage samples before looking up the BAR in the table. Since the loop delay is 10 ms, that means the pressure reading is updated every 100 ms. Seems to react relatively smoothly to changes I make in the pump speed. But as you can see, the reading still bounces around a few tenths of a BAR. Not a huge problem, but I'd like to eliminate it.

A more interesting problem is that the pressure transducer produces different readings than the boiler gauge depending on resistance in the path. I calibrated it to match the boiler gauge at free flow,. But with puck resistance in the path (as simulated with a Scace), the transducer reads about .5 BAR lower than the boiler gauge. With a blind basket in place, the difference is a full 1 BAR. The difference seems constant across the entire range. Not sure why this is happening and which gauge is closer to being correct. Anybody have an explanation?

This may not be a huge problem for the simple task of capping the pressure. I was planning on having different speeds and caps I can select depending on what I'm doing -- free flow, pulling a shot or backflushing. I can take the difference in gauge readings into account when choosing the numbers. I might have to consider recalibrating with the Scace in place so the gauges agree when pulling a shot. Then again, 0.5 BAR isn't much, and with the readings jumping around a few tenths of a BAR there's already some error.

I'm open to suggestions on the instability and different readings depending on resistance. Maybe I need a better transducer? Accuracy is 1.5% of full scale, which is 18 BAR (4.5V), so about a quarter BAR.
AssafL wrote:The ratio between Vin-Vout is an excellent way to detect runaway scenarios.
Again, there's no pump current output. RPM can't tell you about a runaway scenario. You'd need to look at the pressure or the flow rate.
AssafL wrote: BTW - How long does it take you to fill the steam boiler with the MG204?
Good question. I haven't timed it. I don't drain it often, but it does seem to take longer than I'd like. I'm always worried that the level sensor won't function and the boiler will overfill and trip the OPV. Come to think of it, that might not happen with my line pressure down at 1.5-2.0 BAR. Can't wait to get the needle valve in place so I can bring line pressure back up to 3.0 BAR.

Anyway, when I fill the steam boiler the gear pump is set to 9 BAR brew boiler pressure at free flow, which produces a flow rate at the group of about 450-500 ml/min. That's the same free flow rate the stock rotary pump produces when set to 9 BAR. However, when filling the steam boiler there's no gicleur in the path, so the flow rate must be higher. But I'd bet the rotary pump flow rate with no restriction is higher -- maybe a lot higher. That's the magic of the bypass valve. When I remember to do it, I set the gear pump for 12 BAR boiler pressure at free flow, which fills the steam boiler quite a bit faster.

Next time I drain/fill the steam boiler I'll time it. You do the same and we'll know.

User avatar
AssafL

#15: Post by AssafL »

On the Quest I ended up with a 20x4 display (OLED - Very nice display but not recommended due to timing issues). That allows quite a bit more data for display.

An interesting display for this (I think) is the Sparkfun Microview https://www.sparkfun.com/products/12923? which is on sale for less than 20$ for the next 4 days. It is tiny, OLED, has an embedded Uno Arduino, graphics capability and can fit lots of data on a tiny screen. Perhaps possible to record a pressure profile and actually display it?

Pressure jumping about: These sensors are usually Wheatstone style load bridges. Very sensitive. They need good differential amp and stable grounds. Check grounding. (if the DMM reading is stable it is likely you have noise in the Arduino feeding to the gauge). But even a good stable one will jump about somewhat. I often run a buffer to smooth out the readings (FIFO). I don't care about each instantaneous reading - just the average pressure the boiler sees (you tried 10 readings. Perhaps try 50 averages?). AFAIK fluke 189 does not average reading (it does only under MIN MAX mode) - BTW none of my handhelds do; all of my bench multimeters do.

I think Jacob controlled based on flowmeter ticks. Hence his gear pump fluctuated all the time to compensate and keep the flow constant. Very cool idea. As I said, it may be a nice option (flow profile, pressure profile, manual).

Regarding the yellow RPM wire - In theory the yellow line and your input should have the same voltage (set 2v speed in have 2v speed out). But that is without load. If load exists (like free flow water) - voltage will drop as speed will drop. If the puck is sealed (blind puck) - voltage will drop more as pump will crawl... I prefer measuring pressure; but I'd wire the yellow and keep an eye on it as well (as a safety feature should the pressure sensor burn out). Record the Yellow line voltage for a few weeks. Say the minimum you see it is 1.5v. Add a threshold to stop the pump if say - 10 consecutive readings are under 1.4 volts.

Pressure readings part II: If pressure is not your control parameter - you can't assume it is constant (pipes stretching, tiny air bubbles, etc. can all add up). If pressure is the control metric - it should sense stable. As for the difference in reading between pump and boiler: sure. You are reading at the pump. Flowing water will measure less than static water (Bernoulli). Also, there will be lags (pipe stretch, etc.). That is why I would want to measure at the boiler. The boiler is a stabilizing element (a big "capacitor") by storing potential energy in the form of heat and pressure. It therefore makes more sense to measure the pressure there.

Pressure part III: EricS got me to procure a Fluke pressure sensor which hooks up to the bleeding port so I could calibrate the manometer. Mine was completely off... This was due to disagreement with a Scace. So use the Scace to compare. Can you seal it?

The FG100 has the throughput of an MG109 but has the ability to get to 9 Bar. Like a vane pump. But to get to 9 bar you would need an FG204/304 or an MG204/304. The 4mm make the throughput tiny which is why LM use a vane pump to help fill the boiler. The need to drive both steam (high volume/low pressure) and brew (low volume/high pressure) is what makes it either necessary to use two pumps (a-la EP) or to use an expensive pump (FG100). Come to think of it, I'd still need the autofill solenoid (to prevent water ingress as mains will fill it even without the pump working). Since I already have the Vane pump, I may opt for the dual pump solution. Wire the pump motor (using a 220v relay to reduce the current draw for the Gicar relay) in parallel to the autofill solenoid completely separating the hydraulics from the pneumatic circuits.

Edit: Since the Sparkfun Microviews are 19$ I got 2 and a programmer interface. Great price. But even nicer: shipping to Israel was under 5$. World is getting smaller.
Scraping away (slowly) at the tyranny of biases and dogma.

User avatar
AssafL

#16: Post by AssafL »

Just dawned on me - there will no longer be a need for a "preinfusion" step. Here is the thought:

The needle valve is there to reduce flow when it is flow limited. You can have the Arduino operate the needle valve bypass solenoid at - say - 4 bar potentiometer position - once the hydraulic circuit becomes "pressure limited". At which point you don't need any more timers.

Alternatively - you can have the "switchover" happen automatically (not potentiometer related) when flow rate drops.

Assaf

Edited for clarity...
Scraping away (slowly) at the tyranny of biases and dogma.

User avatar
Peppersass
Supporter ❤

#17: Post by Peppersass »

AssafL wrote:An interesting display for this (I think) is the Sparkfun Microview
Cool, but too tiny for my old eyes. No buttons, either.
AssafL wrote:Pressure jumping about:...
Solved this with a running average. Might try an exponential filter, but it's reasonably stable now. Just a little fluctuation in the tenths place.
AssafL wrote: Regarding the yellow RPM wire - In theory the yellow line and your input should have the same voltage (set 2v speed in have 2v speed out).
Again, the yellow wire carries a tachometer signal. It's a 5V p-p square wave, regardless of motor speed. You count the pulses over a set time and compute the frequency. Multiple by (60/32) and you get the RPM. All that is in the MG204 manual. I have the RPM readout working on my Arduino now. The pulse counting is interrupt-driven, of course.

Bottom line, there's no voltage drop, no way to measure motor current except with an ammeter in the 24VDC feed. That's the red wire.
AssafL wrote:That is why I would want to measure at the boiler. The boiler is a stabilizing element (a big "capacitor") by storing potential energy in the form of heat and pressure. It therefore makes more sense to measure the pressure there.
Yes, except the needle valve will be between the pump and the boiler. In order to protect the pump during pre-brew I need to measure pressure at the pump. Maybe two pressure transducers?
AssafL wrote: Pressure part III: EricS got me to procure a Fluke pressure sensor which hooks up to the bleeding port so I could calibrate the manometer. Mine was completely off... This was due to disagreement with a Scace. So use the Scace to compare. Can you seal it?
I'd like some details on the Fluke pressure sensor. Sounds like a good thing to have. That said, I can seal the Scace by replacing the drilled cap on the end with a plain cap. I think my boiler pressure gauge is pretty accurate at brew pressure because the Scace shows the usual 1-1.5 BAR drop across the gicleur. But it would be interesting to check. My Scace setup is a homebrew modification whereby I added a good-quality fluid-filled gauge to the Scace via a cool quick-disconnect fitting. Got the idea here on H-B.

BTW, I have the basic Arduino program done now. I can flip a toggle switch to enable the Arduino or use my old manual pot system. When the Arduino is on, it controls the pump speed. It has two modes: manual and PID. The manual mode just reads the same external pot and converts the voltage to the motor PWM (turns out it works better without an RC circuit, though I didn't try optimizing that.) In PID mode it keeps pressure steady at one of two limits I can select with buttons, currently 10.5 BAR and 12 BAR. This is not a cap. It's a target pressure regardless of flow restriction. Getting that to work is just the first step in implementing various options, like a cap, constant pressure, profiling, etc.

Being entirely new to PID, it took hours to get this to work. At first I tried going off the calculated BAR, but that didn't work. I tried the averaged A/D input from the pressure sensor, but that didn't work, either. Eventually I realized it was because I had tried to implement it as a cap to the pot-driven speed, and that code was interfering with the PID. It worked better after I changed it to be one or the other -- pot-driven or PID driven, but the PID still oscillated too much, regardless of the tuning parameters. Then I tried using the voltage from pressure transducer instead of the A/D count, and that worked a lot better. I finally returned to using the pressure in BAR, and that worked best of all.

It's almost usable. It ramps up at a reasonable rate to the target pressure. When my system has the low pressure phenomenon (i.e., before the mysterious pressure jump), it'll ramp up to 10.5 BAR and stay there. But when the pressure jumps to normal, the PID tends to overshoot to almost 12 BAR, then slowly decays down to 10.5 BAR. In either case, it does hold the pressure at the set point once it gets there. But if I try it against a blind basket, the pressure ramps up too fast, goes over 12 BAR and I have to stop it. I don't know if the PID would eventually bring the pressure down, but I'm not going to run the machine at over 12 BAR to find out!

I'm pretty sure that's also an overshoot problem. Basically, pressure is rising too fast for the PID. I've tried changing the PID parameters (I thought Ki was supposed to be important for controlling overshoot), and also the sample time, but so far haven't found the right settings. I was recompiling to do that, which is tedious, so I just modified the code to let me change Kp, Ki and Kd in 0.1 increments up or down on the fly from the buttons on the LCD display.

FWIW, I'm using Kp=1, Ki=6 and Kd=0.2. Had a lot of trouble with Kd values of 1 and up. Seems like 100 ms is the lowest sample time I can use, with 500 ms being the upper end.

Tricky stuff. Any advice would be appreciated.

User avatar
Peppersass
Supporter ❤

#18: Post by Peppersass »

AssafL wrote:Just dawned on me - there will no longer be a need for a "preinfusion" step. Here is the thought:

The needle valve is there to reduce flow when it is flow limited. You can have the Arduino operate the needle valve bypass solenoid at - say - 4 bar potentiometer position - once the hydraulic circuit becomes "pressure limited". At which point you don't need any more timers.

Alternatively - you can have the "switchover" happen automatically (not potentiometer related) when flow rate drops.

Assaf

Edited for clarity...
Yeah, that would be easy. Once the Arduino sees the pressure start to rise it could open the bypass. But there are many variations. You might want to time it, might want to let the puck "soak" at a low pressure after pre-infusion, etc. The possibilities are endless.

AFAIK, Slayer doesn't do it this way. I think it's timed.

Still pondering whether to hook up the flow meter. Easy to do if I decide to forego circuit isolation. I have a feeling I'm going to end up completing my GS/3 interface board so I can monitor and control everything. It's been on the shelf for ages. I'll have to refresh my memory on all the optocoupler stuff.

User avatar
AssafL

#19: Post by AssafL »

Did you try to run the auto-tuner for the PID?
Scraping away (slowly) at the tyranny of biases and dogma.

User avatar
AssafL

#20: Post by AssafL »

Peppersass wrote:Yeah, that would be easy. Once the Arduino sees the pressure start to rise it could open the bypass. But there are many variations. You might want to time it, might want to let the puck "soak" at a low pressure after pre-infusion, etc. The possibilities are endless.

AFAIK, Slayer doesn't do it this way. I think it's timed.

Still pondering whether to hook up the flow meter. Easy to do if I decide to forego circuit isolation. I have a feeling I'm going to end up completing my GS/3 interface board so I can monitor and control everything. It's been on the shelf for ages. I'll have to refresh my memory on all the optocoupler stuff.
The "decision" that you are in "flow limited" or "pressure limited" mode - is one made by the puck and the water debit. It is not a "timed" event (even if the Slayer or we have a timer for it).

As examples:
A flush is always flow limited (since water flows freely). We measure the water debit because of this.
A cleaning cycle (using a blind basket) - is mostly pressure limited (as the basket is full with a slurry of water and detergent).

The decision to "flow very slowly" or "give the puck a squeeze" - are all on the paddle range. Left most is low pressure restricted debit; rightmost - high pressure high debit.

Even more convincing (to me) is the fact that the other 2 quadrants (low pressure - but high flow & 9 bar with a needle valve) are not quadrants I can find a use for.

So the only question is - at what potentiometer position do I want to open the bypass valve?
Scraping away (slowly) at the tyranny of biases and dogma.