Arduino Smoker


16
Jan 10

Update: code complete, contest missed, one bug remains

Well, with the holiday season sweeping through and busyness at work, we missed the deadline to submit our smoker to the ArduinoFun guys.  That is a bummer, but the contest did motivate us this far and we’re close enough to finishing that the momentum should carry us.

Over the holidays, Josh was able to finish the smoker control code and get the smoker fully assembled.  He ran into a physical bug in that the temperature sensor never registered anything above 185 degrees even though the inside temperature of the trash can got up to 230.  We think this is due to the placement of the sensor, which is just inside the can on one side.  We’re going to try putting the sensor on a rod of some sort so that it sticks out into the center of the can.  We’ll need to add a shield to prevent the sensor from getting dirtied with drippings from the meat, but that should be easy enough.

We’ll update the blog when we cook our first meal with the smoker.

And, as before the code for running the arduino and controlling it from the laptop are available in either of our git repositories.


21
Dec 09

It’s alive!

The arduino powered hotplate is actually working, end-to-end. We simply need to connect the temperature sensor back up, write a bit of software, and it’s food time!


14
Dec 09

Smoker code repository and something more interesting with ProtoThreads

Last week, I started work on a code repository for our smoker.

It’s available on github under my profile: http://github.com/justone/arduino-smoker.  We may find a more official place for it, but it’ll always be available there.

There are two directories in the root, one for the Arduino code that will power the smoker and one for the code that we’ll use to control it.  The Arduino directory also contains the two libraries our code depends on: ProtoThreads and the PID library.

The initial Arduino sketch implements a simple LED blinker that can be controlled over the serial connection.  It starts off blinking the led every second and you can set the delay by sending a setDelay command (like “setDelay 4″).  It also reports the current delay every ten seconds.  It’s not much, but it does demonstrate using ProtoThreads to handle more than one process at a time.  It also implements serial command parsing, with heavy inspiration (and code) from this todbot post.

Next up, more hardware assembly and integrating the PID library.


5
Dec 09

Arduino Threading (problem solved)

After building up another sketch from scratch, I found the source of the problem from the last post.  Those sketches stored milliseconds in an int, and that just isn’t big enough.

So this:

// state for the led1 function
static int led1Millis;
static int led1State = LOW;

// state for the led2 function
static int led2Millis;
static int led2State = LOW;

Becomes this:

// state for the led1 function
static long led1Millis;
static int led1State = LOW;

// state for the led2 function
static long led2Millis;
static int led2State = LOW;

Now both versions work flawlessly. Now to make it do something interesting…


5
Dec 09

Arduino Threading

The smoker needs to handle quite a bit at a time:

  1. Reading the temperature and updating the PID.
  2. Reading commands from the laptop.
  3. Sending periodic status updates to the laptop.
  4. Flipping the hotplate on and off.
  5. Whatever else we can think of.

So, to make handling all this a little easier, I began writing a little pseudo-threading library (called Polyester) when Josh pointed me at ProtoThreads.  It’s a stackless threading library built for low memory devices, and someone was nice enough to package it in an Arduino library.

I took a crack at making a simple sketch that blinked two LEDs at different intervals to see how the library works.  Here’s what I came up with:

// Blink 2 LEDs, one every second and the other every other second.

// include ProtoThreads
// Originally from: http://www.sics.se/~adam/pt/
// Arduino package: http://arduino.cc/pipermail/developers_arduino.cc/2009-January/000456.html
#include <pt.h>

// LED pins
const int led1Pin =  13;
const int led2Pin =  12;

// state for the led1 function
static int led1Millis;
static int led1State = LOW;

// state for the led2 function
static int led2Millis;
static int led2State = LOW;

// ProtoThreads structures for each function
static struct pt pt1, pt2;

// function to blink led 1 on and off every second
static int led1 (struct pt *pt) {
 PT_BEGIN(pt);

 while(1) {
 led1Millis = millis() + 1000;
 PT_WAIT_UNTIL(pt, led1Millis < millis());

 if (led1State == LOW)
 led1State = HIGH;
 else
 led1State = LOW;

 digitalWrite(led1Pin, led1State);
 }

 PT_END(pt);
}

// function to blink led 2 on and off every other second
// basically the above method with s/1/2/g
static int led2 (struct pt *pt) {
 PT_BEGIN(pt);

 while(1) {
 led2Millis = millis() + 2000;
 PT_WAIT_UNTIL(pt, led2Millis < millis());

 if (led2State == LOW)
 led2State = HIGH;
 else
 led2State = LOW;

 digitalWrite(led2Pin, led2State);
 }

 PT_END(pt);
}

// Arduino setup
void setup()
{
 // we're using the pins for output
 pinMode(led1Pin, OUTPUT);
 pinMode(led2Pin, OUTPUT);

 // initialize the ProtoThreads varables
 PT_INIT(&pt1);
 PT_INIT(&pt2);
}

// Arduino loop
void loop() {

 // call each function continuously
 led1(&pt1);
 led2(&pt2);
}

