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 Function | Pin Number
| MISO | 18
| SCK | 19
| PB2 | 16
| 3V3 | 7
| GND | 8
|
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);
}
|