Install the code base for the stripboard Arduino PID shield and get started using it as a standalone temperature controller.
DIY PID Controller Firmware
This is the second of a series of posts about the stripboard PID shield:
The Arduino firmware is a variant of the original osPID code, written by Brett Beauregard and revamped by Benjamin K. Stuhl. The code has been adapted to reflect the new hardware and extended and updated in all sorts of ways.
Uploading The Firmware
Download the firmware by cloning the Github repository and load osPID_Firmware.ino into the Arduino IDE. The firmware can then be compiled and uploaded in the usual way.
The new code only just fits in 32 kB so you might need to switch to a shorter bootloader like optiboot to fit it on an Arduino Uno. The various versions of the Arduino IDE may compile the code to different lengths. Just in case this is a problem, there is a version of the code precompiled for the Atmega328P that can be uploaded directly with avrdude.
Please note that the shield was tested on an Arduino Uno R3. Reports using other Arduino boards would very much appreciated. The shield should work just fine on the Arduino Mega but there may be some firmware glitches, so please let us know! The firmware will need to be shortened by several kB to fit on an Arduino Leonardo, which has longer bootloader: see the compilation options below for some suggestions. Feel free to fork the firmware on Github and share your versions with the OSH community.
On start up the PID controller shows a banner with the controller name and version number.
The next thing that you see is a scrollable list of menus, starting with Dashboard, Tuning, Config and the name of the current Profile. The dashboard is displays the set value and measured temperature and is what you usually want in view when the apparatus is running. The configuration menu sets the options that allow flexible use of the controller.
Clicking OK to enter the dashboard menu displays the set value Sv and input reading Pv (for "process value"), just as you would typically see on the panel of a normal PID controller. Scrolling down shows the output duty cycle Out expressed as a percentage, and a setting that toggles between Manual Control and PID Control of the output.
The set value can be edited by pressing OK. The prompt will change from ">" to "→" indicating that the value is being edited. The value can be altered one digit at a time, as indicated by the cursor, by pressing Up and Down. Press OK to edit the next digit or Return to edit the previous digit. To finish editing press OK or Return until the cursor is back to ">".
The set value can be swapped between 4 different temperatures by pressing and holding OK until you see a 2x2 menu of 4 items, Sv1 (the default) through Sv4. These are initially preset to different values but after selection each can be edited as above.
Scrolling down to the input value Pv you will see the prompt "|" which indicates that the value cannot be edited.
The output value O can be manually set between 0 and 100%, provided that the final menu item is set to Manual Control. Manual control can be used, for example, to boil wort when the power percentage sets the vigor of the boil. PID Control is the other option, and is useful when you want to reach and hold a specified temperature (the set value).
The Alarm sets limits for the input temperature. When the bounds are exceeded an loud chirp sounds intermittently and the prompt flashes "!" to alert the user. The alarm menu has four settings: Alarm Enabled / Disabled, low temperature limit Min, upper temperature limit Max, and Auto / Manual Reset. Under Auto Reset, the alarm will automatically turn off when the temperature falls back within the specified temperature limits. If Manual Reset is selected, the alarm must be turned off either manually by navigating to set point in the dashboard menu and pressing OK. (It can also be reset by a command over a serial link: serial communication with the controller is covered in the next post).
Clicking Return sends you back from the dashboard to the main menu.
The first three menu options are P, I, and D and set the proportional, integral, and derivative gains, respectively. Tuning a PID controller manually requires some skill and can be time consuming. A relatively easy method to auto tune the settings initially until the performance seems reasonable, and tweak the settings from there.
The next item selects between Direct Action and Reverse Action, and governs the sign of the gain. Reverse action is useful when heating, direct action when cooling.
The final item on the main menu turns on auto tuning (as indicated by a flashing "T" cursor) or cancels the auto tuner if it is already running. By default the auto tuner uses a relay method to calculate PI tunings based on the Ziegler-Nichols rule, but other options are available. The defaults can be changed as compile options in the firmware, or by using the serial interface (see details in next post). For lag-dominated processes, a PID tuning (with non-zero derivative term) is a good choice.
Next, onto the Config menu. (We will deal with Profile settings in the next post.)
Sensor selects between three measurement options: Thermistor, DS18B20+, and Thermocouple. The default thermistor is a 10 KΩ NTC thermistor with 10 KΩ reference resistor. The recommended 1-wire sensor is DS18B20+, which is accurate to 0.5 °C across its range.
The next option sets the calibration value Cal, a temperature offset for the selected sensor. A different value can be applied to each of the three types of sensor.
The next option sets the output cycle period Cyc. The default of 5 seconds is fine when a resistive heating element is being controlled by an SSR. Electromechanical relays will eventually fail after many operations, so a longer cycle period may be desired if driving a relay of this kind. Certain kinds of load do not tolerate fast switching, such as refrigerator compressors which should be set to a cycle length no shorter than 10 minutes (600 seconds).
The Power On menu switches between 3 kinds of behavior when restarting from power down. Disable resumes in manual mode. Continue carries on running the controller using the set point that was in use before power down. Resume Profile restarts the current profile from the point at which it was previously running.
The final item Reset Memory wipes the EEPROM of all stored information and restores the default settings. This is a useful option after switching between Celsius and Fahrenheit units using the compile options (see below).
Further configuration options are available as compile options, intended to be chosen when setting up the controller and changed only infrequently. These options can be manually edited in ospConfig.h.
The controller name and version tag are included here, should you wish to display different values on start up. The pin assignments are also defined here, can can be changed if you have altered the hardware of the PID shield in some way.
#define UNITS_FAHRENHEIT sets the input sensor units to Fahrenheit. After changing between Fahrenheit and Celsius, the controller will reset the memory to clear the values in the old units.
#define SILENCE_BUZZER makes the PID quiet. You will still get a visual prompt of the alarm signal.
#define USE_SIMULATOR generates input values from a simple simulation model and may be useful when debugging. (Try an LED across the terminals of the 2-pin output block as a visual indication of the output duty cycle).
#define ATMEGA_32kB_FLASH is the option to choose if you use an Arduino such as the Uno with 32 kB of flash memory. Undefining this option restores a couple of serial commands and debugging utilities, which might be handy if you are using something with more memory like an Arduino Mega.
#define STANDALONE_CONTROLLER disables the serial communication while retaining all the features of a standalone PID controller.
The default auto tune settings and thermistor values — nominal and reference resistance, etc — can also be edited the PID_Engine.h file.
Standalone PID Controller
This sous vide set up is made from an Arduino Uno with stripboard PID shield and an electric kettle plugged into a solid state relay module built previously. The Arduino is powered by a wall-mounted USB adapter.
This poached fish supper was thrown together from fillet of arctic char with lemon juice, salt, peppercorns, sliced shallot, and splash of vermouth. (The sprig of parsley was strictly for the photographs.) Sealed up in a ziploc sandwich bag, it went in the kettle for 30 minutes at 51 °C. For the record, I used a PI tuning with P = 3 and I = 0.005.
Everything you need to know about sous vide cooking you can find out from Douglas Baldwin.
Sometimes the resistor values used for the analogue buttons are not close to their specified values. If the buttons seem unreliable, try fiddling with the preset values in ospConfig.h, or swap the resistors out.