Heated bed project part 3

Posted December 30 2011, tagged reprap, launchpad, heatedbed,

I've been getting to grips with various aspects of the TI Launchpad.  Specifically ADC conversion and controlling various devices within the chip.  I have got a basic temperature reading circuit linked trhough to an external LED (which I'm using in lieu of a heater).  The reading from the ADC is now controlling the 'heater' if the temperature is below an abitry threshold.  For reference I've put the code so far below.

 

While just checking the forums, I came across these two posts.  They offer more information on heated bed control circuits. 

http://forums.reprap.org/read.php?1,111424

http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html

Also since I keep losing this, basic circuit for Launchpad MPS430

 

 

#include	"msp430g2231.h"
#include "stdbool.h"

#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2

#define Bit_time 104 // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104
#define Bit_time_5 52 // Time for half a bit.

unsigned char BitCnt; // Bit count, used when transmitting byte
unsigned int TXByte; // Value sent over UART when Transmit() is called
unsigned int RXByte; // Value recieved once hasRecieved is set

bool isReceiving; // Status for when the device is receiving
bool hasReceived; // Lets the program know when a byte is received


#define TEMP_SENSOR BIT5

#define HEATER BIT4
#define LED_AT_TEMP BIT6
#define LED_HEATER_ON BIT0

bool ADCDone; // ADC Done flag
unsigned int ADCValue; // Measured ADC Value



// Function Definitions
void Transmit(void);
void ConfigureADC(void);

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz

P1SEL |= TXD + TEMP_SENSOR;
P1DIR |= TXD + HEATER + LED_AT_TEMP + LED_HEATER_ON;

P1IES |= RXD; // RXD Hi/lo edge interrupt
P1IFG &= ~RXD; // Clear RXD (flag) before enabling interrupt
P1IE |= RXD; // Enable RXD interrupt

// Turn off all the outputs
P1OUT &= ~(LED_AT_TEMP + LED_HEATER_ON);
P1OUT != HEATER; // The heater should be wired to sink current

// Turn off all the outputs
P1OUT &= ~(LED_AT_TEMP + LED_HEATER_ON);
P1OUT != HEATER; // The heater should be wired to sink current

ConfigureADC();


isReceiving = false; // Set initial values
hasReceived = false;

__bis_SR_register(GIE); // interrupts enabled\

while(1)
{
if (ADCDone) {
ADCDone = false;
TXByte = ADCValue;
Transmit(); // Send the value to the host pc

if (ADCValue < 210)
{
// Too Cold
// Turn on heater, turn on heating LED, turn off on temp LED
P1OUT &= ~(HEATER + LED_AT_TEMP); // Remember this should be wired to sink current
//P1OUT ^= LED_AT_TEMP;
P1OUT |= LED_HEATER_ON;
}
else
{
P1OUT |= (HEATER + LED_AT_TEMP);
P1OUT &= ~LED_HEATER_ON;
}
}


if (hasReceived) // If the device has recieved a value
{

P1OUT ^= (LED_AT_TEMP + LED_HEATER_ON + HEATER);

hasReceived = false; // Clear the flag
}
//if (~hasReceived) // Loop again if another value has been received
// __bis_SR_register(CPUOFF + GIE);
// LPM0, the ADC interrupt will wake the processor up. This is so that it does not
// endlessly loop when no value has been Received.
}
}

void ConfigureADC(void)
{
/* Configure ADC Channel */
ADC10CTL1 = INCH_5 + ADC10DIV_3 ; // Channel 5, ADC10CLK/4
ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; //Vcc & Vss as reference
ADC10AE0 |= TEMP_SENSOR; //P1.5 ADC option
}

/**
* ADC interrupt routine. Pulls CPU out of sleep mode for the main loop.
**/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
ADCValue = ADC10MEM; // Saves measured value.
ADCDone = true; // Sets flag for main loop.
__bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues
}

// Function Transmits Character from TXByte
void Transmit()
{
while(isReceiving); // Wait for RX completion
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode

BitCnt = 0xA; // Load Bit counter, 8 bits + ST/SP
CCR0 = TAR; // Initialize compare register

CCR0 += Bit_time; // Set time till first bit
TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1)
TXByte = TXByte << 1; // Add start bit (which is logical 0)

CCTL0 = CCIS0 + OUTMOD0 + CCIE; // Set signal, intial value, enable interrupts
while ( CCTL0 & CCIE ); // Wait for previous TX completion

}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{

isReceiving = true;

P1IE &= ~RXD; // Disable RXD interrupt
P1IFG &= ~RXD; // Clear RXD IFG (interrupt flag)

TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
CCR0 = TAR; // Initialize compare register
CCR0 += Bit_time_5; // Set time till first bit
CCTL0 = OUTMOD1 + CCIE; // Dissable TX and enable interrupts

RXByte = 0; // Initialize RXByte
BitCnt = 0x9; // Load Bit counter, 8 bits + ST

}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{

ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

if(!isReceiving)
{
CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0) // If all bits TXed
{
TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
CCTL0 &= ~ CCIE ; // Disable interrupt
}
else
{
CCTL0 |= OUTMOD2; // Set TX bit to 0
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // If it should be 1, set it to 1
TXByte = TXByte >> 1;
BitCnt --;
}
}
else
{
CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0)
{
TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
CCTL0 &= ~ CCIE ; // Disable interrupt

isReceiving = false;

P1IFG &= ~RXD; // clear RXD IFG (interrupt flag)
P1IE |= RXD; // enabled RXD interrupt

if ( (RXByte & 0x201) == 0x200) // Validate the start and stop bits are correct
{
RXByte = RXByte >> 1; // Remove start bit
RXByte &= 0xFF; // Remove stop bit
hasReceived = true;
}
__bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues
}
else
{
if ( (P1IN & RXD) == RXD) // If bit is set?
RXByte |= 0x400; // Set the value in the RXByte
RXByte = RXByte >> 1; // Shift the bits down
BitCnt --;
}
}

}

 

comments powered by Disqus