diff --git a/lab5/distance/Makefile b/lab5/distance/Makefile new file mode 100755 index 0000000..3789c62 --- /dev/null +++ b/lab5/distance/Makefile @@ -0,0 +1,18 @@ +OBJECTS=main.o +DEVICE = msp430g2553 +INSTALL_DIR=$(HOME)/ti/msp430_gcc + +GCC_DIR = $(INSTALL_DIR)/bin +SUPPORT_FILE_DIRECTORY = $(INSTALL_DIR)/include + +CC = $(GCC_DIR)/msp430-elf-gcc +GDB = $(GCC_DIR)/msp430-elf-gdb + +CFLAGS = -I $(SUPPORT_FILE_DIRECTORY) -mmcu=$(DEVICE) -O2 -g +LFLAGS = -L $(SUPPORT_FILE_DIRECTORY) -T $(DEVICE).ld + +all: ${OBJECTS} + $(CC) $(CFLAGS) $(LFLAGS) $? -o main.elf + +debug: all + $(GDB) main.elf diff --git a/lab5/distance/main.c b/lab5/distance/main.c new file mode 100644 index 0000000..3b5fa75 --- /dev/null +++ b/lab5/distance/main.c @@ -0,0 +1,293 @@ +/* + * main.c + * + * MSP-EXP430G2-LaunchPad User Experience Application + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + + * Heavily modified: Nov, 2013 Carl Michal + * Even more so, February, 2014 + + * This version modified to use the Hardware UART on MSP430G2553 + * see code at https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/msp430g2553-hardware-uart/ + * jumpers for TX/RX on Launchpad board must be rotated 90 degrees + * for hardware UART used here!! + * This may not work on all revisions of the board? + + +*/ + + +/****************************************************************************** + * MSP-EXP430G2-LaunchPad User Experience Application + * + * 1. Device starts up in LPM3 + blinking LED to indicate device is alive + * + Upon first button press, device transitions to application mode + * 2. Application Mode + * + Continuously sample ADC Temp Sensor channel + * + * + Transmit temperature value via TimerA UART to PC + * + * + * Texas Instruments, Inc. + ******************************************************************************/ + +#include "msp430.h" + +#define LED1 BIT0 +#define LED2 BIT6 + +#define TRIG BIT4 +#define ECHO BIT5 + +#define BUTTON BIT3 + +#define TXD BIT2 // TXD on P1.2 +#define RXD BIT1 // RXD on P1.1 + +#define PreAppMode 0 +#define RunningMode 1 + +unsigned int TXByte; +volatile unsigned int Mode; + +void InitializeButton(void); +void PreApplicationMode(void); + +void main(void) +{ + long tempMeasured; + + WDTCTL = WDTPW + WDTHOLD; // Stop WDT + + /* next three lines to use internal calibrated 1MHz clock: */ + BCSCTL1 = CALBC1_1MHZ; // Set range + DCOCTL = CALDCO_1MHZ; + BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1MHz + + InitializeButton(); + + // setup port for leds: + P1DIR |= LED1 + LED2; + P1OUT &= ~(LED1 + LED2); + + P1DIR |= TXD; + P1OUT |= TXD; + + Mode = PreAppMode; + PreApplicationMode(); // Blinks LEDs, waits for button press + + /* Configure ADC Temp Sensor Channel */ + ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 + ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; + + __delay_cycles(1000); // Wait for ADC Ref to settle + + __enable_interrupt(); // Enable interrupts. + + /* Configure hardware UART */ + P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + UCA0CTL1 |= UCSSEL_2; // Use SMCLK + UCA0BR0 = 104; // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13) + UCA0BR1 = 0; // Set baud rate to 9600 with 1MHz clock + UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 + UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine + /* if we were going to receive, we would also: + IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt + */ + + /* Main Application Loop */ + while(1) + { + /* + ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start + __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled turns cpu off. + // an interrupt is triggered when the ADC result is ready. + // The interrupt handler restarts the cpu. + + // store result + tempMeasured = ADC10MEM; + + + // convert to farenheit and send to host computer + TXByte = (unsigned char)( ((tempMeasured - 630) * 761) / 1024 ); + while (! (IFG2 & UCA0TXIFG)); // wait for TX buffer to be ready for new data + UCA0TXBUF = TXByte; + + P1OUT ^= LED1; // toggle the light every time we make a measurement. + + // set up timer to wake us in a while: + TACCR0 = 2400; // period + TACTL = TASSEL_1 | MC_1; // TACLK = ACLK, Up mode. + TACCR1 = 2400; // interrupt at end + TACCTL1 = CCIE; // TACCTL0 + + // go to sleep, wait till timer expires to do another measurement. + __bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled turns cpu off. + + // could have just done this - but low power mode is nicer. + // __delay_cycles(500000); + */ + + + P1IE |= ECHO; // set echo input as interrupt + P1OUT |= TRIG; // start trigger signal + __delay_cycles(10); // we need a 10 us pulse but one clock cycle is 1 us + P1OUT &= ~TRIG; // end trigger signal + TACTL = TACLR; + TACTL = TASSEL_2 | ID_3 | MC_2; // set timer to count up + unsigned int start = TAR; + __bis_SR_register(LPM0_bits + GIE); // low-power mode 0 (SMCLK still on) + unsigned int stop = TAR; + TXByte = stop - start; + while (! (IFG2 & UCA0TXIFG)); // wait for TX buffer to be ready for new data + UCA0TXBUF = TXByte; + P1OUT ^= LED1; + __delay_cycles(10000); // wait 10 ms before measuring again + } +} + +void PreApplicationMode(void) +{ + P1DIR |= LED1 + LED2; + P1OUT |= LED1; // To enable the LED toggling effect + P1OUT &= ~LED2; + + /* these next two lines configure the ACLK signal to come from + a secondary oscillator source, called VLO */ + + BCSCTL1 |= DIVA_1; // ACLK is half the speed of the source (VLO) + BCSCTL3 |= LFXT1S_2; // ACLK = VLO + + /* here we're setting up a timer to fire an interrupt periodically. + When the timer 1 hits its limit, the interrupt will toggle the lights + + We're using ACLK as the timer source, since it lets us go into LPM3 + (where SMCLK and MCLK are turned off). */ + + TACCR0 = 1200; // period + TACTL = TASSEL_1 | MC_1; // TACLK = ACLK, Up mode. + TACCTL1 = CCIE + OUTMOD_3; // TACCTL1 Capture Compare + TACCR1 = 600; // duty cycle + __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled + // in LPM3, MCLCK and SMCLK are off, but ACLK is on. +} + +// this gets used in pre-application mode only to toggle the lights: +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=TIMER0_A1_VECTOR +__interrupt void ta1_isr (void) +#else + void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) ta1_isr (void) +#endif +{ + TACCTL1 &= ~CCIFG; // reset the interrupt flag + if (Mode == PreAppMode){ + P1OUT ^= (LED1 + LED2); // toggle the two lights. + } + else{ + TACCTL1 = 0; // no more interrupts. + __bic_SR_register_on_exit(LPM3_bits); // Restart the cpu + } + +} + +void InitializeButton(void) // Configure Push Button +{ + P1DIR &= ~BUTTON; + P1OUT |= BUTTON; + P1REN |= BUTTON; + P1IES |= BUTTON; + P1IFG &= ~BUTTON; + P1IE |= BUTTON; +} + +/* ************************************************************* + * Port Interrupt for Button Press + * 1. During standby mode: to enter application mode + * + * *********************************************************** */ + +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=PORT1_VECTOR +__interrupt void port1_isr(void) +#else + void __attribute__ ((interrupt(PORT1_VECTOR))) port1_isr (void) +#endif +{ + + /* this disables port1 interrupts for a little while so that + we don't try to respond to two consecutive button pushes right together. + The watchdog timer interrupt will re-enable port1 interrupts + + This whole watchdog thing is completely unnecessary here, but its useful + to see how it is done. +*/ + P1IFG = 0; // clear out interrupt flag + P1IE &= ~BUTTON; // Disable port 1 interrupts + WDTCTL = WDT_ADLY_250; // set up watchdog timer duration + IFG1 &= ~WDTIFG; // clear interrupt flag + IE1 |= WDTIE; // enable watchdog interrupts + + TACCTL1 = 0; // turn off timer 1 interrupts + P1OUT &= ~(LED1+LED2); // turn off the leds + Mode = RunningMode; + __bic_SR_register_on_exit(LPM3_bits); // take us out of low power mode + +} + +// WDT Interrupt Service Routine used to de-bounce button press +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=WDT_VECTOR +__interrupt void wdt_isr(void) +#else + void __attribute__ ((interrupt(WDT_VECTOR))) wdt_isr (void) +#endif +{ + IE1 &= ~WDTIE; /* disable watchdog interrupt */ + IFG1 &= ~WDTIFG; /* clear interrupt flag */ + WDTCTL = WDTPW + WDTHOLD; /* put WDT back in hold state */ + P1IE |= BUTTON; /* Debouncing complete - reenable port 1 interrupts*/ +} + +// ADC10 interrupt service routine +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=ADC10_VECTOR +__interrupt void adc10_isr(void) +#else + void __attribute__ ((interrupt(ADC10_VECTOR))) adc10_isr (void) +#endif +{ + __bic_SR_register_on_exit(CPUOFF); // Restart the cpu +} diff --git a/lab5/distance/main.o b/lab5/distance/main.o new file mode 100644 index 0000000..0966713 Binary files /dev/null and b/lab5/distance/main.o differ diff --git a/lab5/distance/python-serial-plot.py b/lab5/distance/python-serial-plot.py new file mode 100755 index 0000000..50c361d --- /dev/null +++ b/lab5/distance/python-serial-plot.py @@ -0,0 +1,90 @@ +#!/usr/bin/python2.7 +import serial # for serial port +import numpy as np # for arrays, numerical processing +from time import sleep,time +import gtk #the gui toolkit we'll use: +# graph plotting library: +from matplotlib.figure import Figure +from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas + +#needs: python2, pyserial, numpy, matplotlib, pygtk +#0) flash the serial temperature measurement program into the msp430 +#1) start this program +#2) press the button the Launchpad to enter 'applcation mode' +#3) warm the chip (eg with a light bulb or your fingers) +#4) when you've seen enough, press the reset button on the launchpad +#5) exit the program by pressing 'q' or clicking on the x + +#define the serial port. Pick one: +port = "/dev/ttyACM0" #for Linux +#port = "COM5" #For Windows? +#port = "/dev/tty.uart-XXXX" #For Mac? + +#function that gets called when a key is pressed: +def press(event): + print('press', event.key) + if event.key == 'q': + print ('got q!') + quit_app(None) + return True + +def quit_app(event): + outFile.close() + ser.close() + quit() + +#start our program proper: +#open the serial port +try: + ser = serial.Serial(port,2400,timeout = 0.050) + ser.baudrate=9600 +# with timeout=0, read returns immediately, even if no data +except: + print ("Opening serial port",port,"failed") + print ("Edit program to point to the correct port.") + print ("Hit enter to exit") + raw_input() + quit() + +#create a window to put the plot in +win = gtk.Window() +#connect the destroy signal (clicking the x in the corner) +win.connect("destroy", quit_app) +win.set_default_size(400,300) + +yvals = np.zeros(50) #array to hold last 50 measurements +times=np.arange(0,50,1.0) # 50 from 0 to 49. + +#create a plot: +fig = Figure() +ax = fig.add_subplot(111,xlabel='Time Step',ylabel='Temp (deg F)') +ax.set_ylim(0,255) # set limits of y axis. + +canvas = FigureCanvas(fig) #put the plot onto a canvas +win.add(canvas) #put the canvas in the window + +# define a callback for when a key is pressed +fig.canvas.mpl_connect('key_press_event',press) + +#show the window +win.show_all() +win.set_title("ready to receive data"); + +line, = ax.plot(times,yvals) +#open a data file for the output +outFile = open("time_and_temp.txt","w") +start_time = time() +ser.flushInput() + +while(1): #loop forever + data = ser.read(1) # look for a character from serial port, will wait up to timeout above. + if len(data) > 0: #was there a byte to read? should always be true. + yvals = np.roll(yvals,-1) # shift the values in the array + yvals[49] = ord(data) # take the value of the byte + outFile.write(str(time()-start_time)+" "+str(yvals[49])+"\n") #write to file + line.set_ydata(yvals) # draw the line + fig.canvas.draw() # update the canvas + win.set_title("Temp: "+str(yvals[49])+" deg F") + while gtk.events_pending(): #makes sure the GUI updates + gtk.main_iteration() +# sleep(.05) # don't eat the cpu. This delay limits the data rate to ~ 200 samples/s diff --git a/lab5/distance/python-serial-print.py b/lab5/distance/python-serial-print.py new file mode 100755 index 0000000..cdc658e --- /dev/null +++ b/lab5/distance/python-serial-print.py @@ -0,0 +1,37 @@ +#!/usr/bin/python2.7 +import serial # for serial port +import numpy as np # for arrays, numerical processing + +#needs: python2, pyserial, numpy, +#0) flash the serial temperature measurement program into the msp430 +#1) start this program +#2) press the button the Launchpad to enter 'applcation mode' +#3) warm the chip (eg with a light bulb or your fingers) +#4) when you've seen enough, press the reset button on the launchpad +#5) exit the program by pressing 'q' or clicking on the x + +#define the serial port. Pick one: +port = "/dev/ttyACM0" #for Linux +#port = "COM5" #For Windows? +#port = "/dev/tty.uart-XXXX" #For Mac? + + +#start our program proper: +#open the serial port +try: + ser = serial.Serial(port,2400,timeout = 0.050) + ser.baudrate=9600 +# with timeout=0, read returns immediately, even if no data +except: + print ("Opening serial port",port,"failed") + print ("Edit program to point to the correct port.") + print ("Hit enter to exit") + raw_input() + quit() + +ser.flushInput() + +while(1): #loop forever + data = ser.read(1) # look for a character from serial port - will wait for up to 50ms (specified above in timeout) + if len(data) > 0: #was there a byte to read? + print ord(data) diff --git a/lab5/distance/serial_duplex.c b/lab5/distance/serial_duplex.c new file mode 100644 index 0000000..341690e --- /dev/null +++ b/lab5/distance/serial_duplex.c @@ -0,0 +1,100 @@ +/* Example code demonstrating the use of the hardware UART on the MSP430G2553 to receive + * and transmit data back to a host computer over the USB connection on the MSP430 + * launchpad. + * Note: After programming it is necessary to stop debugging and reset the uC before + * connecting the terminal program to transmit and receive characters. + * This demo will turn on the Red LED if an R is sent and turn it off if a r is sent. + * Similarly G and g will turn on and off the green LED + * It also transmits the received character back to the terminal. + +FROM: https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/msp430g2553-hardware-uart/ + + + */ + +#include "msp430.h" +void UARTSendArray(char *TxArray, char ArrayLength); + +static char data; + +void main(void) + +{ + WDTCTL = WDTPW + WDTHOLD; // Stop WDT + + P1DIR |= BIT0 + BIT6; // Set the LEDs on P1.0, P1.6 as outputs + P1OUT = BIT0; // Set P1.0 + + BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz + DCOCTL = CALDCO_1MHZ; // Set DCO to 1MHz + +/* Configure hardware UART */ + P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + UCA0CTL1 |= UCSSEL_2; // Use SMCLK + UCA0BR0 = 104; // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13) + UCA0BR1 = 0; // Set baud rate to 9600 with 1MHz clock + UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 + UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine + IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt + +__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled +} + +// Echo back RXed character, confirm TX buffer is ready first + +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=USCIAB0RX_VECTOR +__interrupt void USCI0RX_ISR(void) +#else + void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) uci0rx_isr(void) +#endif +{ +data = UCA0RXBUF; +UARTSendArray("Received command: ", 18); +UARTSendArray(&data, 1); +UARTSendArray("\n\r", 2); + +switch(data){ + case 'R': + { + P1OUT |= BIT0; + } + break; + case 'r': + { + P1OUT &= ~BIT0; + } + break; + case 'G': + { + P1OUT |= BIT6; + } + break; + case 'g': + { + P1OUT &= ~BIT6; + } + break; + default: + { + UARTSendArray("Unknown Command: ", 17); + UARTSendArray(&data, 1); + UARTSendArray("\n\r", 2); + } + break; + } +} + +void UARTSendArray(char *TxArray, char ArrayLength){ + // Send number of bytes Specified in ArrayLength in the array at using the hardware UART 0 + // Example usage: UARTSendArray("Hello", 5); + // int data[2]={1023, 235}; + // UARTSendArray(data, 4); // Note because the UART transmits bytes it is necessary to send two bytes for each integer hence the data length is twice the array length + +while(ArrayLength--){ // Loop until StringLength == 0 and post decrement + while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for new data + UCA0TXBUF = *TxArray; //Write the character at the location specified py the pointer + TxArray++; //Increment the TxString pointer to point to the next character + } +} diff --git a/lab5/distance/time_and_temp.txt b/lab5/distance/time_and_temp.txt new file mode 100644 index 0000000..bc89549 --- /dev/null +++ b/lab5/distance/time_and_temp.txt @@ -0,0 +1,1445 @@ +2.75770783424 38.0 +2.78425192833 104.0 +2.81221699715 8.0 +2.84269690514 224.0 +2.87347793579 148.0 +2.90892887115 179.0 +2.93950891495 217.0 +2.96721696854 52.0 +2.99796795845 133.0 +3.02697682381 109.0 +3.05762195587 138.0 +3.08878302574 126.0 +3.11919403076 119.0 +3.14911794662 144.0 +3.17958283424 111.0 +3.20980787277 201.0 +3.23999190331 120.0 +3.27002000809 238.0 +3.32091403008 174.0 +3.37056899071 218.0 +3.399974823 22.0 +3.43068981171 236.0 +3.4615278244 46.0 +3.49189901352 61.0 +3.52273488045 17.0 +3.5530769825 107.0 +3.58579587936 210.0 +3.61780190468 136.0 +3.64925003052 146.0 +3.6871778965 66.0 +3.72092485428 161.0 +3.75313901901 204.0 +3.7845659256 49.0 +3.81511592865 55.0 +3.84503102303 56.0 +3.88160800934 55.0 +3.9142138958 53.0 +3.94471287727 55.0 +3.97547483444 56.0 +4.00759601593 55.0 +4.037722826 53.0 +4.06876802444 54.0 +4.10182499886 115.0 +4.13259482384 184.0 +4.16379189491 115.0 +4.19586801529 75.0 +4.22681283951 224.0 +4.25700688362 162.0 +4.29600000381 161.0 +4.35955786705 124.0 +4.38980197906 164.0 +4.42052197456 102.0 +4.45092582703 127.0 +4.4815788269 78.0 +4.51304292679 176.0 +4.54380488396 120.0 +4.57479500771 140.0 +4.60722899437 146.0 +4.63778400421 121.0 +4.66928195953 119.0 +4.70020890236 141.0 +4.73060202599 124.0 +4.76179885864 130.0 +4.79337882996 139.0 +4.82565999031 123.0 +4.85530686378 89.0 +4.8944709301 183.0 +4.92529201508 123.0 +4.95466089249 226.0 +4.98551797867 56.0 +5.01673293114 24.0 +5.04753684998 142.0 +5.07995295525 53.0 +5.11198687553 56.0 +5.14363002777 58.0 +5.17443394661 52.0 +5.20449495316 56.0 +5.23423790932 53.0 +5.26472783089 57.0 +5.31523084641 55.0 +5.36684799194 55.0 +5.39709687233 244.0 +5.42682695389 155.0 +5.45684480667 242.0 +5.48719787598 56.0 +5.51835584641 54.0 +5.548858881 55.0 +5.58081102371 55.0 +5.61184287071 56.0 +5.64225888252 54.0 +5.67323803902 56.0 +5.70424890518 57.0 +5.73560881615 57.0 +5.76576781273 54.0 +5.79614591599 249.0 +5.82808089256 136.0 +5.85916996002 24.0 +5.89782500267 76.0 +5.92810797691 160.0 +5.95945596695 111.0 +5.98981285095 49.0 +6.02100396156 37.0 +6.05109000206 104.0 +6.08166384697 230.0 +6.11339402199 137.0 +6.14428400993 223.0 +6.17460894585 224.0 +6.20472192764 122.0 +6.23396801949 15.0 +6.26470804214 254.0 +6.31186890602 50.0 +6.36730289459 48.0 +6.39875888824 52.0 +6.42912793159 50.0 +6.46042895317 46.0 +6.49128699303 51.0 +6.52279090881 48.0 +6.55243992805 47.0 +6.58353900909 53.0 +6.61696100235 48.0 +6.64760684967 49.0 +6.67920589447 50.0 +6.71451282501 48.0 +6.74570202827 50.0 +6.77729797363 49.0 +6.80765390396 49.0 +6.83601498604 49.0 +6.86437702179 50.0 +6.9011900425 48.0 +6.92985391617 48.0 +6.95844388008 50.0 +6.9872648716 50.0 +7.01674389839 49.0 +7.04686594009 49.0 +7.07652688026 49.0 +7.10758900642 50.0 +7.13755989075 41.0 +7.16731595993 50.0 +7.19858884811 48.0 +7.22954392433 49.0 +7.26056289673 49.0 +7.30350184441 51.0 +7.36349987984 46.0 +7.39400792122 49.0 +7.4244890213 50.0 +7.45412993431 49.0 +7.48395586014 49.0 +7.51355695724 48.0 +7.54326295853 50.0 +7.57389497757 50.0 +7.6057100296 50.0 +7.63355493546 50.0 +7.66232800484 46.0 +7.69264483452 50.0 +7.72336983681 51.0 +7.75225782394 49.0 +7.78292489052 46.0 +7.81398391724 48.0 +7.8457198143 47.0 +7.88409495354 51.0 +7.91621184349 49.0 +7.94717502594 48.0 +7.97807097435 49.0 +8.01021099091 49.0 +8.04043602943 50.0 +8.06927204132 50.0 +8.10014200211 48.0 +8.13005495071 50.0 +8.16148900986 50.0 +8.19070291519 48.0 +8.22014594078 48.0 +8.24824786186 50.0 +8.28166985512 48.0 +8.33464598656 51.0 +8.3788819313 48.0 +8.40823483467 48.0 +8.43687081337 51.0 +8.46634602547 51.0 +8.49547481537 47.0 +8.52553892136 49.0 +8.55448484421 49.0 +8.58402585983 49.0 +8.61434292793 50.0 +8.64408898354 47.0 +8.67496490479 49.0 +8.70544791222 51.0 +8.73486495018 49.0 +8.764772892 50.0 +8.79609489441 49.0 +8.82625102997 47.0 +8.85592889786 50.0 +8.8973338604 48.0 +8.92718791962 50.0 +8.95677304268 50.0 +8.98583483696 48.0 +9.01539683342 50.0 +9.04555487633 49.0 +9.07642292976 47.0 +9.10926485062 50.0 +9.14029288292 50.0 +9.16928887367 50.0 +9.19804191589 49.0 +9.22861289978 48.0 +9.25950694084 49.0 +9.30212688446 50.0 +9.36303186417 49.0 +9.39276981354 46.0 +9.42302799225 50.0 +9.45315885544 51.0 +9.48338794708 50.0 +9.51335287094 48.0 +9.54366397858 49.0 +9.57376098633 46.0 +9.60438394547 52.0 +9.63681483269 50.0 +9.66957902908 49.0 +9.70458602905 48.0 +9.73394703865 51.0 +9.7663769722 49.0 +9.79808497429 51.0 +9.82935380936 48.0 +9.8602449894 47.0 +9.89854001999 51.0 +9.92843699455 50.0 +9.95911502838 47.0 +9.99075984955 50.0 +10.0220918655 49.0 +10.0511059761 48.0 +10.0818648338 52.0 +10.1146328449 46.0 +10.1466648579 48.0 +10.1779849529 51.0 +10.2092809677 51.0 +10.2385408878 47.0 +10.2700698376 49.0 +10.3222959042 48.0 +10.3701570034 52.0 +10.4013738632 50.0 +10.4315969944 50.0 +10.4615988731 47.0 +10.4912559986 50.0 +10.5219759941 51.0 +10.5517659187 48.0 +10.5820119381 48.0 +10.6129608154 50.0 +10.6422088146 49.0 +10.6719470024 51.0 +10.7025859356 48.0 +10.7322309017 49.0 +10.7632439137 49.0 +10.7925598621 49.0 +10.821944952 52.0 +10.851544857 46.0 +10.8889319897 52.0 +10.9196739197 48.0 +10.9497978687 51.0 +10.9804890156 48.0 +11.0117878914 49.0 +11.0428328514 50.0 +11.0728969574 49.0 +11.1027150154 50.0 +11.1341919899 49.0 +11.1646249294 49.0 +11.1938598156 48.0 +11.2239599228 49.0 +11.2538728714 50.0 +11.2919909954 48.0 +11.3528468609 49.0 +11.3844029903 50.0 +11.4148819447 51.0 +11.4458909035 47.0 +11.4762508869 48.0 +11.5070569515 49.0 +11.5362148285 51.0 +11.5663018227 50.0 +11.5966238976 48.0 +11.6287579536 48.0 +11.6576328278 50.0 +11.6870908737 49.0 +11.7174859047 49.0 +11.746450901 49.0 +11.7746698856 48.0 +11.8038840294 51.0 +11.8327248096 49.0 +11.8627569675 48.0 +11.9005799294 49.0 +11.9298629761 50.0 +11.9602680206 49.0 +11.990983963 52.0 +12.0232310295 47.0 +12.0595560074 49.0 +12.0903208256 50.0 +12.1229720116 50.0 +12.1521909237 48.0 +12.1821908951 49.0 +12.21240592 49.0 +12.2421529293 48.0 +12.2736518383 50.0 +12.3261368275 50.0 +12.3779959679 49.0 +12.4071619511 47.0 +12.4375708103 51.0 +12.468613863 49.0 +12.4994418621 50.0 +12.5291469097 49.0 +12.559499979 48.0 +12.5898878574 51.0 +12.6215200424 48.0 +12.6509339809 48.0 +12.6808879375 50.0 +12.7153408527 51.0 +12.7484719753 48.0 +12.7793908119 44.0 +12.8099808693 39.0 +12.841285944 42.0 +12.8740489483 42.0 +12.9082698822 222.0 +12.9376118183 126.0 +12.9691939354 31.0 +13.0001089573 52.0 +13.0301439762 52.0 +13.0599918365 55.0 +13.0897328854 55.0 +13.1203730106 58.0 +13.1500170231 55.0 +13.1808419228 53.0 +13.2124090195 56.0 +13.2435159683 56.0 +13.2741229534 56.0 +13.3222148418 55.0 +13.3699688911 169.0 +13.4004778862 90.0 +13.4306569099 173.0 +13.4616320133 74.0 +13.4919140339 189.0 +13.5225138664 41.0 +13.5516040325 179.0 +13.5819590092 209.0 +13.6122770309 74.0 +13.6439819336 85.0 +13.6740028858 123.0 +13.7041199207 35.0 +13.7333660126 222.0 +13.7641420364 137.0 +13.7957518101 142.0 +13.8262310028 128.0 +13.8555710316 122.0 +13.8930900097 117.0 +13.9237220287 90.0 +13.9530899525 134.0 +13.9831318855 27.0 +14.0145368576 195.0 +14.0448260307 79.0 +14.0751988888 36.0 +14.105481863 55.0 +14.138051033 41.0 +14.1678910255 45.0 +14.1992368698 32.0 +14.2308979034 56.0 +14.2617678642 38.0 +14.3065109253 50.0 +14.3628499508 151.0 +14.3927719593 114.0 +14.423404932 116.0 +14.4533958435 36.0 +14.483522892 29.0 +14.5146620274 55.0 +14.5456688404 203.0 +14.5760569572 60.0 +14.6070728302 31.0 +14.638021946 110.0 +14.668612957 42.0 +14.6999230385 30.0 +14.7303488255 49.0 +14.7614808083 39.0 +14.7926399708 23.0 +14.8240809441 240.0 +14.8533029556 76.0 +14.8912789822 254.0 +14.9213719368 34.0 +14.9512379169 44.0 +14.9818949699 72.0 +15.0124919415 50.0 +15.0430939198 241.0 +15.0740690231 11.0 +15.1045348644 126.0 +15.1363749504 114.0 +15.1671178341 43.0 +15.1984059811 43.0 +15.2288570404 45.0 +15.2596349716 43.0 +15.3016479015 43.0 +15.3616759777 42.0 +15.3908560276 43.0 +15.4213149548 45.0 +15.4512298107 42.0 +15.4819908142 41.0 +15.5122950077 43.0 +15.5428278446 44.0 +15.5736849308 43.0 +15.6045968533 44.0 +15.6372108459 42.0 +15.6678249836 42.0 +15.7019658089 44.0 +15.7323048115 43.0 +15.7654879093 44.0 +15.7971839905 41.0 +15.8279390335 43.0 +15.8579559326 43.0 +15.8947668076 43.0 +15.9243359566 44.0 +15.953291893 41.0 +15.9834148884 45.0 +16.0140538216 42.0 +16.0441758633 44.0 +16.0755298138 43.0 +16.1083090305 41.0 +16.1402490139 44.0 +16.1703398228 45.0 +16.2009029388 40.0 +16.230755806 42.0 +16.261674881 44.0 +16.3101358414 44.0 +16.3647680283 43.0 +16.393914938 42.0 +16.4248058796 43.0 +16.454641819 45.0 +16.4851779938 41.0 +16.5157408714 43.0 +16.548635006 75.0 +16.5821368694 24.0 +16.6126358509 42.0 +16.644646883 43.0 +16.6753978729 50.0 +16.7067658901 210.0 +16.7362129688 0.0 +16.7664129734 184.0 +16.7968268394 39.0 +16.8269579411 135.0 +16.8562669754 161.0 +16.8943710327 53.0 +16.9246618748 56.0 +16.953802824 56.0 +16.9825818539 54.0 +17.01243186 54.0 +17.0417108536 57.0 +17.0713689327 56.0 +17.1017999649 55.0 +17.1322920322 54.0 +17.1648139954 55.0 +17.1961328983 127.0 +17.2266819477 213.0 +17.2561039925 40.0 +17.2934780121 62.0 +17.3574328423 48.0 +17.386485815 27.0 +17.4170389175 113.0 +17.447412014 124.0 +17.4777829647 156.0 +17.5090270042 115.0 +17.5395598412 63.0 +17.5696308613 185.0 +17.6007590294 54.0 +17.6310489178 53.0 +17.6628990173 56.0 +17.693600893 54.0 +17.7242949009 58.0 +17.7538158894 54.0 +17.7841908932 55.0 +17.8149540424 55.0 +17.8448278904 56.0 +17.8798308372 55.0 +17.9114429951 120.0 +17.9420919418 115.0 +17.9718649387 232.0 +18.0026979446 31.0 +18.0323808193 114.0 +18.0631759167 121.0 +18.093569994 30.0 +18.1240518093 37.0 +18.1550090313 115.0 +18.1854028702 135.0 +18.2160828114 210.0 +18.2465119362 54.0 +18.2813708782 55.0 +18.3375329971 56.0 +18.3800268173 54.0 +18.4111099243 54.0 +18.4419088364 58.0 +18.4723930359 57.0 +18.5029439926 56.0 +18.5332770348 58.0 +18.5648720264 58.0 +18.5949618816 115.0 +18.6255209446 50.0 +18.6576328278 244.0 +18.698953867 25.0 +18.7306509018 53.0 +18.7651779652 53.0 +18.7973430157 56.0 +18.8270428181 56.0 +18.8560099602 54.0 +18.8929350376 55.0 +18.923897028 56.0 +18.9533410072 57.0 +18.9843318462 52.0 +19.0156610012 163.0 +19.0458199978 191.0 +19.0768740177 159.0 +19.1076610088 129.0 +19.1376299858 249.0 +19.1694560051 179.0 +19.2008159161 198.0 +19.2314009666 76.0 +19.2622690201 130.0 +19.3093128204 213.0 +19.3627579212 239.0 +19.3928918839 123.0 +19.4234628677 122.0 +19.4530258179 6.0 +19.48366189 62.0 +19.5153408051 21.0 +19.5460278988 54.0 +19.5774929523 53.0 +19.608520031 50.0 +19.6400878429 56.0 +19.6728060246 56.0 +19.7023808956 56.0 +19.7302799225 56.0 +19.7592468262 55.0 +19.7880618572 56.0 +19.8190658092 210.0 +19.8489668369 143.0 +19.8863990307 57.0 +19.9189968109 55.0 +19.9488589764 56.0 +19.980096817 55.0 +20.0120618343 57.0 +20.0438668728 54.0 +20.0753908157 55.0 +20.1068079472 57.0 +20.1370129585 56.0 +20.1695199013 57.0 +20.2004609108 61.0 +20.2304589748 32.0 +20.2611539364 31.0 +20.3077478409 71.0 +20.3629519939 66.0 +20.3927898407 116.0 +20.4231419563 135.0 +20.4523799419 165.0 +20.4830229282 195.0 +20.5139498711 121.0 +20.5446419716 132.0 +20.5758190155 98.0 +20.6069319248 54.0 +20.6371908188 10.0 +20.6694059372 36.0 +20.7000198364 49.0 +20.7299339771 48.0 +20.7614200115 50.0 +20.7920069695 51.0 +20.8238868713 50.0 +20.8538730145 48.0 +20.8909850121 49.0 +20.9268438816 50.0 +20.9575028419 48.0 +20.9876658916 50.0 +21.0172078609 49.0 +21.0475919247 49.0 +21.0768749714 50.0 +21.1069438457 51.0 +21.137387991 47.0 +21.1692228317 50.0 +21.1996150017 50.0 +21.2295930386 47.0 +21.260062933 50.0 +21.3027968407 50.0 +21.3589789867 49.0 +21.3907940388 49.0 +21.4198179245 49.0 +21.448319912 50.0 +21.4779620171 49.0 +21.5086770058 49.0 +21.5369479656 50.0 +21.5668950081 49.0 +21.5973570347 48.0 +21.6281080246 50.0 +21.6600959301 50.0 +21.6941130161 48.0 +21.7228829861 48.0 +21.7531888485 50.0 +21.783864975 49.0 +21.8147070408 49.0 +21.8448519707 48.0 +21.8798518181 49.0 +21.9122169018 49.0 +21.9411218166 51.0 +21.9704949856 50.0 +22.0021958351 47.0 +22.0314879417 50.0 +22.0623338223 49.0 +22.092913866 49.0 +22.1228659153 50.0 +22.1520609856 48.0 +22.1844689846 50.0 +22.2143268585 50.0 +22.2441649437 50.0 +22.2739229202 49.0 +22.3261659145 48.0 +22.3736319542 50.0 +22.4034938812 49.0 +22.4335348606 51.0 +22.4647829533 46.0 +22.4948079586 49.0 +22.5248568058 52.0 +22.556625843 49.0 +22.5869009495 48.0 +22.6166648865 50.0 +22.6477198601 46.0 +22.6797029972 52.0 +22.711014986 51.0 +22.7417328358 48.0 +22.7716109753 50.0 +22.801514864 50.0 +22.83056283 48.0 +22.8605430126 50.0 +22.9020328522 49.0 +22.9322099686 47.0 +22.9636149406 51.0 +22.9943020344 50.0 +23.024283886 48.0 +23.0540709496 48.0 +23.0843169689 51.0 +23.1144609451 48.0 +23.1470389366 49.0 +23.1791398525 49.0 +23.2085168362 50.0 +23.2376139164 49.0 +23.270056963 50.0 +23.3201398849 47.0 +23.3712778091 48.0 +23.4006090164 52.0 +23.431385994 49.0 +23.4649050236 50.0 +23.498914957 48.0 +23.5291678905 49.0 +23.559568882 51.0 +23.5903840065 50.0 +23.620028019 49.0 +23.6510558128 48.0 +23.6842329502 47.0 +23.7138748169 51.0 +23.744907856 49.0 +23.7751729488 49.0 +23.8049080372 48.0 +23.8350839615 51.0 +23.8661630154 49.0 +23.9046359062 48.0 +23.9346268177 50.0 +23.9647099972 50.0 +23.994081974 49.0 +24.0237698555 52.0 +24.0537278652 47.0 +24.0834088326 49.0 +24.1146168709 51.0 +24.1452999115 51.0 +24.1755199432 47.0 +24.2047328949 48.0 +24.2354278564 49.0 +24.2651748657 49.0 +24.3153400421 52.0 +24.3649389744 48.0 +24.3953828812 51.0 +24.4261748791 49.0 +24.4575719833 51.0 +24.4880578518 48.0 +24.5193889141 50.0 +24.5496029854 49.0 +24.5800948143 48.0 +24.6107709408 6.0 +24.6429669857 140.0 +24.6755189896 43.0 +24.7108879089 190.0 +24.7417099476 20.0 +24.7722480297 201.0 +24.8030529022 68.0 +24.8337659836 197.0 +24.8645620346 132.0 +24.902671814 11.0 +24.9333899021 21.0 +24.9641158581 1.0 +24.9947769642 222.0 +25.0260128975 89.0 +25.0557398796 245.0 +25.0860228539 162.0 +25.1169660091 23.0 +25.1489570141 41.0 +25.1821229458 201.0 +25.2131149769 155.0 +25.2441828251 14.0 +25.278151989 65.0 +25.3324048519 23.0 +25.3789229393 48.0 +25.4097568989 31.0 +25.4417068958 14.0 +25.473225832 134.0 +25.5033109188 18.0 +25.535435915 195.0 +25.5662558079 105.0 +25.5976920128 188.0 +25.6292388439 114.0 +25.6605298519 219.0 +25.6938569546 123.0 +25.724383831 234.0 +25.7544298172 10.0 +25.7853028774 167.0 +25.8170359135 188.0 +25.8475849628 235.0 +25.8874688148 67.0 +25.921173811 71.0 +25.9519050121 14.0 +25.9829180241 189.0 +26.0144560337 210.0 +26.0464198589 133.0 +26.078305006 154.0 +26.1098818779 147.0 +26.1422839165 4.0 +26.1723508835 53.0 +26.2039849758 50.0 +26.2357079983 1.0 +26.2661499977 42.0 +26.3193588257 107.0 +26.368270874 42.0 +26.399217844 19.0 +26.4308719635 31.0 +26.4618959427 217.0 +26.4931800365 111.0 +26.5244209766 194.0 +26.5548539162 138.0 +26.5859868526 192.0 +26.6177618504 34.0 +26.6501460075 172.0 +26.6835379601 13.0 +26.715430975 43.0 +26.7465858459 59.0 +26.7777769566 26.0 +26.8086178303 0.0 +26.8391509056 232.0 +26.8701369762 45.0 +26.9098680019 43.0 +26.9418029785 41.0 +26.9728980064 44.0 +27.0039019585 44.0 +27.0333659649 16.0 +27.0636589527 154.0 +27.0994968414 156.0 +27.1613299847 51.0 +27.1929068565 51.0 +27.222837925 49.0 +27.2522008419 49.0 +27.2877318859 47.0 +27.35044384 52.0 +27.384469986 47.0 +27.4161889553 48.0 +27.4479320049 50.0 +27.4785938263 47.0 +27.5100150108 51.0 +27.5406718254 49.0 +27.5714440346 50.0 +27.6026668549 48.0 +27.6337690353 49.0 +27.6655459404 50.0 +27.701748848 49.0 +27.7325468063 48.0 +27.766163826 50.0 +27.7974128723 50.0 +27.8277418613 47.0 +27.8586478233 48.0 +27.8976409435 50.0 +27.9293298721 51.0 +27.9608240128 48.0 +27.9922728539 48.0 +28.0211918354 48.0 +28.0502660275 51.0 +28.0796978474 52.0 +28.1105158329 48.0 +28.1430490017 48.0 +28.1728999615 49.0 +28.2040159702 49.0 +28.2329280376 50.0 +28.2629418373 50.0 +28.3092889786 47.0 +28.3637459278 49.0 +28.3936049938 51.0 +28.4237480164 49.0 +28.4546439648 47.0 +28.4853498936 50.0 +28.5158150196 51.0 +28.5468769073 48.0 +28.5782649517 49.0 +28.6083860397 48.0 +28.639056921 50.0 +28.6694729328 49.0 +28.7018339634 50.0 +28.7328548431 48.0 +28.7635560036 49.0 +28.7958319187 49.0 +28.8260378838 48.0 +28.8562150002 49.0 +28.8924119473 49.0 +28.9224898815 48.0 +28.9516208172 49.0 +28.9810168743 49.0 +29.0107779503 49.0 +29.0386469364 47.0 +29.0680580139 51.0 +29.0988719463 50.0 +29.1300439835 47.0 +29.1612298489 50.0 +29.1932258606 50.0 +29.2237398624 49.0 +29.2526278496 48.0 +29.2881989479 49.0 +29.3507499695 49.0 +29.3811969757 48.0 +29.4115898609 51.0 +29.4425339699 49.0 +29.4736509323 48.0 +29.5031228065 48.0 +29.5326428413 50.0 +29.5632078648 50.0 +29.5929839611 48.0 +29.6222200394 49.0 +29.6527488232 49.0 +29.6811728477 50.0 +29.7128179073 50.0 +29.7420558929 46.0 +29.7711939812 50.0 +29.8004820347 49.0 +29.831127882 50.0 +29.8611049652 48.0 +29.8998088837 48.0 +29.9293758869 49.0 +29.9595668316 50.0 +29.9901659489 50.0 +30.0192518234 48.0 +30.0489289761 47.0 +30.0795190334 50.0 +30.1105480194 47.0 +30.1405959129 51.0 +30.1704540253 48.0 +30.2037529945 49.0 +30.234046936 49.0 +30.2636289597 50.0 +30.3116660118 48.0 +30.3665509224 49.0 +30.3964178562 50.0 +30.4274389744 49.0 +30.4590909481 47.0 +30.4923839569 50.0 +30.5253720284 50.0 +30.5537018776 49.0 +30.583673954 48.0 +30.6136078835 49.0 +30.6451218128 50.0 +30.6757259369 47.0 +30.7122468948 50.0 +30.7418849468 48.0 +30.7738289833 48.0 +30.8030610085 50.0 +30.8326480389 50.0 +30.8628950119 51.0 +30.9006249905 45.0 +30.9309740067 51.0 +30.9615249634 49.0 +30.9911289215 48.0 +31.021504879 49.0 +31.0518689156 48.0 +31.0825929642 49.0 +31.1126408577 52.0 +31.1436638832 49.0 +31.1741039753 49.0 +31.206058979 47.0 +31.23467803 51.0 +31.2649958134 49.0 +31.3131799698 49.0 +31.3643000126 47.0 +31.3939268589 51.0 +31.4243018627 50.0 +31.4544098377 50.0 +31.4832429886 47.0 +31.5133578777 50.0 +31.5435519218 49.0 +31.5740509033 50.0 +31.6029429436 49.0 +31.6336829662 48.0 +31.6650910378 48.0 +31.694355011 51.0 +31.7246229649 49.0 +31.7555229664 48.0 +31.7844929695 49.0 +31.8151578903 51.0 +31.8454909325 47.0 +31.880494833 48.0 +31.9127240181 51.0 +31.9433038235 48.0 +31.9745368958 49.0 +32.005535841 49.0 +32.0333769321 50.0 +32.063272953 47.0 +32.0936980247 51.0 +32.1245698929 49.0 +32.1547949314 49.0 +32.1847698689 47.0 +32.215626955 50.0 +32.2464609146 51.0 +32.2808628082 50.0 +32.3373060226 48.0 +32.3789858818 47.0 +32.4084749222 51.0 +32.4386339188 49.0 +32.4692900181 49.0 +32.4983658791 48.0 +32.5285968781 48.0 +32.5581469536 49.0 +32.588351965 51.0 +32.6181898117 46.0 +32.6490638256 50.0 +32.6797728539 50.0 +32.7106668949 48.0 +32.7402780056 47.0 +32.7702338696 49.0 +32.8007018566 48.0 +32.8311738968 51.0 +32.8616089821 51.0 +32.898362875 47.0 +32.9273998737 47.0 +32.9562399387 51.0 +32.9857988358 49.0 +33.0172758102 48.0 +33.0485799313 48.0 +33.0781269073 50.0 +33.1084318161 49.0 +33.1385409832 48.0 +33.1695408821 49.0 +33.1997499466 49.0 +33.231153965 47.0 +33.2615389824 51.0 +33.3065009117 48.0 +33.3625278473 49.0 +33.3928279877 49.0 +33.4209558964 50.0 +33.4518718719 48.0 +33.4825799465 49.0 +33.5128729343 47.0 +33.543792963 50.0 +33.5748770237 49.0 +33.6044869423 50.0 +33.6346838474 48.0 +33.6646039486 50.0 +33.7013640404 49.0 +33.7358129025 49.0 +33.7672798634 48.0 +33.7984139919 50.0 +33.8289120197 51.0 +33.8599758148 48.0 +33.8977229595 51.0 +33.9294238091 47.0 +33.9600768089 47.0 +33.990172863 53.0 +34.0198869705 47.0 +34.0495929718 49.0 +34.0805358887 48.0 +34.1111409664 51.0 +34.1426110268 50.0 +34.1731739044 47.0 +34.20418787 48.0 +34.2358360291 49.0 +34.2660839558 50.0 +34.3165419102 49.0 +34.3688468933 49.0 +34.3982489109 48.0 +34.4277839661 51.0 +34.4589679241 49.0 +34.4896810055 48.0 +34.5204598904 48.0 +34.5497858524 49.0 +34.5806999207 49.0 +34.6100800037 50.0 +34.640324831 49.0 +34.6693639755 47.0 +34.7007980347 49.0 +34.7337949276 51.0 +34.7646780014 46.0 +34.794975996 50.0 +34.8255338669 48.0 +34.8547408581 51.0 +34.8925290108 48.0 +34.9230358601 47.0 +34.9521148205 50.0 +34.982542038 49.0 +35.0135178566 51.0 +35.0439488888 48.0 +35.0733599663 49.0 +35.1032259464 49.0 +35.1329329014 51.0 +35.1630289555 49.0 +35.1941688061 45.0 +35.226585865 51.0 +35.2565259933 50.0 +35.2937698364 49.0 +35.3581488132 49.0 +35.386346817 48.0 +35.4158539772 47.0 +35.4473278522 50.0 +35.4771928787 49.0 +35.5073239803 51.0 +35.5380339622 46.0 +35.5691258907 50.0 +35.5999538898 48.0 +35.6309218407 49.0 +35.6624388695 49.0 +35.6915848255 50.0 +35.7206988335 50.0 +35.7480590343 49.0 +35.7769429684 50.0 +35.806568861 46.0 +35.8349199295 50.0 +35.8643269539 51.0 +35.901458025 48.0 +35.9309399128 48.0 +35.959676981 50.0 +35.9884769917 49.0 +36.0177140236 50.0 +36.0483369827 50.0 +36.0776548386 47.0 +36.1073548794 49.0 +36.1370539665 50.0 +36.1679418087 48.0 +36.1973400116 49.0 +36.2296378613 49.0 +36.2595479488 50.0 +36.3021528721 49.0 +36.358935833 49.0 +36.387403965 48.0 +36.4165878296 51.0 +36.4476268291 48.0 +36.4782090187 49.0 +36.5084528923 50.0 +36.5381729603 49.0 +36.5688619614 49.0 +36.5979149342 49.0 +36.6268110275 47.0 +36.6558969021 50.0 +36.6865949631 50.0 +36.7218148708 50.0 +36.7526400089 46.0 +36.7831850052 57.0 +36.8134889603 52.0 +36.8435919285 55.0 +36.8756740093 55.0 +36.9098668098 55.0 +36.9375898838 54.0 +36.9671599865 56.0 +36.9967558384 55.0 +37.0278999805 53.0 +37.058369875 56.0 +37.0891628265 54.0 +37.1192998886 36.0 +37.1513178349 53.0 +37.1810998917 51.0 +37.2118198872 48.0 +37.2437429428 50.0 +37.2767419815 49.0 +37.3303279877 49.0 +37.3749568462 50.0 +37.4055769444 46.0 +37.4395279884 51.0 +37.4692528248 50.0 +37.4989600182 48.0 +37.5306649208 50.0 +37.5614860058 51.0 +37.5920979977 49.0 +37.6229729652 49.0 +37.6522848606 49.0 +37.6807608604 48.0 +37.7110388279 50.0 +37.7433719635 48.0 +37.7742049694 48.0 +37.803237915 49.0 +37.833781004 50.0 +37.8646090031 49.0 +37.9024820328 48.0 +37.9342498779 48.0 +37.9638650417 51.0 +37.9942948818 48.0 +38.0253868103 51.0 +38.0557370186 48.0 +38.0873999596 47.0 +38.1173558235 51.0 +38.1483058929 49.0 +38.1790988445 48.0 +38.2098348141 49.0 +38.2410628796 48.0 +38.2727618217 52.0 +38.3211379051 53.0 +38.3715078831 45.0 +38.400195837 49.0 +38.430729866 49.0 +38.4599869251 46.0 +38.48960495 50.0 +38.5186388493 47.0 +38.5490918159 48.0 +38.5798838139 48.0 +38.6088218689 47.0 +38.6380670071 48.0 +38.6688499451 46.0 +38.6985738277 53.0 +38.7308239937 49.0 +38.762953043 42.0 +38.794301033 50.0 +38.8245129585 48.0 +38.8554298878 47.0 +38.8914208412 50.0 +38.9231169224 47.0 +38.9542310238 48.0 +38.984197855 50.0 +39.0150220394 50.0 +39.0440328121 49.0 +39.0738270283 49.0 +39.1017138958 49.0 +39.1308538914 51.0 +39.1606249809 48.0 +39.1910228729 49.0 +39.2206828594 49.0 +39.2515628338 54.0 +39.2851788998 48.0 +39.3427820206 46.0 +39.3808448315 49.0 +39.4108498096 48.0 +39.4416139126 48.0 +39.470459938 52.0 +39.49949193 48.0 +39.5300309658 47.0 +39.5603859425 49.0 +39.5906338692 49.0 +39.6202709675 52.0 +39.650056839 50.0 +39.6801459789 51.0 +39.7148349285 46.0 +39.7480618954 52.0 +39.778429985 49.0 +39.8089668751 47.0 +39.8393399715 51.0 +39.8744778633 49.0 +39.9075880051 46.0 +39.9372708797 50.0 +39.9678678513 47.0 +39.9980139732 48.0 +40.0289399624 12.0 +40.0593669415 255.0 +40.0898230076 3.0 +40.1196789742 250.0 +40.1514728069 248.0 +40.1813099384 5.0 +40.2127540112 23.0 +40.2439279556 4.0 +40.2780339718 6.0 +40.3341708183 254.0 +40.3778018951 37.0 +40.4082229137 22.0 +40.4384958744 5.0 +40.4675178528 13.0 +40.498185873 4.0 +40.5289969444 24.0 +40.5605478287 4.0 +40.5916650295 14.0 +40.6225349903 246.0 +40.6540329456 5.0 +40.6851828098 12.0 +40.7162768841 3.0 +40.7482488155 38.0 +40.7807748318 4.0 +40.8118629456 254.0 +40.8423190117 12.0 +40.880371809 12.0 +40.9113488197 49.0 +40.941316843 50.0 +40.9713308811 51.0 +41.0020070076 47.0 +41.0330479145 49.0 +41.0649189949 46.0 +41.0958528519 41.0 +41.1270070076 42.0 +41.1574068069 41.0 +41.1876690388 188.0 +41.2174630165 215.0 +41.2485699654 240.0 +41.2855420113 152.0 +41.342553854 21.0 +41.380753994 211.0 +41.4117498398 166.0 +41.443092823 20.0 +41.4742369652 51.0 +41.5052509308 17.0 +41.535410881 27.0 +41.5663928986 8.0 +41.5971348286 70.0 +41.6283159256 16.0 +41.6597859859 35.0 +41.6920080185 93.0 +41.7229700089 16.0 +41.7533779144 243.0 +41.7864289284 32.0 +41.8173828125 57.0 +41.8488929272 40.0 +41.8858058453 42.0 +41.9174609184 33.0 +41.9486260414 55.0 +41.979528904 37.0 +42.010751009 9.0 +42.040943861 16.0 +42.071187973 29.0 +42.1025969982 25.0 +42.1340258121 57.0 +42.1660199165 51.0 +42.1963338852 14.0 +42.2274849415 205.0 +42.2581160069 194.0 +42.3042359352 23.0 +42.3638620377 36.0 +42.3945269585 11.0 +42.4254620075 51.0 +42.4578669071 67.0 +42.4888989925 18.0 +42.5188539028 20.0 +42.5501129627 47.0 +42.5811698437 44.0 +42.6123259068 36.0 +42.6437129974 20.0 +42.6751179695 253.0 +42.7108609676 17.0 +42.7418749332 75.0 +42.7751970291 9.0 +42.8051638603 55.0 +42.8356788158 171.0 +42.8667199612 125.0 +42.9046700001 110.0 +42.9352660179 148.0 +42.9667048454 138.0 +42.9971590042 96.0 +43.0295569897 223.0 +43.0606608391 199.0 +43.0920798779 171.0 +43.1227838993 16.0 +43.1532969475 51.0 +43.1850218773 25.0 +43.2150688171 9.0 +43.2471539974 122.0 +43.285629034 249.0 +43.3448858261 185.0 +43.3822069168 197.0 +43.4135088921 61.0 +43.4452939034 83.0 +43.4754328728 40.0 +43.5057590008 163.0 +43.5372359753 132.0 +43.5689048767 254.0 +43.5987179279 255.0 +43.6301989555 8.0 +43.6612148285 76.0 +43.6936988831 18.0 +43.7247848511 52.0 +43.7561328411 30.0 +43.7895228863 5.0 +43.8192548752 207.0 +43.8504509926 165.0 +43.8880388737 132.0 +43.9195868969 123.0 +43.9508759975 245.0 +43.9818849564 142.0 +44.0133459568 208.0 +44.0447108746 231.0 +44.0754618645 73.0 +44.1071279049 140.0 +44.1386399269 116.0 +44.169811964 23.0 +44.199903965 34.0 +44.2310729027 231.0 +44.2626700401 180.0 +44.3116788864 147.0 +44.375962019 192.0 +44.4064879417 195.0 +44.4385519028 121.0 +44.4698679447 135.0 +44.5007610321 79.0 +44.5330638885 17.0 +44.564759016 189.0 +44.5968899727 168.0 +44.6270568371 30.0 +44.6586999893 111.0 +44.6906659603 198.0 +44.721020937 199.0 +44.7524898052 170.0 +44.7842469215 76.0 +44.8158369064 241.0 +44.8476138115 189.0 +44.8861989975 206.0 +44.9187049866 20.0 +44.9502060413 175.0 +44.9811060429 231.0 +45.012075901 127.0 +45.0434570312 152.0 +45.0751869678 47.0 +45.1057488918 188.0 +45.1364519596 142.0 +45.1678068638 204.0 +45.1983349323 196.0 +45.2297258377 162.0 +45.2613978386 189.0 +45.3103349209 51.0 +45.3666608334 157.0 +45.3973739147 200.0 +45.4288468361 158.0 +45.4597399235 155.0 +45.4907519817 16.0 +45.5211269855 208.0 +45.5522098541 224.0 +45.5831849575 136.0 +45.6154539585 76.0 +45.6472170353 232.0 +45.6783399582 32.0 +45.7136368752 17.0 +45.746021986 49.0 +45.778138876 216.0 +45.8096599579 162.0 +45.8409259319 44.0 +45.8754868507 10.0 +45.911896944 49.0 +45.9426920414 54.0 +45.974462986 49.0 +46.0046098232 43.0 +46.0360388756 50.0 +46.0683779716 12.0 +46.0991039276 13.0 +46.1316759586 53.0 +46.1626989841 51.0 +46.1938409805 40.0 +46.225260973 48.0 +46.2564918995 30.0 +46.294978857 41.0 +46.3600380421 42.0 +46.3901219368 48.0 +46.4213638306 50.0 +46.4525489807 42.0 +46.4830889702 41.0 +46.5139629841 27.0 +46.5450358391 50.0 +46.5765719414 38.0 +46.6070389748 52.0 +46.6379938126 49.0 +46.66898489 48.0 +46.6991829872 49.0 +46.730837822 52.0 +46.7627139091 47.0 +46.7955338955 50.0 +46.8266088963 47.0 +46.8566048145 51.0 +46.8945310116 47.0 +46.9252848625 48.0 +46.9544718266 50.0 +46.9856178761 45.0 +47.0165598392 45.0 +47.0462880135 50.0 +47.0762178898 49.0 +47.1079938412 54.0 +47.1394369602 52.0 +47.1698579788 55.0 +47.2027339935 52.0 +47.2336668968 55.0 +47.2644758224 54.0 +47.3149819374 54.0 +47.366355896 59.0 +47.3960609436 48.0 +47.4268398285 218.0 +47.4571499825 111.0 +47.48741889 56.0 +47.5188179016 57.0 +47.5485110283 57.0 +47.5786750317 54.0 +47.6087598801 57.0 +47.6395900249 55.0 +47.6696939468 54.0 +47.7012658119 55.0 +47.7315149307 53.0 +47.7627089024 59.0 +47.7938678265 53.0 +47.8253338337 56.0 +47.8544378281 52.0 +47.8917479515 56.0 +47.9239969254 57.0 +47.9543099403 54.0 +47.9855399132 53.0 +48.0163238049 56.0 +48.0470650196 54.0 +48.0773839951 57.0 +48.1080999374 55.0 +48.1386318207 54.0 +48.1696338654 54.0 +48.1992068291 57.0 +48.2276849747 53.0 +48.2572648525 56.0 +48.2969529629 58.0 +48.3611118793 51.0 +48.3910009861 56.0 +48.4205498695 53.0 +48.4520208836 55.0 +48.4834189415 56.0 +48.5135660172 55.0 +48.5443809032 54.0 +48.5752048492 56.0 +48.6065838337 56.0 +48.6347689629 56.0 +48.6634190083 54.0 +48.6978919506 52.0 +48.7340788841 57.0 +48.7670040131 56.0 +48.7994148731 56.0 +48.8289878368 53.0 +48.8592748642 54.0 +48.8978228569 55.0 +48.9288368225 57.0 +48.9598619938 55.0 +48.9909219742 53.0 +49.0200748444 56.0 +49.0511188507 56.0 +49.07990098 55.0 +49.1091868877 54.0 +49.1396818161 55.0 +49.1695678234 55.0 +49.1983258724 57.0 +49.2324268818 54.0 +49.2635958195 55.0 +49.3158459663 55.0 diff --git a/lab5/temperature_demo5/Makefile b/lab5/temperature_demo5/Makefile new file mode 100755 index 0000000..3789c62 --- /dev/null +++ b/lab5/temperature_demo5/Makefile @@ -0,0 +1,18 @@ +OBJECTS=main.o +DEVICE = msp430g2553 +INSTALL_DIR=$(HOME)/ti/msp430_gcc + +GCC_DIR = $(INSTALL_DIR)/bin +SUPPORT_FILE_DIRECTORY = $(INSTALL_DIR)/include + +CC = $(GCC_DIR)/msp430-elf-gcc +GDB = $(GCC_DIR)/msp430-elf-gdb + +CFLAGS = -I $(SUPPORT_FILE_DIRECTORY) -mmcu=$(DEVICE) -O2 -g +LFLAGS = -L $(SUPPORT_FILE_DIRECTORY) -T $(DEVICE).ld + +all: ${OBJECTS} + $(CC) $(CFLAGS) $(LFLAGS) $? -o main.elf + +debug: all + $(GDB) main.elf diff --git a/lab5/temperature_demo5/main.c b/lab5/temperature_demo5/main.c new file mode 100644 index 0000000..e6d02c4 --- /dev/null +++ b/lab5/temperature_demo5/main.c @@ -0,0 +1,274 @@ +/* + * main.c + * + * MSP-EXP430G2-LaunchPad User Experience Application + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + + * Heavily modified: Nov, 2013 Carl Michal + * Even more so, February, 2014 + + * This version modified to use the Hardware UART on MSP430G2553 + * see code at https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/msp430g2553-hardware-uart/ + * jumpers for TX/RX on Launchpad board must be rotated 90 degrees + * for hardware UART used here!! + * This may not work on all revisions of the board? + + +*/ + + +/****************************************************************************** + * MSP-EXP430G2-LaunchPad User Experience Application + * + * 1. Device starts up in LPM3 + blinking LED to indicate device is alive + * + Upon first button press, device transitions to application mode + * 2. Application Mode + * + Continuously sample ADC Temp Sensor channel + * + * + Transmit temperature value via TimerA UART to PC + * + * + * Texas Instruments, Inc. + ******************************************************************************/ + +#include "msp430.h" + +#define LED1 BIT0 +#define LED2 BIT6 + +#define BUTTON BIT3 + +#define TXD BIT2 // TXD on P1.2 +#define RXD BIT1 // RXD on P1.1 + +#define PreAppMode 0 +#define RunningMode 1 + +unsigned int TXByte; +volatile unsigned int Mode; + +void InitializeButton(void); +void PreApplicationMode(void); + +void main(void) +{ + long tempMeasured; + + WDTCTL = WDTPW + WDTHOLD; // Stop WDT + + /* next three lines to use internal calibrated 1MHz clock: */ + BCSCTL1 = CALBC1_1MHZ; // Set range + DCOCTL = CALDCO_1MHZ; + BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1MHz + + InitializeButton(); + + // setup port for leds: + P1DIR |= LED1 + LED2; + P1OUT &= ~(LED1 + LED2); + + P1DIR |= TXD; + P1OUT |= TXD; + + Mode = PreAppMode; + PreApplicationMode(); // Blinks LEDs, waits for button press + + /* Configure ADC Temp Sensor Channel */ + ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 + ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; + + __delay_cycles(1000); // Wait for ADC Ref to settle + + __enable_interrupt(); // Enable interrupts. + + /* Configure hardware UART */ + P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + UCA0CTL1 |= UCSSEL_2; // Use SMCLK + UCA0BR0 = 104; // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13) + UCA0BR1 = 0; // Set baud rate to 9600 with 1MHz clock + UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 + UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine + /* if we were going to receive, we would also: + IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt + */ + + /* Main Application Loop */ + while(1) + { + ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start + __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled turns cpu off. + // an interrupt is triggered when the ADC result is ready. + // The interrupt handler restarts the cpu. + + // store result + tempMeasured = ADC10MEM; + + + // convert to farenheit and send to host computer + TXByte = (unsigned char)( ((tempMeasured - 630) * 761) / 1024 ); + while (! (IFG2 & UCA0TXIFG)); // wait for TX buffer to be ready for new data + UCA0TXBUF = TXByte; + + P1OUT ^= LED1; // toggle the light every time we make a measurement. + + // set up timer to wake us in a while: + TACCR0 = 2400; // period + TACTL = TASSEL_1 | MC_1; // TACLK = ACLK, Up mode. + TACCR1 = 2400; // interrupt at end + TACCTL1 = CCIE; // TACCTL0 + + // go to sleep, wait till timer expires to do another measurement. + __bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled turns cpu off. + + // could have just done this - but low power mode is nicer. + // __delay_cycles(500000); + + } +} + +void PreApplicationMode(void) +{ + P1DIR |= LED1 + LED2; + P1OUT |= LED1; // To enable the LED toggling effect + P1OUT &= ~LED2; + + /* these next two lines configure the ACLK signal to come from + a secondary oscillator source, called VLO */ + + BCSCTL1 |= DIVA_1; // ACLK is half the speed of the source (VLO) + BCSCTL3 |= LFXT1S_2; // ACLK = VLO + + /* here we're setting up a timer to fire an interrupt periodically. + When the timer 1 hits its limit, the interrupt will toggle the lights + + We're using ACLK as the timer source, since it lets us go into LPM3 + (where SMCLK and MCLK are turned off). */ + + TACCR0 = 1200; // period + TACTL = TASSEL_1 | MC_1; // TACLK = ACLK, Up mode. + TACCTL1 = CCIE + OUTMOD_3; // TACCTL1 Capture Compare + TACCR1 = 600; // duty cycle + __bis_SR_register(LPM3_bits + GIE); // LPM3 with interrupts enabled + // in LPM3, MCLCK and SMCLK are off, but ACLK is on. +} + +// this gets used in pre-application mode only to toggle the lights: +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=TIMER0_A1_VECTOR +__interrupt void ta1_isr (void) +#else + void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) ta1_isr (void) +#endif +{ + TACCTL1 &= ~CCIFG; // reset the interrupt flag + if (Mode == PreAppMode){ + P1OUT ^= (LED1 + LED2); // toggle the two lights. + } + else{ + TACCTL1 = 0; // no more interrupts. + __bic_SR_register_on_exit(LPM3_bits); // Restart the cpu + } + +} + +void InitializeButton(void) // Configure Push Button +{ + P1DIR &= ~BUTTON; + P1OUT |= BUTTON; + P1REN |= BUTTON; + P1IES |= BUTTON; + P1IFG &= ~BUTTON; + P1IE |= BUTTON; +} + +/* ************************************************************* + * Port Interrupt for Button Press + * 1. During standby mode: to enter application mode + * + * *********************************************************** */ + +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=PORT1_VECTOR +__interrupt void port1_isr(void) +#else + void __attribute__ ((interrupt(PORT1_VECTOR))) port1_isr (void) +#endif +{ + + /* this disables port1 interrupts for a little while so that + we don't try to respond to two consecutive button pushes right together. + The watchdog timer interrupt will re-enable port1 interrupts + + This whole watchdog thing is completely unnecessary here, but its useful + to see how it is done. +*/ + P1IFG = 0; // clear out interrupt flag + P1IE &= ~BUTTON; // Disable port 1 interrupts + WDTCTL = WDT_ADLY_250; // set up watchdog timer duration + IFG1 &= ~WDTIFG; // clear interrupt flag + IE1 |= WDTIE; // enable watchdog interrupts + + TACCTL1 = 0; // turn off timer 1 interrupts + P1OUT &= ~(LED1+LED2); // turn off the leds + Mode = RunningMode; + __bic_SR_register_on_exit(LPM3_bits); // take us out of low power mode + +} + +// WDT Interrupt Service Routine used to de-bounce button press +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=WDT_VECTOR +__interrupt void wdt_isr(void) +#else + void __attribute__ ((interrupt(WDT_VECTOR))) wdt_isr (void) +#endif +{ + IE1 &= ~WDTIE; /* disable watchdog interrupt */ + IFG1 &= ~WDTIFG; /* clear interrupt flag */ + WDTCTL = WDTPW + WDTHOLD; /* put WDT back in hold state */ + P1IE |= BUTTON; /* Debouncing complete - reenable port 1 interrupts*/ +} + +// ADC10 interrupt service routine +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=ADC10_VECTOR +__interrupt void adc10_isr(void) +#else + void __attribute__ ((interrupt(ADC10_VECTOR))) adc10_isr (void) +#endif +{ + __bic_SR_register_on_exit(CPUOFF); // Restart the cpu +} + diff --git a/lab5/temperature_demo5/main.o b/lab5/temperature_demo5/main.o new file mode 100644 index 0000000..a99383e Binary files /dev/null and b/lab5/temperature_demo5/main.o differ diff --git a/lab5/temperature_demo5/python-serial-plot.py b/lab5/temperature_demo5/python-serial-plot.py new file mode 100755 index 0000000..faf1709 --- /dev/null +++ b/lab5/temperature_demo5/python-serial-plot.py @@ -0,0 +1,90 @@ +#!/usr/bin/python2.7 +import serial # for serial port +import numpy as np # for arrays, numerical processing +from time import sleep,time +import gtk #the gui toolkit we'll use: +# graph plotting library: +from matplotlib.figure import Figure +from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas + +#needs: python2, pyserial, numpy, matplotlib, pygtk +#0) flash the serial temperature measurement program into the msp430 +#1) start this program +#2) press the button the Launchpad to enter 'applcation mode' +#3) warm the chip (eg with a light bulb or your fingers) +#4) when you've seen enough, press the reset button on the launchpad +#5) exit the program by pressing 'q' or clicking on the x + +#define the serial port. Pick one: +port = "/dev/ttyACM0" #for Linux +#port = "COM5" #For Windows? +#port = "/dev/tty.uart-XXXX" #For Mac? + +#function that gets called when a key is pressed: +def press(event): + print('press', event.key) + if event.key == 'q': + print ('got q!') + quit_app(None) + return True + +def quit_app(event): + outFile.close() + ser.close() + quit() + +#start our program proper: +#open the serial port +try: + ser = serial.Serial(port,2400,timeout = 0.050) + ser.baudrate=9600 +# with timeout=0, read returns immediately, even if no data +except: + print ("Opening serial port",port,"failed") + print ("Edit program to point to the correct port.") + print ("Hit enter to exit") + raw_input() + quit() + +#create a window to put the plot in +win = gtk.Window() +#connect the destroy signal (clicking the x in the corner) +win.connect("destroy", quit_app) +win.set_default_size(400,300) + +yvals = np.zeros(50) #array to hold last 50 measurements +times=np.arange(0,50,1.0) # 50 from 0 to 49. + +#create a plot: +fig = Figure() +ax = fig.add_subplot(111,xlabel='Time Step',ylabel='Temp (deg F)') +ax.set_ylim(50,100) # set limits of y axis. + +canvas = FigureCanvas(fig) #put the plot onto a canvas +win.add(canvas) #put the canvas in the window + +# define a callback for when a key is pressed +fig.canvas.mpl_connect('key_press_event',press) + +#show the window +win.show_all() +win.set_title("ready to receive data"); + +line, = ax.plot(times,yvals) +#open a data file for the output +outFile = open("time_and_temp.txt","w") +start_time = time() +ser.flushInput() + +while(1): #loop forever + data = ser.read(1) # look for a character from serial port, will wait up to timeout above. + if len(data) > 0: #was there a byte to read? should always be true. + yvals = np.roll(yvals,-1) # shift the values in the array + yvals[49] = ord(data) # take the value of the byte + outFile.write(str(time()-start_time)+" "+str(yvals[49])+"\n") #write to file + line.set_ydata(yvals) # draw the line + fig.canvas.draw() # update the canvas + win.set_title("Temp: "+str(yvals[49])+" deg F") + while gtk.events_pending(): #makes sure the GUI updates + gtk.main_iteration() +# sleep(.05) # don't eat the cpu. This delay limits the data rate to ~ 200 samples/s diff --git a/lab5/temperature_demo5/python-serial-print.py b/lab5/temperature_demo5/python-serial-print.py new file mode 100755 index 0000000..cdc658e --- /dev/null +++ b/lab5/temperature_demo5/python-serial-print.py @@ -0,0 +1,37 @@ +#!/usr/bin/python2.7 +import serial # for serial port +import numpy as np # for arrays, numerical processing + +#needs: python2, pyserial, numpy, +#0) flash the serial temperature measurement program into the msp430 +#1) start this program +#2) press the button the Launchpad to enter 'applcation mode' +#3) warm the chip (eg with a light bulb or your fingers) +#4) when you've seen enough, press the reset button on the launchpad +#5) exit the program by pressing 'q' or clicking on the x + +#define the serial port. Pick one: +port = "/dev/ttyACM0" #for Linux +#port = "COM5" #For Windows? +#port = "/dev/tty.uart-XXXX" #For Mac? + + +#start our program proper: +#open the serial port +try: + ser = serial.Serial(port,2400,timeout = 0.050) + ser.baudrate=9600 +# with timeout=0, read returns immediately, even if no data +except: + print ("Opening serial port",port,"failed") + print ("Edit program to point to the correct port.") + print ("Hit enter to exit") + raw_input() + quit() + +ser.flushInput() + +while(1): #loop forever + data = ser.read(1) # look for a character from serial port - will wait for up to 50ms (specified above in timeout) + if len(data) > 0: #was there a byte to read? + print ord(data) diff --git a/lab5/temperature_demo5/serial_duplex.c b/lab5/temperature_demo5/serial_duplex.c new file mode 100644 index 0000000..341690e --- /dev/null +++ b/lab5/temperature_demo5/serial_duplex.c @@ -0,0 +1,100 @@ +/* Example code demonstrating the use of the hardware UART on the MSP430G2553 to receive + * and transmit data back to a host computer over the USB connection on the MSP430 + * launchpad. + * Note: After programming it is necessary to stop debugging and reset the uC before + * connecting the terminal program to transmit and receive characters. + * This demo will turn on the Red LED if an R is sent and turn it off if a r is sent. + * Similarly G and g will turn on and off the green LED + * It also transmits the received character back to the terminal. + +FROM: https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/msp430g2553-hardware-uart/ + + + */ + +#include "msp430.h" +void UARTSendArray(char *TxArray, char ArrayLength); + +static char data; + +void main(void) + +{ + WDTCTL = WDTPW + WDTHOLD; // Stop WDT + + P1DIR |= BIT0 + BIT6; // Set the LEDs on P1.0, P1.6 as outputs + P1OUT = BIT0; // Set P1.0 + + BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz + DCOCTL = CALDCO_1MHZ; // Set DCO to 1MHz + +/* Configure hardware UART */ + P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD + UCA0CTL1 |= UCSSEL_2; // Use SMCLK + UCA0BR0 = 104; // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13) + UCA0BR1 = 0; // Set baud rate to 9600 with 1MHz clock + UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 + UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine + IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt + +__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled +} + +// Echo back RXed character, confirm TX buffer is ready first + +#if defined(__TI_COMPILER_VERSION__) +#pragma vector=USCIAB0RX_VECTOR +__interrupt void USCI0RX_ISR(void) +#else + void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) uci0rx_isr(void) +#endif +{ +data = UCA0RXBUF; +UARTSendArray("Received command: ", 18); +UARTSendArray(&data, 1); +UARTSendArray("\n\r", 2); + +switch(data){ + case 'R': + { + P1OUT |= BIT0; + } + break; + case 'r': + { + P1OUT &= ~BIT0; + } + break; + case 'G': + { + P1OUT |= BIT6; + } + break; + case 'g': + { + P1OUT &= ~BIT6; + } + break; + default: + { + UARTSendArray("Unknown Command: ", 17); + UARTSendArray(&data, 1); + UARTSendArray("\n\r", 2); + } + break; + } +} + +void UARTSendArray(char *TxArray, char ArrayLength){ + // Send number of bytes Specified in ArrayLength in the array at using the hardware UART 0 + // Example usage: UARTSendArray("Hello", 5); + // int data[2]={1023, 235}; + // UARTSendArray(data, 4); // Note because the UART transmits bytes it is necessary to send two bytes for each integer hence the data length is twice the array length + +while(ArrayLength--){ // Loop until StringLength == 0 and post decrement + while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for new data + UCA0TXBUF = *TxArray; //Write the character at the location specified py the pointer + TxArray++; //Increment the TxString pointer to point to the next character + } +} diff --git a/lab5/temperature_demo5/time_and_temp.txt b/lab5/temperature_demo5/time_and_temp.txt new file mode 100644 index 0000000..53be6e7 --- /dev/null +++ b/lab5/temperature_demo5/time_and_temp.txt @@ -0,0 +1,171 @@ +1.77205991745 87.0 +10.0263590813 87.0 +10.6817378998 87.0 +10.8080530167 87.0 +11.1541500092 0.0 +26.2722930908 87.0 +26.5502300262 0.0 +29.9946060181 87.0 +30.1150250435 88.0 +30.4667789936 0.0 +36.3493950367 88.0 +37.739372015 88.0 +38.0597360134 0.0 +41.1656959057 88.0 +41.53591609 0.0 +44.5073740482 88.0 +45.2329130173 88.0 +45.8213620186 88.0 +45.9182698727 88.0 +46.292304039 0.0 +47.9162359238 88.0 +48.2350459099 0.0 +51.0878880024 88.0 +51.2012159824 88.0 +51.5593209267 0.0 +53.9454829693 88.0 +54.9813899994 88.0 +57.1134779453 88.0 +58.8585898876 88.0 +58.9516170025 88.0 +59.3279669285 0.0 +60.2412030697 88.0 +60.5913639069 0.0 +61.3735120296 88.0 +61.7318439484 0.0 +62.5942320824 88.0 +62.9517040253 0.0 +64.2808358669 87.0 +64.6298289299 0.0 +66.676609993 88.0 +67.4041640759 88.0 +68.1725950241 88.0 +75.216796875 88.0 +75.9059848785 87.0 +76.0256788731 88.0 +76.3773438931 0.0 +77.4960620403 88.0 +77.7985479832 0.0 +78.4848248959 88.0 +78.8059849739 0.0 +80.1690919399 88.0 +81.702039957 88.0 +81.8249678612 88.0 +82.172950983 0.0 +83.0561380386 88.0 +85.0543339252 87.0 +85.5549719334 88.0 +85.6780650616 88.0 +86.023182869 0.0 +197.485710859 87.0 +197.642025948 87.0 +197.957994938 0.0 +200.328988075 87.0 +200.63052392 0.0 +204.43433094 87.0 +204.552805901 87.0 +204.90365696 0.0 +207.021686077 87.0 +207.602361917 87.0 +208.664263964 87.0 +208.78538394 87.0 +209.13550806 0.0 +211.361093044 87.0 +211.638974905 0.0 +212.498952866 87.0 +212.807632923 0.0 +214.108011007 87.0 +214.200826883 87.0 +214.576770067 0.0 +215.203356028 87.0 +215.518167973 0.0 +216.203274965 87.0 +216.510565042 0.0 +217.959785938 87.0 +224.170849085 87.0 +224.260709047 87.0 +224.64217186 0.0 +226.045338869 87.0 +226.257998943 87.0 +226.429722071 87.0 +226.606987953 87.0 +226.695899963 87.0 +226.870508909 87.0 +227.101451874 87.0 +227.270215988 87.0 +227.371995926 87.0 +227.548193932 88.0 +227.707774878 87.0 +227.975720882 87.0 +228.151233912 87.0 +228.235579014 87.0 +228.395956993 88.0 +228.579133034 87.0 +228.723888874 87.0 +228.967443943 87.0 +229.065361023 87.0 +229.235224962 87.0 +229.483686924 87.0 +229.595293999 87.0 +229.788245916 87.0 +230.038101912 87.0 +230.147944927 87.0 +230.397887945 87.0 +230.502285957 87.0 +230.685940027 87.0 +230.857460976 88.0 +231.020709038 87.0 +231.197432041 88.0 +231.35481596 88.0 +231.520189047 87.0 +231.913542986 88.0 +232.158943892 88.0 +232.296463013 87.0 +232.426964045 88.0 +232.595606089 87.0 +232.761909008 87.0 +233.015954018 87.0 +233.096441031 88.0 +233.280994892 87.0 +233.448677063 87.0 +233.614598989 87.0 +233.794538975 87.0 +233.968185902 87.0 +234.153837919 88.0 +234.332063913 88.0 +234.631798029 87.0 +234.690438032 88.0 +234.878174067 88.0 +235.168398857 87.0 +235.324084044 88.0 +235.509407043 88.0 +235.688710928 87.0 +235.866517067 88.0 +235.956760883 87.0 +236.227550983 87.0 +238.925761938 87.0 +239.866142035 88.0 +239.985929966 88.0 +240.333611012 0.0 +241.162170887 88.0 +241.48149991 0.0 +242.113638878 88.0 +242.241039038 87.0 +242.525716066 88.0 +242.70381093 87.0 +242.798628092 88.0 +242.989850998 88.0 +243.258746862 88.0 +243.33511591 88.0 +243.531604052 88.0 +243.689504862 88.0 +243.870397091 88.0 +244.036158085 88.0 +244.219717026 88.0 +244.484622955 88.0 +244.575479984 88.0 +244.77366209 88.0 +245.063790083 88.0 +245.142785072 88.0 +245.309396029 88.0 +245.707669973 0.0