Lab 5 and 6 notes.

This commit is contained in:
Jonathan Chan 2018-02-17 14:01:43 -08:00
parent 39d41e5cd8
commit 76a9201164
3 changed files with 100 additions and 0 deletions

0
labnotes/Lab 5 and 6.out Normal file
View File

BIN
labnotes/Lab 5 and 6.pdf Normal file

Binary file not shown.

100
labnotes/Lab 5 and 6.tex Normal file
View File

@ -0,0 +1,100 @@
\documentclass[letterpaper]{article}
\author{Jonathan Chan (15354146)}
\title{PHYS 319\\Labs 5 and 6 Notes}
\usepackage{fullpage}
\usepackage{minted}
\usepackage{siunitx}
\usepackage{hyperref}
\begin{document}
\maketitle
The goal of this lab is to measure distances with the ultrasonic ranger. References to specific values and other documentation notes refer to \url{http://www.robot-electronics.co.uk/htm/srf04tech.htm}. The steps to achieve this can be outlined as follows:
\begin{enumerate}
\item Send a trigger pulse to the ranger. According to the documentation, this pulse needs to be $\SI{10}{\micro s}$ long.
\item Wait for the echo input to be raised. This can be done by setting a low-to-high interrupt on the echo pin.
\item Time the length of the echo pulse sent by the ranger. We will set \texttt{TAR} to 0 and retrieve the value of \texttt{TAR} when the echo pin is lowered, which can be done by setting a high-to-low interrupt on the echo pin. We will use the SMCLK timer, which runs at $\SI{1}{M\hertz}$, meaning that the maximum length that can be measured without overflowing is $\SI{65 535}{\micro s}$. However, according to the documentation, the ranger will time out and lower the echo pin after $\SI{30 000}{\micro s}$, so we aren't in danger of overflowing.
\item Convert the measurement to distance in centimetres. According to the documentation, we need to divide by $58$. Since we're limited to sending one byte at a time, we can also set the value to $0$ if the distance exceeds $\SI{255}{cm}$ to prevent the plot from graphing meaningless overflowed values.
\item Send the data to the Python plot. This portion of the code will come from the provided temperature measurement program.
\item Repeat the measurement. According to the documentation, we need to wait $\SI{10}{ms}$ to allow the ranger to recharge. I've set the delay to $\SI{100}{ms}$ to smooth out the data and prevent rapid changes in the position of the ranger from being recorded.
\end{enumerate}
With some measurements using a metre stick, the distances measured by the ranger are indeed accurate to the centimetre. It also appears that it cannot measure anything closer than $\SI{3}{cm}$. Of course, we are also upper-bounded at $\SI{255}{cm}$ by the size of one byte, even if the limit of the ranger itself is $\SI{30 000}{\micro s} / \SI{58}{\micro s*cm^{-1}} \approx \SI{517}{cm}$. We can circumvent this by dividing the the value by $2$ in the C program then multiplying it by $2$ again in the Python program, so that the maximum measurable distance is $\SI{510}{cm}$, at the cost of decreasing the precision to a granularity of $\SI{2}{cm}$.
Below is the modified \texttt{main.c} file, with the remaining files unchanged from \url{http://www.phas.ubc.ca/~michal/phys319/temperature_demo4.zip}. Of course, the axis ranges and labels of the plot should be adjusted accordingly. After the C program has been written to the microprocessor, connect P1.4 to the ranger's trigger pin, connect P1.6 to the ranger's echo pin through a $\SI{1}{k\ohm}$ resistor, connect the ranger to $\SI{5}{V}$ and ground, connect the microprocessor to ground, and run \texttt{python python-serial-plot.py}.
\newpage
\noindent \textit{\texttt{main.c}}:
\begin{minted}{c}
#include "msp430.h"
#define TXD BIT2
#define RXD BIT1
#define TRIG BIT4
#define ECHO BIT6
#define CM 58
unsigned int TXByte;
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1 MHz
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
P1DIR |= TXD;
P1OUT |= TXD;
P1DIR |= TRIG; // set trigger output
P1DIR &= ~ECHO; // set echo input
P1IE |= ECHO; // use echo input as interrupt
TACTL = TACLR; // reset clock
TACTL = TASSEL_2 | MC_2; // set SMCLK timer to count up at 1 MHz
__enable_interrupt();
while (1) {
P1OUT |= TRIG; // start trigger signal
__delay_cycles(10); // we need a >10 us pulse and one clock cycle is 1 us
P1OUT &= ~TRIG; // end trigger signal
P1IES &= ~ECHO; // interrupt on low to high
__bis_SR_register(LPM0_bits + GIE);
TAR = 0;
P1IES |= ECHO; // interrupt on high to low
__bis_SR_register(LPM0_bits + GIE);
TXByte = TAR / CM; // distance in cm
TXByte = (TXByte <= 0xFF) * TXByte; // set to 0 if beyond range
while (!(IFG2 & UCA0TXIFG)); // wait for TX buffer to be ready for new data
UCA0TXBUF = TXByte;
__delay_cycles(100000); // wait >10 ms before measuring again
}
}
// handle P1.3 interrupts
#if defined(__TI_COMPILER_VERSION__)
#pragma vector=PORT1_VECTOR
__interrupt void port1_isr(void)
#else
void __attribute__ ((interrupt(PORT1_VECTOR))) port1_isr (void)
#endif
{
P1IFG = 0; // reset interrupt flag
__bic_SR_register_on_exit(LPM0_bits); // take us out of low power mode
}
\end{minted}
\noindent \textit{\texttt{serial-python-plot.py}}:
\begin{minted}{python}
...
ax = fig.add_subplot(111,xlabel='Time Step',ylabel='Distance (cm)')
ax.set_ylim(0,255) # set limits of y axis.
...
\end{minted}
\end{document}