Today, one of my personal goals was realized. I made a small contribution to a large open-source project. The project is the Arduino core for the ESP8266. The ESP8266 is my workhorse microcontroller, but the Arduino core provides a framework to quickly develop software. It contains numerous features that are based on the Arduino platform but adapted for the ESP8266. It also has many features unique to this device. While working on μDAQC, I was trying to store login credentials in a secure way, but the existing Arduino core didn’t have functions that allowed me to do it. Instead of writing my own implementation, I took the plunge, forked (made my own copy of) the repository, and modified the core itself. Once I’d tested the change, I submitted the change as a Pull Request – my very first one. The folks who maintain the project reviewed it. Once I responded to their feedback, it was approved. Today, my fork was merged into the current development branch, and my changes will be a part of the next release. My little bit of code probably won’t be used for it’s intended purpose by too many people, and I seriously doubt it’ll ever actually protect anyone’s information from an intrusion. Still, once the next version is released, it’ll be sitting there on thousands of hard drives, ready if it’s needed. Here is a link to the pull request on GitHub if you’d like to see the details.
The recent modifications to the cabinet warranted a small software upgrade. The power and heat transfer of the two modes are drastically different. The heating side, a SSR-throttled in-line water heater element, can increase the temperature of the fluid much faster than the thermoelectric chips I was using previously. The cooling side, a copper coil sitting inside the refrigerator, is much slower; in fact, it has to slowly cool the fluid reservoir before it even approaches a useful rate of heat transfer from the fermenter. Previously, I’d used a single set of control parameters for both the heating and the cooling side, but the parameters are now too different. I had to rewrite the code to use different PID parameters for each. This is trivial, but rewriting the TCP communication protocols to include the parameter values so that I can change them for the purpose of tuning took a little time. Here’s the current control scheme: This is essentially a dual-loop control configuration with a bit of switching logic included. In simple terms, one controller uses the temperature of the fermenter to determine what temperature the heat exchange fluid should be. The heating and cooling controllers measure the current temperature of the heat exchange fluid, compare it to the desired temperature, and adjust the power output to bring the temperature to the setpoint. A bit of control logic (which actually includes another controller) determines whether the the cabinet should be in heating or cooling mode. This is necessary to keep the cabinet from inappropriately switching between the two modes when the temperature of the fermenter is near setpoint. By “controller” I mean PID. Many brewers are familiar with discrete hardware units that are called PID controllers, but PID control is really just an approach to controlling a measured variable by changing a process output. I wrote a software PID object in C++ based on my father’s Visual Basic implementation (check out his blog to see that I am a small chip off a very large block) that I use in the software for the microcontroller that runs the cabinet. I omitted derivative control, opting only for proportional and integral. As my father would say, derivative control isn’t often that important. An important thing to know about PID controllers is that they have to be tuned. Plainly, this setting how the controller reacts to the error it detects. A well tuned controller will quickly reach setpoint. An overtuned controller will oscillate aggressively about the setpoint. A loosely tuned controller will take forever to get there. An incorrectly tuned controller will blast off in the wrong direction, an undesirable and possibly unsafe scenario. Rigorous controller tuning would require a decent process model. I don’t have even a simple one and don’t care to make one, so I opted for manual tuning. This is an iterative process that involves perturbing the system, watching its response, and adjusting the PID tuning parameters accordingly. Here is the data from the last bit of cooling mode tuning. I decided to get the fluid temperature controller tuned for the cooling