Wiblocks --- PICO1TRC HALL EFFECT DEMO

PICOBEE Thermocouple Interface Example

The PICOBEE features the hardware of the PICO1TRC and adds a ZigBee radio (XBee). The wiblocks TWI library and wiblocks RTC library are compatible with the PICOBEE

The schematic on the right shows how to connect a thermocouple to the PICOBEE using a MAX31885KASA thermocouple interface IC. The circuit shown was connected to the PICOBEE using the wire-wrap pins on the bottom of the board.

Description

The MAX31885KASA is a thermocouple-to-digital converter that outputs a digital value proportional to the temperature. The IC features cold-junction compensation and is compensated for K-type thermocouples.

The MAX31885KASA is a 3.3V device that connects to the PICOBEE SPI port. The connections are listed in the table below. Since the IC is an output-only device only three digital lines are required -- MISO, SCLK and /CS.

Pin FunctionPin Number
MISO18
SCK19
PB216
3V37
GND8






Sketch

#include <avr/interrupt.h>    
#include <avr/io.h>  

#include <LED_debug.h>
#include <TWI.h>
#include <RTC.h>

#define DEBUG 1

// PCI2 triggers for PCINT23..16
// PCI1 triggers for PCINT14..8
// PCI0 triggers for PCINT7..0 

#define int_enable   PCICR  |=  (1 << PCIE1)
#define int_disable  PCICR  &= ~(1 << PCIE1)

// Atmel         RTC           Aduino Pin
// ------------  ------------  ----------
// PC3  PCINT11  INTA, ALARM1  17 
// PC0  PCINT8   INTB, ALARM2  14

#define RTC_ALARM1_OUTPUT 17 // PC3
#define RTC_ALARM1_INT    PCINT11

#define TC_CS     PB2
#define UC_MOSI   PB3
#define UC_MISO   PB4
#define UC_SCK    PB5

#define tc_select   PORTB &= ~(1<<TC_CS)
#define tc_deselect PORTB |=  (1<<TC_CS)


LED_debug led;
RTC       rtc;

unsigned char alarm_flag = 0;
unsigned char intdata = 0;

#if 0
#define XB_DESTINATION_ADDRESS "ATDH0, DL1234\r"
#define XB_MY_ADDRESS          "ATMY5678\r"
#else
#define XB_DESTINATION_ADDRESS "ATDH0, DL5678\r"
#define XB_MY_ADDRESS          "ATMY1234\r"
#endif

#define XB_PAN_ID              "ATID1111\r"
#define XB_DATA_MODE           "ATCN\r"
#define XB_CMD_MODE            "+++"

uint8_t ready_p = 0;

