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
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
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} ;
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 ;
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++) ;
}
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) ;
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*/
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
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 ;
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 */
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 ) ;
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)
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
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 */
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] ;
}
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 ( '*' ) ;
}
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 ;
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 */
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 ) ;
}
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 ;
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.