Additionally, the set value for the boiler temperature is calculated using separate model that takes the group head temperature into the account.
The end result is that the controller is able to stabilize immediately, with maximum power of the heater and with no overshoots or undershoots to a temperature that takes into the account the state of group head to provide the ideal water when brewing.
While PID is able to control the temperature very accurately I found even in best case it took additional 50% of the time to stabilize and also it was difficult to optimally use 100% power of the heater until last possible moment.
Being able to achieve stability almost immediately means I can keep lower water temperature in the boiler and bring it to temperature at the last possible moment. End result being that it is now much faster to get it ready.
The avoidance of overshoot when using a PID, especially for temperature control of any kind of thermal mass, can be achieved quite satisfactorily by using the posicast technique of setpoint control.
From my experience it is often observed in large processing plants that the operators have learned to do this instinctively from the standard faceplate.
My controller and implementation is currently proof of concept stage.
I have slapped together few components to create a working prototype, STM32 Nucleo board with STM32L452 MCU, Texas Instruments development board with Bluetooth 5, some RTD temperature measurement development boards from MaximIntegrated, a bunch of relays, current sensors, water
flow sensor from Digmesa (actually replacement part from one of Saeco machines), etc.
I am using a test board to detect existing espresso machine operation and perform readings using multichannel laboratory thermometer that measures external boiler case temperature, group head temperature, brewing water temperature (inside portafilter), tank water temperature and external temperature along with signals (when the brewing starts, stops, etc.) to provide experimental data to build the model.
I am using Matlab and Simulink to help me generate parts of the software using gathered experimental data. This lets me play with models and observe how it could behave without actually brewing any coffee:)
Predictors are often too hard in practice, but in this case seems simple as looks like you have the parameters you need to calculate the required energy as Q=ml (+losses) and just put exactly that amount of electrical joules into the heating element.
"Tune" factors like thermal losses by hand, and/or have a simple heuristic learning algo that tunes factors for you based on previous result errors.
I am assuming you have the level in the tank as well to calculate volume, as how else do you protect the boiler element from coming on when no water in the tank?
Predictor calculates future evolution of the system based on current state and system parameters. The horizon changes dynamically and typically is about 5 seconds when in steady state and up multiple minutes when cooling from steaming to brewing temperature (depends heavily on insulation, steaming temperature, how long it was steamed, etc.)
The parameters are not directly physical values like thermal mass or energy but are related to them. For example, I am calculating the amount of energy lost based on water temperature and outside temperature (outside is inside enclosure). This is in units used to drive the heater (the unit is half-cycle of AC power). I am calculating (predicting) cooling of water when it is pumped based on amount of water pumped and temperature of water in the tank (this is also being measured).
I calculate initial values based on step responses and then use moving horizon estimator to continually test past predictions vs actual readings and adjust parameters to match.
I haven't yet analyzed which parameters are truly important and which can be easily compensated for without having to sense them.
As to the level of water in the I could not find suitable sensor so I built one. It can only give low level alarm (water falling below set level). It is a plastic pipe with floating magnet attach to the inside of the tank. On the outside, not mounted to the tank so that I can freely remove the tank, but pressed with a flat spring are two reed switches. Using those reed switches I can detect when water falls when its being used or when it rises when it is replenished.
I am using Rancilio Silvia. It is well built machine but has absolutely no electronics and it is easy to disassemble and plenty of free space internally which makes it perfect for experimentation.
My research of mods that are described on the Internet shows that most people put some kind of existing PID controller, SSR to control the heating element and a temperature probe which gets mounted on the outside of the boiler.
Minority is using Raspberry Pi, Arduino or some other kind of existing microcontroller board to allow for nice display and more functionality.
Few people are doing completely custom boards which is what I am doing for this project. I am currently learning electronics after almost 20 years in software and I find it very good exercise from design perspective.
Additionally, the set value for the boiler temperature is calculated using separate model that takes the group head temperature into the account.
The end result is that the controller is able to stabilize immediately, with maximum power of the heater and with no overshoots or undershoots to a temperature that takes into the account the state of group head to provide the ideal water when brewing.
While PID is able to control the temperature very accurately I found even in best case it took additional 50% of the time to stabilize and also it was difficult to optimally use 100% power of the heater until last possible moment.
Being able to achieve stability almost immediately means I can keep lower water temperature in the boiler and bring it to temperature at the last possible moment. End result being that it is now much faster to get it ready.