Jump to content
Sign in to follow this  
spirilis

Kitchen Roast! Thermocouple Monitor

Recommended Posts

This is my POTM for Nov-Dec 2013: http://forum.stellarisiti.com/topic/1773-open-43oh-stellarisiti-2013-nov-dec-project-of-the-month/?p=5545

 

This was a low-budget gift for my wife I put together in the last 3 days before christmas.  I chose the Stellaris LaunchPad simply because I had no firm plans for it, and I have two Tiva-C LaunchPads that succeed it.  The application itself would be much better fit for an MSP430 (and could be implemented with battery power too) but alas, it was a good test of my last-minute resourcefulness  :D

 

First, pics!

 

We start with the TI Stellaris LaunchPad.

post-163-1426460534398_thumb.jpg

 

Then home-etch a PCB using the laser toner-transfer process and ferric chloride, with some MG Liquid Tin for a nice tin protective coating:

post-163-14264605344246_thumb.jpg

post-163-14264605344503_thumb.jpg

 

This board features the MAX31855 Thermocouple Amplifier chipset along with a Nordic nRF24L01+ PA+LNA board with external antenna.  The latter is used to report temperatures to my Linux server, which posts them on a webpage every 30 seconds so my wife can view the state of her roast remotely with her iPad.

 

Then add @@bluehash 's first attempt at the Nokia 1202 BoosterPack, unfortunately the LCD on this board had its white backing removed (noob mistake I have not repeated since) so the LCD has a weird background effect to it-

post-163-14264605344753_thumb.jpg

 

Stack them all together:

post-163-14264605345011_thumb.jpg

 

I am not good with woodworking, but I made an exception here and worked hard with a circular saw and dremel out in my garage.  Used boiled linseed oil as a simple coating on the outside of the enclosure, milled out the holes with a drill & dremel...

post-163-14264605345264_thumb.jpg

 

It could definitely use some strain relief for the cord, I'll probably wrap it around the bottom female headers of the Stellaris LaunchPad at some point:

post-163-1426460534581_thumb.jpg

 

Anyway, my wife used it to make fudge and to make a rib roast for Christmas and it turned out perfectly!  This unit is expandable, meaning I can pop the top and replace/re-etch the boosterpacks as I see fit.  If she asks, I may implement more than one MAX31855 and possibly home-etch a Nokia 1202 boosterpack with pushbuttons with some implement to allow her to press them from the top wooden cover.

 

Board files for the custom MAX31855+nRF24L01+ PCB: Thermocouple_BPak40_draft1.zip (DipTrace)

Nokia 1202 boosterpack from 43oh: http://forum.43oh.com/topic/3724-43oh-nokia-1202-lcd-display-boosterpack/

 

Code:

 

Used Energia 11 for this one.  First off, 2 libraries:

Nokia1202 - https://github.com/spirilis/Nokia1202

Enrf24 - https://github.com/spirilis/Enrf24

 

Nokia1202 requires 9-bit SPI, while I have an alternative Energia SPI lib for MSP430, I didn't have one for Stellaris/Tiva-C.

It required one update.  Updated energia-0101E0011/hardware/lm4f/libraries/SPI/SPI.cpp and SPI.h files: SPI_lm4f_9bit.zip

 

Energia sketch:

#include <ste2007.h>
#include <Nokia1202.h>
#include <Enrf24.h>
#include <nRF24L01.h>
#include <SPI.h>


struct MAX31855_DATUM {
  uint32_t rawData;
  int16_t tcDecimalC;
  int16_t tcC;
  int16_t tcF;
  int16_t ambDecimalC;
  int16_t ambC;
  int16_t ambF;
  uint8_t faultBits;
};

void max31855_read(struct MAX31855_DATUM *);

#define TC_CS PA_3
#define nRF24_CE PC_7
#define nRF24_CSN PE_0
#define nRF24_IRQ PD_6
#define LCD_BL PA_4
#define LCD_CS PA_5
#define LCD_RST PA_6
#define RADIO_CHANNEL 10
#define RADIO_ID 20
// 30-seconds between polls
#define WAIT_TIME 30

const uint8_t radio_basestation[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01};

Nokia1202 lcd(LCD_CS);
Enrf24 radio(nRF24_CE, nRF24_CSN, nRF24_IRQ);

