Shop OBEX P1 Docs P2 Docs Learn Events
SX Coffee Roaster — Parallax Forums

SX Coffee Roaster

DunnseptDunnsept Posts: 115
edited 2006-04-13 05:23 in General Discussion
I am getting started on my project (finally).
I am going to use an SX to control my coffee roaster. should be fairly simple. My coffee roaster is actually a hot-air popcorn popper.
I will use the SX to control the heater element while the fan is allowed to just run.
OK, so I have a basic flow chart and times & temps and I started putting together a skeleton bit of code (I'm waiting on the MAX6675 thermocouple amp)
soooo,.....I'm trying to decide if I want to use interrupts on this or not, and if so, which portion to put in the ISR.

my first thought is to put the 'measure the temp' portion in along with the timing.. but I'm not sure if it will really matter one way or another..
basic run is as follows:

energize heater, until temp = 350
hold·3 mins
raise temp to 410
hold 2 mins
raise temp to 440
hold 1.5 mins or until "operator" hits the "stop" button to end cycle early

thoughts? I have a dallas 1602 RTCC/elapsed time if I need it. I dont need any really fancy stuff to begin, meaning·times and temps actually dont have to be really exact since each batch of beans will be different anyway. One of the biggest problems is trying to measure the beans' temperature ( coffee beans, not HITT beans) instead of measuring the air that is flowing thru the 'roaster'. generally the air temp is measured as it exits the chamber just above the surface of the beans and this is accepted·practice and is about the best you can do considering that the beans are moving around like crazy. I'll be using thermocouple & the max6675 for this (provided I dont fry the 6675 SOIC trying to solder it in place... matter of fact, maybe I'd better order a couple extra)
so... just in a plain ol loop with delays in it?
ISR for "polling" the max6675 as things move along
ISR polling temp AND tracking time either internally or thru the 1602?

thanks
Paul...

Comments

  • PJMontyPJMonty Posts: 983
    edited 2006-04-10 02:36
    Paul,

    I would use the interrupt to create a clock of some sort. I have done this in other projects where the interrupt fires at regular intervals, and the interrupt handler updates a counter. When the counter reaches some logical value (e.g. the # of interrupts = .1 second), then it updates another counter that the rest of the code can use.

    The main code sits in a loop and polls the .1 second counter (or 1 second counter, or whatever time interval you choose) and when enough time has gone by, it jumps to a subroutine that handles something it has to do. This way, your main code creates a collection of time durations (x amount of time between temperature polls, y amount of time between fan adjustments, etc), and the main polling code simply keeps track of the amount of time that has elapsed and whether it has crossed the threshold for one of the events. If so, it jumps to the appropriate sub-routine. If not, then it keeps polling.

    The advantage to this approach is that when you think of another feature to add, all you do is create another timer threshold variable and add it to the collection you keep comparing against the time. It also lets you easily fine tune the granularity of events so that if you discover a certain event needs to happen more often, you just change a single constant in your code, re-assemble or compile, and then start the project running again.

    If you create a series of delays, then everything becomes dependent on everything else. If you decide to have some event happen more often, shortening that one delay means that all the delays that come after it need to be adjusted to keep the total time constant. Delays are a serial process, meaning that until one completes, the next can't start. By using a constant timer and polling that, you are in essence creating a mini multi-tasker.
      Thanks, PeterM
  • DunnseptDunnsept Posts: 115
    edited 2006-04-10 12:35
    PeterM...
    thanks... so, I could have the ISR adjust a timer "CheckTemp" and then in main, check "CheckTemp" and when mod 2 =0, gosub to check the temp. Then have the ISR set another one "profileTemp" updated every 1 sec, then in the main loop have it check for the 2 minutes or 3 minutes or whatever I want for that temp, and then when reached, ramp to next temp...

    works for me!
    thanks!

    ..well. maybe I shouldn't say "works for me!" until I have it working...

    how bout· "thanks for the input!"
  • PJMontyPJMonty Posts: 983
    edited 2006-04-11 16:01
    Paul,

    Sounds like you understood my intent. In some of my projects I have set up a high and low resolution timer so that different tasks could check a timer that had a granularity more suited to them. It's no big deal to have the interrupt handler update more than one timer, so you might have a .1 second timer and a 1 second timer, or you might want a 1 second and a 1 minute, or however many seem appropriate.

    By using a timer that's scales well to your event, then you can have a simple variable for each event in the main loop. What you do is read the current timer, and then add the number of units to it that will equal your next desired event trigger. For example, say you have a timer in the interrupt called "SecondsTimer" which is updated every second by the interrupt code. Let's also say you have an event that checks the temperature that you want to go off every five seconds. You create a variable (such as "NextTempCheck") which will be used to monitor when to check the temperature next.

    Make sure you clear all the memory space when your program starts up. In your main loop, take the current value of "SecondsTimer" and add 5 to it. If "SecondsTimer" happened to equal 2 at that moment, then "NextTempCheck" now equals 7. In your main loop, you constantly check if "SecondsTimer" equals "NextTempCheck". When the "SecondsTimer" finally hits 7, your condition will be met, and you go call the sub-routine to check the temperature.

    When you return, you take the current value of "SecondsTimer" and add 5 to it again, and this will now automatically calculate when your next service should take place. Conversely, you could calculate that before calling the sub-routine if you don't want the sub-routine time to factored into the next trigger time. By calculating a difference between the current time and the next trigger and then waiting until the timer hits that new value, you can easily change the time duration of your events by changing a simple constant in your code.

    I highly recommend using timers and timing intervals that can be managed in a single byte. You don't want to create race conditions where the main loop is checking the first of two bytes, the interrupt goes off and updates one of the two bytes, and then the returns control to the main code. the main won't know it got interrupted between checking bytes of the tier and could come to the wrong conclusion.

    Another advantage to single byte timers and durations is that you can add a constant to it forever, and the CPU will automatically handle the rollover conditions for you. In other words, when the timer is at 252 and you add 5 to it, the answer will be 1. Since the timer just keeps rolling over as well, everything works out perfectly. Just be careful that no sub-routine takes longer to service than the shortest event you have or you could have other issues like missing an event completely until the next rollover.

    Probably more than you wanted to know, but there you have it.
      Thanks, PeterM
  • DunnseptDunnsept Posts: 115
    edited 2006-04-11 17:20
    PeterM,

    nope, that's not more than I wanted to know.. Thanks.

    I have just setup a sort of KISS prototype. Instead of measuring temps and controlling SSRs, I am using buttons and LEDs. After Jon Williams and Bean knocked some sense into me (see the post about SX/B toggle) I have it working just fine.

    now all I have to do is order the MAX6675 from someplace like SparkFun along with an SOIC-DIP adapter and I can start working on the real thing. I will have to figure out handling WORD data in two BYTE vars at that point too, but can't wait to really get started on this
    (I have a few SSRs and PIDS and tons of thermocouple wire already, anybody need some?)

    My wife knocked my popcorn popper off the table, so I dont even have to worry about opening up the housing anymore, it's cracked to pieces.
    Once I have it working, Coffee tasting at my house!
    (next project after that is my beer brewing system, dont know if that one will be an open invitation or not wink.gif
  • PJMontyPJMonty Posts: 983
    edited 2006-04-13 05:23
    Paul,

    Just wanted to mention that having a straightforward but practical project (such as your coffee roaster) to work on will teach you more about programming and working with the SX than all the tutorials and "toy" projects in the world. I can't tell you the number of times I see folks who have never written a line of code in their lives who want to start off making some "blue tooth enabled, ethernet accessible, real time servo controller" or some other equally titanic project. These sorts of things always lead to tears and recrimination.

    Good move on your behalf.
      Thanks, PeterM
Sign In or Register to comment.