While this code seemed to work just fine, after about 30 seconds, the LEDs stop blinking.  The first version of the code printed to the serial monitor, and I noticed that closing and opening the serial monitor kicked my Arduino enough that it worked for another 30 seconds.  However, removing the serial code didn’t change this behavior. Neither did running the Arduino off of the wall wart (with no USB cable attached).

After poring over the code for a bit, I rewrote it to not use ProtoThreads, to eliminate the library as the source of the problem:

// Blink 2 LEDs, one every second and the other every other second.

// LED pins
const int led1Pin =  13;
const int led2Pin =  12;

// state for the led1 function
static int led1Millis;
static int led1State = LOW;

// state for the led2 function
static int led2Millis;
static int led2State = LOW;

// function to blink led 1 on and off every second
static void led1 () {
  if (led1Millis > millis()) {
    return;
  }
  led1Millis = millis() + 1000;

  if (led1State == LOW)
    led1State = HIGH;
  else
    led1State = LOW;

  digitalWrite(led1Pin, led1State);
}

// function to blink led 2 on and off every other second
// basically the above method with s/1/2/g
static void led2 () {
  if (led2Millis > millis()) {
    return;
  }
  led2Millis = millis() + 2000;

  if (led2State == LOW)
    led2State = HIGH;
  else
    led2State = LOW;

  digitalWrite(led2Pin, led2State);
}

// Arduino setup
void setup()
{
  // we're using the pins for output
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
}

// Arduino loop
void loop() {

  // call each function continuously
  led1();
  led2();
}

However, the problem didn’t go away.  It still freezes after about 30 seconds.  At this point, I was concerned that it may be a hardware issue.

So I loaded both blink sketches from the Arduino tutorial site and let them run for a while.  Thankfully, after several minutes, there were no freezes.

Time to do a little debugging.


4
Dec 09

12/04 Status update: XBee Communication

Our forward progress on the smoker project has been a little slower than we were hoping, but we’re back on it now and have all the parts assembled to make it happen!

Today we got the critical wireless communications between the Arduino and the Mac up and running:

Here’s the perl code for the Mac side:

#!/usr/bin/perl

use warnings;
use strict;
use Device::SerialPort;

$|++;

my $port = init_serial();

my $lines = 0;
while(1) {
    my $str = $port->lookfor();
    next unless $str;
    print "$str\n";
    $lines++;
    if($lines > 5) {
        $port->write("Got 5\n");
        $lines = 0;
    }
}

sub init_serial {
    my @devs = qw(/dev/tty.usbserial-FTELR4YH /dev/tty.usbserial-A7006SAd);

    my $port = undef;
    for my $port_dev (@devs) {
        $port = Device::SerialPort->new($port_dev);
        last if $port;
    }
    if(!$port) {
        die "No known devices found to connect to serial: $!\n";
    }

    $port->databits(8);
    $port->baudrate(9600);
    $port->parity("none");
    $port->stopbits(1);

    return $port;
}

And here’s the very simple Arduino code to exercise it:

void setup() {
  Serial.begin(9600);
}

int quiet_count = 0;
void loop()
{
  if(quiet_count > 10) {
    Serial.println("ALIVE");
    quiet_count = 0;
  }
  else {
    quiet_count++;
  }
  // otherwise echo anything else sent to us
  while(Serial.available()) {
    Serial.print((char)Serial.read());
  }
  delay(100);
}

Nate will post in a bit about his threading work.

Next up is getting the Arduino-controlled power outlet built, which is the scariest portion of this project — playing with high current, high voltage AC is always fun, with a side order of adrenaline.


9
Nov 09

Arduino Smoker: a contender in the Arduino Fun contest

A few days ago, ArduinoFun posted information about a contest they are running over the next couple months.

What perfect motivation to kick our first real project into high gear. Or maybe just into gear.

Our project is an electronically controlled smoker.  The basic idea comes from Alton Brown, whose method is described in this instructable. We are augmenting this project with an Arduino so that, at the very least, we can control the temperature.

To that end, after collecting many parts, we started down the road of implementation. I assembled the XBee Adapter Kit that will be used to control the smoker from a laptop, and Josh got the AD595 functioning.

Pictures

xbee_adapter

The completed XBee adapter next to a new kit.

AD595 breadboarded with the Arduino and Type-K Thermocouple
The AD595 Thermocouple, breadboarded up for testing.

AD595_reading

The AD595 reading the temperature of the room.

Here are some of our suppliers and the subcomponents we’ll be using:

  • XBees and XBee adaptors, for setting the temperature and data gathering (from a nearby computer): Adafruit. (We also got our Arduinos from the always awesome ladyada.)
  • The relay used to control the hot plate itself will be based on this design from SparkFun.
  • The AD595 thermocouple amplifier and the Thermocouple also came from SparkFun.
  • Even through we want to smoke a lot more than turkeys, we were certainly inspired by the TurkeyTracker folks. (Who you can now follow on twitter at @turkeytracker!)
  • For actually deciding when to trigger the hot plate off and on, we’ll be using the Arduino PID Library. More detail on that as we get closer to showtime.