rpn, I'm using the phidgets i/o board and the dual relay board. Temp data is coming from an Omega HH306 w/K-type through rs232. The PID is a very simple implementation that I found on some web site (which I can no longer find) and converted to C#. The software model is pretty straightforward:
Roaster
^
|
Controller <----> RoastUI ---> RoastLog
'Roaster' encapsulates a simple roaster device/environment, which consists off a heat on/off switch and two readable temperature probes. 'Controller' models the roast process (roast lifetime, profile application, heat settings, things like that). The RoastUI interacts with the Controller to visualize/control the roast process and uses the RoastLog to persist roast info.
I just recently added support for automated profiles. A profile consists of a collection of segments, each of which has a heat setting and a limit. The heat setting can be either a temp-based setting (pid control) or a percent-based setting, controlling how long heat is applied during each 10 second cycle (for example, 70% means: on for 7 seconds, off for 3 seconds). The segment limit can be time-based or temp-based. A time-based segment expires when the segment has been active for the specified amount of time. A temp-based segment expires when the specified temperature is reached. When a segment expires, the next segment in the profile becomes active. I'm still working out the UI interface to an executing profile but, for the moment, there are two ways to interact with an executing profile - a segment can be suspended when a manual heat setting is chosen (which allows you to effectively extend a segment); and the remainder of a segment can be skipped (which allows you to shorten a segment). This interface is about to get reworked this weekend though, after a little 'double click mishap' caused me to accidently stop a roast of Joe's Harrah 1:13 into C1 last night... doh!