+ All Categories
Home > Documents > GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature...

GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature...

Date post: 21-Mar-2020
Category:
Upload: others
View: 3 times
Download: 0 times
Share this document with a friend
21
Alfred Mazhindu & Simbarashe Chiweshe Page 1 CY-0205M Sensor and Actuators Lab Report for Sensor Calibration using a PIC16F84 GROUP MEMBERS ALFRED MAZHINDU - 09022270 SIMBARASHE CHIWESHE - 09016352
Transcript
Page 1: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 1

CY-0205M Sensor and Actuators

Lab Report for Sensor Calibration using a PIC16F84

GROUP MEMBERS

ALFRED MAZHINDU - 09022270

SIMBARASHE CHIWESHE - 09016352

Page 2: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 2

CONTENTS Table of Figures and Tables ............................................................................................................... 2

INTRODUCTION ............................................................................................................................. 3

The Temperature Sensor .................................................................................................................... 3

Comments on test5.c ......................................................................................................................... 3

Exercise 1: Measuring and displaying temperature ............................................................................. 3

C Code for Continuous Temperature Display in Centigrade and Fahrenheit ................................... 3

Comments on Ex 1 ........................................................................................................................ 5

Exercise 2: Display a periodically changing pattern of lights .............................................................. 5

C Code for timing the successive-approximation ADC................................................................... 5

Comments on Ex 2 ........................................................................................................................ 6

Exercise 3: Asses the LDR light measurement system........................................................................ 6

C Code for Exercise 3 .................................................................................................................... 6

Responses for Ex 3 ...................................................................................................................... 13

Exercise 4: Measuring the ambient light .......................................................................................... 13

Ex5: Adding an out-of-range indicator ............................................................................................. 14

C Code for Exercise 3 .................................................................................................................. 14

Ideas for improving the the accuracy of the system ......................................................................... 21

CONCLUSION ............................................................................................................................... 21

REFERENCE .................................................................................................................................. 21

Table of Figures and Tables Figure 1: The temperature sensor circuit for measuring positive temperatures. ...................... 3

Table 1: Table of results of exercise 3 ................................................................................. 13

Page 3: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 3

INTRODUCTION

The Laboratory session builds from the previous laboratory sessions. It focused on a linear

and non linear sensor. It also involved writing a C program for output the temperature in

Centigrade or Fahrenheit depending on the switch. The look up table approach is used for

calibrating the sensor.

The Temperature Sensor

The sensor is a linear sensor which covers a range –40 C to +110 C.

(Orange)

Vs

GND

Vout

to

ADC

0 V

5 V

LM35

(Red)

(Brown)

Figure 1: The temperature sensor circuit for measuring positive temperatures.

Comments on test5.c

The temperature reading would increase when it was held in the human hand. The lowest

reading that could be seen on the seven-segment display was a decimal 1 and the largest

value was 255. Without the sensor connected when the voltage knob was adjusted the digital

output would also change accordingly.

Exercise 1: Measuring and displaying temperature

The code below is a modification of test5.c, it continuously show the temperature reading on

the seven segment display and outputs the temperature in Centigrade or Fahrenheit’s

depending whether the switch is pressed or not.

C Code for Continuous Temperature Display in Centigrade and Fahrenheit //

// Sensors and Actuators lab3

// Data acquisition from an optical sensor

// Please type your name and your partner's name below

// Simbarashe Chiweshe & Alfred Mazhindu

//

//

const char pattern[] =

/* 0 1 2 3 4 5 6 7 */

{0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,

/* 8 9 A b C d E F */

0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e} ;

Page 4: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 4

unsigned char segments[4] ; /* storage for values to display in led

segments */

void delay(unsigned int) ;

void DecNumber(unsigned char) ;

void refresh_segments (unsigned char) ;

unsigned char adc(void) ;

void main( void)

{

unsigned char i, j ;

set_bit (STATUS, RP0) ;

TRISB = 0x00 ; /* all o/p */

TRISA = 10001b ;

clear_bit (STATUS, RP0) ;

while(1) // endless loop

{

i = adc() ;

if(PORTA&16==16);

i = 32+(9*i)/5;

for (j = 0 ; j < 30 ; j++)

{

DecNumber (i) ;

refresh_segments (i) ;

}

}

} // end of main

