embed sensor

24
Intro to Embedded – Ping sensor William O’Connell – s3330253 Nanthakumar Thangavelu –s3207608 Introduction The goal of our project was to build a device to measure distance based around the OUSB board using the ATMEGA32, programming the device using assembler. To achieve this we decided use the parallax ping sensor which is able to measure distances between 2cm and 3m, and using a serial LCD or the LEDs built onto the OUSB board to display the distance measured. The device operation is split into 4 main sections, the device initialisation, the ping sensor operation subroutine, the display routine and delays. The general device operation is given in Figure 1.

Upload: belinda-lee

Post on 16-Nov-2015

234 views

Category:

Documents


5 download

DESCRIPTION

senser in ousb

TRANSCRIPT

Intro to Embedded Ping sensor William OConnell s3330253Nanthakumar Thangavelu s3207608

Introduction The goal of our project was to build a device to measure distance based around the OUSB board using the ATMEGA32, programming the device using assembler. To achieve this we decided use the parallax ping sensor which is able to measure distances between 2cm and 3m, and using a serial LCD or the LEDs built onto the OUSB board to display the distance measured. The device operation is split into 4 main sections, the device initialisation, the ping sensor operation subroutine, the display routine and delays. The general device operation is given in Figure 1.

Figure 1

Operation:

In device initialisation the program sets up any required registers and peripherals used. For this project it sets the stack pointer to RAMEND allowing the use of subroutine calls in the code allowing separation of code, then registers R0 and R1 are set to 0 and 1 respectively so they can be used for 0 and 1. Port B is then set as an output as this port is used to write to the serial LCD or to drive the LEDs based on which display routine is selected. Followed by a call to PingTimerSetup which sets up the 8-bit timer used when communicating with the ping sensor.The Ping sensor operation subroutine is the first subroutine call in the main loop of the program, this subroutine is responsible for controlling the ping sensor and reading in the value representing the distance measured. The communication with the sensor occurs over a single pin, with the protocol used defined in the datasheet. To begin a measurement a single pulse is sent over the line, the microcontroller must then listen on this line (setting it as an input) waiting for the response. The response sent by the sensor is a single pulse, with the width of the pulse representing the distance measured. Our project uses the built in 8-bit hardware timer to measure the width of this pulse. Once the pulse width has been measured, the communication line is then reset back to an output and the value representing the distance is read from the timer and stored in a general purpose register. Timing of the communication with the sensor required that the device be able to meet the timing requirements with the sensor. These values are given in the datasheet shown in figure 1. Figure 2

The display subroutine uses the value given by the ping subroutine and uses it to display the distance. For out project there are two methods available to be used to display the distance though they are unable to be used at the same time. The first uses the LEDs built onto the OUSB board, lighting up one of the eight LEDs depending on the distance measured, with shorter distances being represented by one of the leftmost LEDs being lit up, and longer distances represented by one of the rightmost LEDs being lit up. To display the distance on the LEDs we split each LED into representing distances of the maximum distance able to be measured by the sensor divided by the number of LEDs, resulting in each LED representing a distance of approximately 37cm. For example if the 4th LED from the left was lit up, that would mean a distance between 112cm and 150cm.The second method for displaying the measured distance using the serial LCD uses part of the example code given to drive it. This code sends one character at a time to the LCD using one pin on port b as the output. This required converting the value read from the ping sensor into ASCII characters that can be displayed on the LCD. To do this we multiplied the ping sensor value by 145, which is the distance that a single tick of the timer represents. To then convert that value into ASCII characters we subtract whichever unit of measurement we are attempting to display, until the value is less than that unit. For example, if after the multiplication the sensor value is 234, we subtract 100 from the value in a loop incrementing a counter each time until the value is less than 100. So at the end of the 100s loop, we would end up with the counter being 2. We can then add this to the ASCII value of 0 to determine the ASCII value for 2, which we then output to the LCD. Repeating this process for 10s and 1s.The final subroutine in the main loop is one that simply acts as a delay, this allows time for the ping sensor to get ready for the next measurement and to slow down the loop somewhat. This delay is equal to approximately 5ms and is implemented using a nested loop that increments two registers from 0 to 255.To test and develop our program we primarily used VMLab, checking that our registers displayed the values we were expecting, though to check timing required testing the device with the sensor.One special feature of our program is that is uses one of the hardware timers to measure the width of the pulse received from the ping sensor. This simply allows us to start the timer at the rising edge of the pulse and stop the timer at the falling edge of the pulse. To ensure that the timer was able to measure the entire pulse width required setting the timer prescaler. For the 8-bit timer to be able to measure from the rising edge to the falling edge (tIN-MAX in figure 1) a prescaler of 1024 was used. One of the problems with this approach is that the distance will be measured using 8-bit resolution, meaning the measurement will be within one of the 255 values available. But this is not entirely correct as tIN-MAX does not represent the same time as the maximum time for the timer. tIN-MAX actually occurs when the timer is at 217. Meaning 3m is represented by a value of 217, and any intermediate value a fraction of that (1.5m would be represented by a timer value of 108). This gives our device a measurement resolution of 1.3cm, which for displaying the distance in centimeters is just acceptable for out purposes. To make this more accurate there are two options, the first is to use a 16-bit timer as opposed to the 8-bit. This would allow for a lower prescaler as well as more bits representing the distance. With 65536 values for the 16-bit timer, and tIN-MAX corresponding with a value of approximately 27777, each tick would represent a distance of about 0.1mm. The second possible method is a loop that increments a counter in the subroutine itself, this has the benefit of not requiring the hardware counter, but requires more programming within the subroutine to make the loops and requires accurate knowledge of the amount of time each loop represents. Another added benefit of using the 8-bit timer is that it mostly avoids 16-bit values which can increase code complexity.ImprovementsAt the start of the project we thought that such system would be easy to design and implement but as we got closer to develop the code and looked at more small details we realised that its much more complicated due to having an LCD in the system but using ATMEGA 32 was a really good option due to it having enough memory of 32K.