void setup()
{
  // put your setup code here, to run once:
  //Serial.setBufferSize(512, 64);
  Serial.begin(115200);

  Serial.println("Init TC CS, SPI-");  
  pinMode(TC_CS, OUTPUT); digitalWrite(TC_CS, HIGH);
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(1);
 
  radio.begin(250000, RADIO_CHANNEL);
  radio.setCRC(true, true);
  radio.setTXaddress(radio_basestation);
  radio.autoAck(false);

  // Manually reset LCD
  Serial.println("Resetting LCD-");
  pinMode(LCD_BL, OUTPUT); digitalWrite(LCD_BL, HIGH);
  pinMode(LCD_RST, OUTPUT); digitalWrite(LCD_RST, LOW);
  delay(250);
  digitalWrite(LCD_RST, HIGH);
  Serial.println("Init LCD-");
  lcd.begin();  // Cursor enabled, contrast at medium, tabstop=4
  lcd.clear();
  Serial.println("Writing splash screen-");
  lcd.print("Kitchen Roast!\nTemp Reporter\n\n");
  lcd.print("From Eric with\nLove \n\n");
  lcd.print("Web address:\nsisko.lan/roast");
  delay(2500);
  Serial.println("LCD splash screen delay complete-");
}

void loop()
{
  uint8_t nrfmsg[32], cursor = 0;
  struct MAX31855_DATUM tc;
  uint32_t lastupdate;

  Serial.println("max31855_read()-");
  max31855_read(&tc);
  // Update display
  Serial.println("LCD update-");
  lcd.clear();
  lcd.println("Kitchen Roast!");
  lcd.setCursor(0,2);
  lcd.print("Temp: "); lcd.print(tc.tcF); lcd.print('\x7f'); lcd.println("F");
  lcd.print("     ("); lcd.print(tc.tcC); lcd.print('\x7f'); lcd.println("C)");

  if (tc.faultBits) {
    lcd.setCursor(0, 7);
    if (tc.faultBits & 0x01)
      lcd.print("DISCON ");
    if (tc.faultBits & 0x06)
      lcd.print("SHORT ");
  }
  lcd.setCursor(0, 6);
  lcd.print("sisko.lan/roast");

  Serial.println("nRF24 radio transmit-");
  nrfmsg[0] = 0x10;  // PROTO = THERMOCOUPLE UPDATE
  nrfmsg[1] = 0x06;
  nrfmsg[2] = RADIO_ID;
  nrfmsg[3] = tc.tcC & 0x00FF;
  nrfmsg[4] = tc.tcC >> 8;
  nrfmsg[5] = tc.ambC & 0x00FF;
  nrfmsg[6] = tc.ambC >> 8;
  nrfmsg[7] = tc.faultBits;
  radio.write(nrfmsg, 8);
  radio.flush();
  
  Serial.print("Waiting "); Serial.print(WAIT_TIME); Serial.println(" seconds before next update-");
  lastupdate = millis();
  while ( (millis() - lastupdate) < 1000*WAIT_TIME ) {
    delay(1000);
    lcd.setCursor(15, cursor);
    cursor ^= 1;
  }
  
}

void max31855_read(struct MAX31855_DATUM *datum)
{
  uint32_t tcread;
  int16_t tmp;
  
  digitalWrite(TC_CS, LOW);
  tcread = SPI.transfer(0) << 24;
  tcread |= SPI.transfer(0) << 16;
  tcread |= SPI.transfer(0) << 8;
  tcread |= SPI.transfer(0);
  digitalWrite(TC_CS, HIGH);
  
  datum->rawData = tcread;
  
  // Thermocouple temp, degrees C and F
  tmp = (tcread & 0xFFFC0000) >> 18;
  if (tmp & 0x2000)
    tmp |= 0xC000;  // sign-extend
  // tmp = TC deg C decimal
  datum->tcDecimalC = tmp;
  datum->tcC = tmp / 4;
  datum->tcF = ((tmp * 9) / 5 + (32*4)) / 4;
  
  // Ambient temp, degrees C and F
  tmp = (tcread & 0x0000FFF0) >> 4;
  if (tmp & 0x0800)
    tmp |= 0xF000;  // sign-extend
  // tmp = Amb deg C decimal
  datum->ambDecimalC = tmp;
  datum->ambC = tmp / 16;
  datum->ambF = ((tmp * 9) / 5 + (32*16)) / 16;
  
  // Fault information
  datum->faultBits = tcread & 0x00000007;
}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...