void delay(unsigned int n)

{

unsigned int i ;

for (i = 0 ; i < n ; i++) ;

}

void DecNumber(unsigned char value)

{

unsigned int temp ;

// put values to display in array segment

segments[2] = value / 100 ;

temp = value % 100 ;

segments[1] = temp / 10 ;

segments[0] = temp % 10 ;

}

void refresh_segments (unsigned char i)

{

PORTA = 0 ;

if (i < 100) goto miss1 ;

PORTB = pattern[segments[2]] ;

PORTA = 2 ;

delay(100) ;

PORTA = 0 ;

miss1:

if (i < 10) goto miss2 ;

Page 5: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 5

PORTB = pattern[segments[1]] ;

PORTA = 4 ;

delay(100) ;

PORTA = 0 ;

miss2:

PORTB = pattern[segments[0]] ;

PORTA = 8 ;

delay(100) ;

PORTA = 0 ;

} // end of refresh_segments

unsigned char adc(void) // successive approximation adc

{

unsigned char i, bitn0, bitn1, value=0; /* local variables */

bitn1 = 10000000b ; // set bit mask

bitn0 = ~bitn1 ; // clear bit mask

value = 0 ;

for (i = 1 ; i <= 8 ; i++)

{

value = (value | bitn1) ;

PORTB = value ;

nop () ;

nop () ; // delay necessary for reliable adc operation

if (PORTA & 1 == 0)

value=(value & bitn0) ; // Input voltage exceeded so clear bit

bitn1 = (bitn1 >> 1); // right shift set bit

bitn0 = ~bitn1; // clear bit gets right shifted

}

return value;

} // end of adc subroutine

Comments on Ex 1

The maximum temperature reached with the human thumb on in Centigrade was 30

The maximum temperature reached with the human thumb on in Fahrenheit was 86

The ambient temperature was about 22 in Centigrade and in Fahrenheit was 72

Exercise 2: Display a periodically changing pattern of lights

The code below is the modified code of test6.c but it displays a periodical changing pattern of

our choice. The program was tested and proved to be working and it was also approved by a

demonstrator.

C Code for timing the successive-approximation ADC //

// Sensors and Actuators lab3

// Data acquisition from an optical sensor

// Please type your name and your partner's name below

// Simbarashe Chiweshe & Alfred Mazhindu

//

//

void delay (void)

{

int n;

for (n=0;n< 0x3000;n++) ;

}

Page 6: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 6

char lut(char n)

{

// Declaring a look-up-table like this

// stores the data in code memory

// If the array is not declared const

// it is stored in RAM and there is not enough!

const char a[] =

{1,8,4,2,128,32,64,16} ;

return a[n] ;

}

void main( void)

{

char i, z ;

set_bit (STATUS, RP0) ;

TRISB = 0 ; /* Port B all o/p */

TRISA = 255 ; /* Port A all i/p */

clear_bit (STATUS, RP0) ;

while(1) // endless loop

{

for (i = 0 ; i < 8 ; i++)

{

PORTB = lut(i) ;

delay() ;

}

}

} // end of main

Comments on Ex 2

It is observed that the sequence of the light changed according to the patter one would

have put. Only powers of two are recognised to make a readable pattern.

Exercise 3: Asses the LDR light measurement system

Exercise 3 required modification of test7.c so that it only operated when the switch SA4 was

pressed.

C Code for Exercise 3

// This program uses LCD functions from the Matrix

// Multimedia C for PICmicros tutorial

//

// Sensors and Actuators lab3

// Data acquisition from an optical sensor

// Simbarashe Chiweshe & Alfred Mazhindu

//

//

//

void lcd_delay (int) ;

Page 7: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 7

char lcd_start ( void ) ;

char lcd_clear ( void ) ;

char lcd_print_ch ( char ) ;

char lcd_cursor ( char, char ) ;

void lcd_command ( unsigned char ) ;

/* You will have to change these bits */

/* if the hardware changes */

/* You will also need to change: */