Ghannt chart

Refection:William O'Connell Terrisa Pro Forma Your mark 3 I have not marked it as one more difficult because there were only a couple of times when I had difficulty in getting a portion of the program working as I wanted it to. No change To become more confident with a similar task I will need to become more familiar with coding in assembler and how to use two or more registers when calculating larger numbers (such as needing to multiply a 16-bit or larger number). I personally found the most difficult part of this project to be using the provided code for the serial LCD. Initially I had some difficulty getting the example working and converting the sensor reading to ASCII codes to display, though this was overcome with some trial and error. I initially thought that the most difficult part would be communicating with the ping sensor, but the timing restrictions on the device were easier to meet than I expected making it easy to design code that could meet the requirements.If I were doing this as part of a paid project, I would be more concerned about the accuracy of the timing (using the 16-bit timer instead of the 8-bit) and possibly attempt to move the measuring of the input pulse from the timer from simply polling the pin to watch for the rising and falling edge, to attaching the sensor to a pin that is able to trigger interrupts on the rising and falling edges, and using those interrupts to control the timer. Allowing for more processing time for other parts of the program (assuming additional functions are added, as its not really required for this project as is).

Terissa: Nanthakumar Thangavelu

I expect that the most difficult part of this project will be

Familiarizing our team with the code associated with the LCD module and ATMega32.

Before Evaluation:Evaluate the complexity of this project: 4

Write down the reasons why you have not evaluated the question as one level less difficult: Our team has yet to familiarize ourselves with the components being used for the project.

Appendix:

Appendix 1 Program code.include "C:\VMLAB\include\m32def.inc"

; Define here the variables;.def Temp =r16.def Temp2 = r17.def Temp3 = r23

.Set TicksPerLED =27.Set TickDistance = 145 ; represents 1.45mm

.DEF ZERO = R0;.DEF ONE = R1;.DEF SER_REG = R18.DEF SER_REG1 = R19.DEF DELAYL = R20 ; 24 bit counter to generate long delays.DEF DELAYM = R21 ;.DEF DELAYH = R22 ;.EQU B192 = 205;

; Define here Reset and interrupt vectors, if any;reset: rjmp start reti ; Addr $01 reti ; Addr $02 reti ; Addr $03 reti ; Addr $04 reti ; Addr $05 reti ; Addr $06 Use 'rjmp myVector' reti ; Addr $07 to define a interrupt vector reti ; Addr $08 reti ; Addr $09 reti ; Addr $0A reti ; Addr $0B This is just an example reti ; Addr $0C Not all MCUs have the same reti ; Addr $0D number of interrupt vectors reti ; Addr $0E reti ; Addr $0F reti ; Addr $10

; Program starts here after Reset;start: ; Set up stack pointer LDI Temp, LOW(RAMEND) OUT SPL, Temp LDI Temp, HIGH(RAMEND) OUT SPH, Temp

;Initialise timer for ping subroutine CALL PingTimerSetup CLR Temp MOV R0, Temp CLR Temp DEC Temp MOV R1, Temp

; Set PortB as output for LEDs LDI Temp, 0xFF OUT DDRB, Temp

forever: CALL Ping ; Read the ping sensor

;CALL Display ; Display the distance on the LEDs, cannot be used at the same time as the LCD CALL DisplayLCD ; Displays the distance on the LCD in centimeters CALL Delay ; delay for ~5Ms

rjmp forever

;;;; Converts the value stored in temp to thermometer LED display;;Display: ; If Temp < 27 Light LED 1 LDI Temp2, TicksPerLED CP Temp, Temp2 BRSH Higher1 ; Branch if same or higher ; If Temp < 27 (27 * 1) Light LED 1 LDI Temp, (1