void setup() {

  PORTB |= (1<<TC_CS);
  DDRB  |= (1<<UC_MOSI) | (0<<UC_MISO) | (1<<UC_SCK) | (1<<TC_CS);
  DDRD  |= (1<<PD7);

  SPCR = (0<<SPIE) | (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (0<<CPOL);
  SPSR = (1<<SPI2X);

  Serial.begin(9600); 
  led.blink(3);
  xbee_init();
  led.blink(3);

  // setup the TWI 

  TWBR = TWI_TWBR;             // Set bit rate register (Baudrate). Defined in TWI.h  
  TWDR = 0xFF;                 // Default content = SDA released.
  TWCR = (1<<TWEN)|            // Enable TWI-interface and release TWI pins.
         (0<<TWIE)|(0<<TWINT)| // Disable Interupt.
         (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|  // No Signal requests.
         (0<<TWWC);

  // enable pullup on alarm1 output

  pinMode(RTC_ALARM1_OUTPUT, INPUT);
  digitalWrite(RTC_ALARM1_OUTPUT, HIGH);

  // uncomment the set_date and set_time commands to set initial date
  // and time.  This is only required immediately after the battery is
  // installed.

  // initialize the date
  // rtc.set_date(2011, 4, 16);

  // intialize the clock
  // rtc.set_time(15, 06, 20);

  // Initialize the control register for a 32768Hz square wave
  // and disable the square wave output

  // RTC_RS2 | RTC_RS1 ..... Rate Select, square wave output = 32768Hz
  // RTC_INTCN ............. Interrupt Control (=1 interrupts activated,
  //                         no square wave on INTB

  rtc.write_reg(RTC_REG_CONTROL, RTC_RS2 | RTC_RS1 | RTC_INTCN);

  // Setup ALARM1 to alarm when the seconds count equals 10
  // and then enable the ALARM1

  // RTC_ALARM1_MODE2 ..... Alarm when seconds match
  // dow .................. 0
  // hours ................ 0
  // minutes .............. 0
  // seconds .............. 10
  
  rtc.set_alarm1(RTC_ALARM1_MODE2, 0, 0, 0, 10);
  rtc.enable_alarm1();

  // Initialize the pin change interrupt mask for the
  //  pin that is connected to the RTC /INTA output. 

  PCMSK1 |= (1 << RTC_ALARM1_INT);

  // Enable the pin change interrupts

  int_enable;

}

unsigned char state = 0;

void loop() {
  char timestr[22];
  while(1) {
    rtc.read_regs();
    rtc.localtime(timestr);
#if DEBUG  
    Serial.print(timestr);
    Serial.print(" | ");
    Serial.print(temp_read(), 1);
    Serial.print("\r");
#else 
    // If there was an alarm then print the alarm
    // message, clear the alarms and re-enable the
    // interrupts.
    Serial.print(timestr);
    if (alarm_flag) {
      int_disable;
      Serial.print(" | ");
      Serial.print(temp_read(), 1);
      Serial.print("\r");
      alarm_flag = 0;
      rtc.clear_alarm1();
      delay(1000);
      PCMSK1 |= _BV(RTC_ALARM1_INT);
      int_enable;
    } else {
      Serial.print("\r");
    }
#endif
    led.blink(1); 
    delay(1000);
  }
}

// When this routine is called the alarm flag is set and the pin
// change mask is cleared.

// The interrupt flags are read and reset in the main loop.

ISR( PCINT1_vect )
{
  alarm_flag = 1;
  PCMSK1 &= ~(1<<RTC_ALARM1_INT);
}


void xbee_init() {
  long count = 0;
  char in_byte = 0;

  // To put the radio in command mode transmit the XB_CMD_MODE string
  // and wait of the "OK\r" reply. If the wait is too long then exit
  // and blink the ZB1 status LED.

  Serial.print(XB_CMD_MODE);

  while (in_byte != '\r') {
    if (Serial.available() > 0) {
      in_byte = Serial.read(); 
    }
    if (count++ > 100000) break;
  }

  if (count <= 100000) {

     // Initialize the XBee to transmit and recieve

     // 1. Set the destination address of the radio that will receive
     //    the transmissions.
     // 2. Set the source address of the radio on this ZB1 board.
     // 3. Set the Personal Area Network (PAN) ID. All of the radios
     //    in this mesh need to have the same PAN ID
     // 4. Place the radio back into data mode to receve commands.

     // All of the message string are defined at the top of the program

     Serial.print(XB_DESTINATION_ADDRESS);
     Serial.print(XB_MY_ADDRESS); 
     Serial.print(XB_PAN_ID);
     Serial.print(XB_DATA_MODE);

     ready_p = 1;
  } else {
    led.blink(5);
  }
}


float temp_read(void) {
  unsigned char i;
  unsigned char mem_bytes[4];
  short temp;
  tc_select;
  for (i = 0; i < 4; i++) {
    SPDR = 0xff; 
    while(!(SPSR & (1 << SPIF)));
    mem_bytes[i] = SPDR;

  }
  tc_deselect;
  temp = (mem_bytes[0] << 8) | (mem_bytes[1] & 0xFC);
  return((float)(temp) / 16);
}