/* setup_lcd and lcd_raw_send */

/* masks for control bits */

#define RSMASK 0x10

#define EBIT 0x05

/* defined values for delays */

/* tested up to 20Mhz PIC */

/* standard write delay */

#define PUTCH_DELAY 250

/* clear and cursor home take longer */

/* special delay for them */

#define CLEAR_DELAY 5000

/* power up delay to let the LCD settle */

#define POWER_UP_DELAY 10000

/* bit delay to let the ports settle */

#define BIT_DELAY 4

const unsigned char lcd_init [5] =

{

/* LCD initialise */

0x33,

/* Set for 4 bit operation */

0x32,

/* Set for 2 line LCD */

0x2c,

/* Select move after write */

0x06,

/* disp. on cursor off blink off */

0x0c

} ;

/* function prototypes */

char adc (void) ;

void DecNumber(int) ;

void refresh_segments (int) ;

char FindX (int) ;

void LinInterp (void) ;

int x1, x2, x ; // ****** globals to transfer data ***********

int y1, y2, y ; // ****** between main and LinInterp *********

char segments[4] ; /* storage for decimal digits to display*/

Page 8: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 8

char subX (char n) // Look-up-table values of ADC output

{

const char a[] =

{5,7,10,15,20,25,30,35,40,45,50,60,70,

80,90,100,125,150,175,200,250,256} ;

return a[n] ;

}

int subY (char n) // Look-up-table values of illumination

{ // corresponging to ADC values in subX

char i ;

const char b[] =

{9, 80, // 5 2384

5, 160, // 7 1440

3, 76, // 10 844

1, 200, // 15 456

1, 38, // 20 294

0, 208, // 25

0, 156, // 30

0, 122, // 35

0, 99, // 40

0, 82, // 45

0, 69, // 50

0, 51, // 60

0, 39, // 70

0, 31, // 80

0, 25, // 90

0, 21, //100

0, 14, //125

0, 9, //150

0, 7, //175

0, 5, //200

0, 3, //250

0, 2} ; //256

i = 2*n ;

return b[i]*256+b[i+1] ;

}

void main( void)

{

unsigned char i, j ;

set_bit (STATUS, RP0) ;

TRISB = 0x00 ; /* all o/p */

TRISA = 11111b ;

clear_bit (STATUS, RP0) ;

while(1)

{

if(PORTA &16==16)

{

i = adc() ; // convert LDR voltage to number

x = i ;

lcd_start () ; // initialise the LCD display, ADC operation

// may have sent spurious signal to LCD

Page 9: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 9

j = FindX (x) ; // find which segment in the look-up-tables

// the voltage is in

x2 = subX (j) ; y2 = subY (j) ; // get x1, x2 and y1, y2 which

j-- ; // bracket i for interpolation

x1 = subX (j) ; y1 = subY (j) ; // to find the corresponding lux

LinInterp ( ) ; // interpolate to find y for given x

// input x and output y are global variables

// display ADC output (mV)

DecNumber (x) ; // split the number into decimal digits

// stored in array segments[]

lcd_cursor ( 5, 0 ) ;

lcd_print_ch (segments[1]) ;

lcd_print_ch (segments[2]) ;

lcd_print_ch (segments[3]) ;

lcd_print_ch (segments[0]) ;

lcd_print_ch ( ' ' ) ;

lcd_print_ch ( 'm' ) ;

lcd_print_ch ( 'V' ) ;

DecNumber (y) ; // display illumination (lux)

lcd_cursor ( 5, 1 ) ;

lcd_print_ch (segments[0]) ;

lcd_print_ch (segments[1]) ;

lcd_print_ch (segments[2]) ;

lcd_print_ch (segments[3]) ;

lcd_print_ch ( ' ' ) ;

lcd_print_ch ( 'L' ) ;

lcd_print_ch ( 'u' ) ;

lcd_print_ch ( 'x' ) ;

lcd_delay(10000) ;

}

}

} // end of main

char FindX (int j) // returns upper index of x segment that

{ // j belongs to

char i,k ;

for (i = 1 ; i <= 21 ; i++)

{

k = subX (i) ;

if (j <= k) break ;

}

if ( i == 22) i = 21 ;

return i ;

}

void LinInterp (void)

{

unsigned int x2t, y2t ;

unsigned char xt ;

xt = x2 - x ;

x2t = x2 - x1 ;

y2t = y1 - y2 ;

y = y2+y2t*xt/x2t ;

Page 10: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 10

}

void DecNumber(int value)

{

unsigned int temp1, temp2 ;

// put values to display in array segment

segments[0] = value / 1000+48 ;

temp1 = value % 1000 ;

segments[1] = temp1 / 100 +48;

temp2 = temp1 % 100 ;

segments[2] = temp2 / 10 + 48 ;

segments[3] = temp2 % 10 + 48;

}

unsigned char adc(void) // successive approximation adc

{

unsigned char bitn0, bitn1, value=0; /* local variables */

char i ;

bitn1 = 10000000b ; // set bit mask

bitn0 = ~bitn1 ; // clear bit mask

value = 0 ;

for (i = 1 ; i <= 8 ; i++)

{

value = (value | bitn1) ;

PORTB = value ;

nop () ;

nop () ;// delay necessary for reliable adc operation

if (PORTA & 1 == 0)

value=(value & bitn0) ; // V exceeded so clear bit

bitn1 = (bitn1 >> 1); // right shift set bit

bitn0 = ~bitn1; // clear bit gets right shifted

}

return value;

} // end of adc subroutine

void lcd_delay ( unsigned int size )

{

unsigned int i ;

for ( i = 0 ; i < size ; i++ ) ;

}

/* sends a byte out to the LCD */

/* the byte is given by in, the */

/* mask is used to allow the */

/* state of RS to be set as well */

void lcd_raw_send ( unsigned char in,

unsigned char mask )

{

unsigned char pb ;

/* use a PIC assembler */

/* to swap the nibbles in the */

/* input */

Page 11: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 11

/* puts high nibble at the */

/* bottom of the byte */

asm swapf param00_lcd_raw_send,F

/* OR in the mask */

pb = (in & 0x0f ) | mask ;

/* OR in the other bits */

/* PORTB */

pb = pb | (PORTB & 0xc0) ;

/* send the data */

/* send the data */

/* don't disturb the other */

/* bits in PORTB */

PORTB = pb ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

/* now clock the bit out */

/* by raising and lowering E */

set_bit ( PORTB, EBIT ) ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

clear_bit ( PORTB, EBIT ) ;

/* put the low nibble back */

/* into in */

asm swapf param00_lcd_raw_send,F

/* OR in the mask */

pb = (in & 0x0f ) | mask ;

/* OR in the other bits */

/* PORTB */

pb = pb | (PORTB & 0xc0) ;

/* send the data */

/* send the data */

/* don't disturb the other */

/* bits in PORTB */

PORTB = pb ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

/* now clock the bit out */

/* by raising and lowering E */

set_bit ( PORTB, EBIT ) ;

Page 12: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 12

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

clear_bit ( PORTB, EBIT ) ;

/* do the delay here */

lcd_delay (PUTCH_DELAY) ;

}

/* puts a character at the cursor */

/* position */

char lcd_print_ch ( unsigned char in )

{

/* use raw send with RS set */

lcd_raw_send ( in, RSMASK ) ;

return 1 ;

}

/* sends a command to the LCD */

void lcd_command ( unsigned char in )

{

lcd_raw_send ( in, 0 ) ;

}

/* clear the display */

/* and home the cursor */

char lcd_clear ( void )

{

lcd_command ( 0x01 ) ;

/* do extra delay here */

lcd_delay (CLEAR_DELAY) ;

lcd_command ( 0x02 ) ;

/* do extra delay here */

lcd_delay (CLEAR_DELAY) ;

return 1 ;

}

/* position the cursor */

char lcd_cursor ( unsigned char x,

unsigned char y )

{

if ( y==0 )

{

/* position for line 0 */

y=0x80 ;

}

else

{

/* position for line 1 */

y=0xc0 ;

}

lcd_command ( y+x ) ;

return 1 ;

}

char lcd_start (void)

Page 13: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 13

{

unsigned char i ;

/* Select the Register bank 1 */

// set_bit ( STATUS, RP0 ) ;

/* set bits of PORTB for output */

/* change for different hardware */

/* clear bottom five bits for LCD */

/* don't change any other bits */

// TRISB = (TRISB & 0xc0) ;

/* Select the Register bank 0 */

// clear_bit( STATUS, RP0 );

/* give the LCD time to settle */

/* from power up */

// lcd_delay ( POWER_UP_DELAY ) ;

for ( i=0 ; i < 5 ; i++ )

{

lcd_command ( lcd_init [i] ) ;

}

lcd_clear () ;

return 1 ;

}

Responses for Ex 3

Lux(P) (Estimated value) Actual Value % Error Absolute Error

10 140 145.16 3.6 5.16

100 39 39.698 1.76 0.698

1000 8 8.928 10.39 0.928 Table 1: Table of results of exercise 3

Exercise 4: Measuring the ambient light

Page 14: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 14

The ambient illumination level falling on the LDR when it is facing upwards towards the

ceiling is 176 lux and when it is facing downwards, 30cm above the bench its 29 lux

Ex5: Adding an out-of-range indicator The accuracy of the system is very poor when the ADC output is less than 5.The code bellow is a

modification that will display **** when the readings are less than 5V.

C Code for Exercise 3

// This program uses LCD functions from the Matrix

// Multimedia C for PICmicros tutorial

//

// Sensors and Actuators lab3

// Data acquisition from an optical sensor

// Please type your name and your partner's name below

// Simbarashe Chiweshe & Alfred Mazhindu

//

//

void lcd_delay (int) ;

char lcd_start ( void ) ;

char lcd_clear ( void ) ;

char lcd_print_ch ( char ) ;

char lcd_cursor ( char, char ) ;

void lcd_command ( unsigned char ) ;

/* You will have to change these bits */

/* if the hardware changes */

/* You will also need to change: */

/* setup_lcd and lcd_raw_send */

/* masks for control bits */

#define RSMASK 0x10

#define EBIT 0x05

/* defined values for delays */

/* tested up to 20Mhz PIC */

/* standard write delay */

#define PUTCH_DELAY 250

/* clear and cursor home take longer */

/* special delay for them */

#define CLEAR_DELAY 5000

/* power up delay to let the LCD settle */

#define POWER_UP_DELAY 10000

/* bit delay to let the ports settle */

#define BIT_DELAY 4

const unsigned char lcd_init [5] =

{

/* LCD initialise */

0x33,

/* Set for 4 bit operation */

Page 15: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 15

0x32,

/* Set for 2 line LCD */

0x2c,

/* Select move after write */

0x06,

/* disp. on cursor off blink off */

0x0c

} ;

/* function prototypes */

char adc (void) ;

void DecNumber(int) ;

void refresh_segments (int) ;

char FindX (int) ;

void LinInterp (void) ;

int x1, x2, x ; // ****** globals to transfer data ***********

int y1, y2, y ; // ****** between main and LinInterp *********

char segments[4] ; /* storage for decimal digits to display*/

char subX (char n) // Look-up-table values of ADC output

{

const char a[] =

{5,7,10,15,20,25,30,35,40,45,50,60,70,

80,90,100,125,150,175,200,250,256} ;

return a[n] ;

}

int subY (char n) // Look-up-table values of illumination

{ // corresponging to ADC values in subX

char i ;

const char b[] =

{9, 80, // 5 2384

5, 160, // 7 1440

3, 76, // 10 844

1, 200, // 15 456

1, 38, // 20 294

0, 208, // 25

0, 156, // 30

0, 122, // 35

0, 99, // 40

0, 82, // 45

0, 69, // 50

0, 51, // 60

0, 39, // 70

0, 31, // 80

0, 25, // 90

0, 21, //100

0, 14, //125

0, 9, //150

0, 7, //175

0, 5, //200

0, 3, //250

0, 2} ; //256

i = 2*n ;

return b[i]*256+b[i+1] ;

}

Page 16: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 16

void main( void)

{

unsigned char i, j ;

set_bit (STATUS, RP0) ;

TRISB = 0x00 ; /* all o/p */

TRISA = 11111b ;

clear_bit (STATUS, RP0) ;

while(1)

{

if(PORTA &16==16)

{

i = adc() ; // convert LDR voltage to number

x = i ;

}

lcd_start () ; // initialise the LCD display, ADC

operation

// may have sent spurious signal to LCD

j = FindX (x) ; // find which segment in the look-up-tables

// the voltage is in

x2 = subX (j) ; y2 = subY (j) ; // get x1, x2 and y1, y2 which

j-- ; // bracket i for interpolation

x1 = subX (j) ; y1 = subY (j) ; // to find the corresponding lux

LinInterp ( ) ; // interpolate to find y for given x

// input x and output y are global variables

// display ADC output (mV)

DecNumber (x) ; // split the number into decimal digits

// stored in array segments[]

lcd_cursor ( 5, 0 ) ;

lcd_print_ch (segments[1]) ;

lcd_print_ch (segments[2]) ;

lcd_print_ch (segments[3]) ;

lcd_print_ch (segments[0]) ;

lcd_print_ch ( ' ' ) ;

lcd_print_ch ( 'm' ) ;

lcd_print_ch ( 'V' ) ;

DecNumber (y) ; // display illumination (lux)

lcd_cursor ( 5, 1 ) ;

if(i < 5)

{

lcd_print_ch ( '*' ) ;

lcd_print_ch ( '*' ) ;

lcd_print_ch ( '*' ) ;

lcd_print_ch ( '*' ) ;

}

Page 17: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 17

else

{

lcd_print_ch (segments[0]) ;

lcd_print_ch (segments[1]) ;

lcd_print_ch (segments[2]) ;

lcd_print_ch (segments[3]) ;

lcd_print_ch ( ' ' ) ;

lcd_print_ch ( 'L' ) ;

lcd_print_ch ( 'u' ) ;

lcd_print_ch ( 'x' ) ;

lcd_delay(10000) ;

}

}

} // end of main

char FindX (int j) // returns upper index of x segment that

{ // j belongs to

char i,k ;

for (i = 1 ; i <= 21 ; i++)

{

k = subX (i) ;

if (j <= k) break ;

}

if ( i == 22) i = 21 ;

return i ;

}

void LinInterp (void)

{

unsigned int x2t, y2t ;

unsigned char xt ;

xt = x2 - x ;

x2t = x2 - x1 ;

y2t = y1 - y2 ;

y = y2+y2t*xt/x2t ;

}

void DecNumber(int value)

{

unsigned int temp1, temp2 ;

// put values to display in array segment

segments[0] = value / 1000+48 ;

temp1 = value % 1000 ;

segments[1] = temp1 / 100 +48;

temp2 = temp1 % 100 ;

segments[2] = temp2 / 10 + 48 ;

segments[3] = temp2 % 10 + 48;

}

unsigned char adc(void) // successive approximation adc

{

unsigned char bitn0, bitn1, value=0; /* local variables */

char i ;

bitn1 = 10000000b ; // set bit mask

bitn0 = ~bitn1 ; // clear bit mask

value = 0 ;

Page 18: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 18

for (i = 1 ; i <= 8 ; i++)

{

value = (value | bitn1) ;

PORTB = value ;

nop () ;

nop () ;// delay necessary for reliable adc operation

if (PORTA & 1 == 0)

value=(value & bitn0) ; // V exceeded so clear bit

bitn1 = (bitn1 >> 1); // right shift set bit

bitn0 = ~bitn1; // clear bit gets right shifted

}

return value;

} // end of adc subroutine

void lcd_delay ( unsigned int size )

{

unsigned int i ;

for ( i = 0 ; i < size ; i++ ) ;

}

/* sends a byte out to the LCD */

/* the byte is given by in, the */

/* mask is used to allow the */

/* state of RS to be set as well */

void lcd_raw_send ( unsigned char in,

unsigned char mask )

{

unsigned char pb ;

/* use a PIC assembler */

/* to swap the nibbles in the */

/* input */

/* puts high nibble at the */

/* bottom of the byte */

asm swapf param00_lcd_raw_send,F

/* OR in the mask */

pb = (in & 0x0f ) | mask ;

/* OR in the other bits */

/* PORTB */

pb = pb | (PORTB & 0xc0) ;

/* send the data */

/* send the data */

/* don't disturb the other */

/* bits in PORTB */

PORTB = pb ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

/* now clock the bit out */

/* by raising and lowering E */

Page 19: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 19

set_bit ( PORTB, EBIT ) ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

clear_bit ( PORTB, EBIT ) ;

/* put the low nibble back */

/* into in */

asm swapf param00_lcd_raw_send,F

/* OR in the mask */

pb = (in & 0x0f ) | mask ;

/* OR in the other bits */

/* PORTB */

pb = pb | (PORTB & 0xc0) ;

/* send the data */

/* send the data */

/* don't disturb the other */

/* bits in PORTB */

PORTB = pb ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

/* now clock the bit out */

/* by raising and lowering E */

set_bit ( PORTB, EBIT ) ;

/* let the bits settle */

lcd_delay ( BIT_DELAY ) ;

clear_bit ( PORTB, EBIT ) ;

/* do the delay here */

lcd_delay (PUTCH_DELAY) ;

}

/* puts a character at the cursor */

/* position */

char lcd_print_ch ( unsigned char in )

{

/* use raw send with RS set */

lcd_raw_send ( in, RSMASK ) ;

return 1 ;

}

/* sends a command to the LCD */

void lcd_command ( unsigned char in )

{

lcd_raw_send ( in, 0 ) ;

}

Page 20: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 20

/* clear the display */

/* and home the cursor */

char lcd_clear ( void )

{

lcd_command ( 0x01 ) ;

/* do extra delay here */

lcd_delay (CLEAR_DELAY) ;

lcd_command ( 0x02 ) ;

/* do extra delay here */

lcd_delay (CLEAR_DELAY) ;

return 1 ;

}

/* position the cursor */

char lcd_cursor ( unsigned char x,

unsigned char y )

{

if ( y==0 )

{

/* position for line 0 */

y=0x80 ;

}

else

{

/* position for line 1 */

y=0xc0 ;

}

lcd_command ( y+x ) ;

return 1 ;

}

char lcd_start (void)

{

unsigned char i ;

/* Select the Register bank 1 */

// set_bit ( STATUS, RP0 ) ;

/* set bits of PORTB for output */

/* change for different hardware */

/* clear bottom five bits for LCD */

/* don't change any other bits */

// TRISB = (TRISB & 0xc0) ;

/* Select the Register bank 0 */

// clear_bit( STATUS, RP0 );

/* give the LCD time to settle */

/* from power up */

// lcd_delay ( POWER_UP_DELAY ) ;

for ( i=0 ; i < 5 ; i++ )

{

lcd_command ( lcd_init [i] ) ;

}

lcd_clear () ;

return 1 ;

Page 21: GROUP MEMBERS · The code below is a modification of test5.c, it continuously show the temperature reading on the seven segment display and outputs the temperature in Centigrade or

Alfred Mazhindu & Simbarashe Chiweshe Page 21

}

Ideas for improving the the accuracy of the system

The system can be made more accurately by increasing the number of illumination values

stored i.e. small steps in the values so as to try and cater for all values possible.

CONCLUSION

The laboratory session has enhanced our programming skills and it has also shown us how

practical the subject is. We have also learnt an application of a sensor, and seen how a sensor

can gather outside data from the enviroment in analouge form and how the data is then

converted to digital form before it is prosseced and then outputs a digital value. Moreover

sensor calibrillation has also been a concept that has been grased in the lab session. Since this

was the last lab session of the module an overall conclusion can be drawn that sensors are

essential in data logging externall readings and PIC make the interfacing on the sensors and

actuators possible and relatively easy.

REFERENCE

JIANG. P 2010-1 SEM1 SENSORS AND ACTUATORS (CY-0205M_2010-1_SEM1_A) > DOCUMENTS > RESOURCES - PING JIANG > LABORATORY EXPERIMENTS > C CODE > S&A_C_LAB3.


Recommended