mattycha
Newbie level 5
Hi. I am trying to replicate a project from best-microcontroller-example.
This is an ultrasonic range dectector project. Initially, it's written in 16F88
but I am changing into 18F2455. Also, original code was written in mikroC
but I am switching to C18.
The problem I am having is that even though my US range detector is
about 11cm about from the wall, the LCD reading is 23641......
I am not sure why the LCD is displaying such a large value. I changed the
binary into decimal using a function "putdec". I am using 20MHz crystal and
I calculated to produce a period of 40kHz on RC1. RC2 is the receiving pin,
trying to capture the signal using CCP1CON=0b00000101.
Could someone please explain what I am doing wrong here? How can I fix
the problem so I can display a correct range??
This is an ultrasonic range dectector project. Initially, it's written in 16F88
but I am changing into 18F2455. Also, original code was written in mikroC
but I am switching to C18.
The problem I am having is that even though my US range detector is
about 11cm about from the wall, the LCD reading is 23641......
I am not sure why the LCD is displaying such a large value. I changed the
binary into decimal using a function "putdec". I am using 20MHz crystal and
I calculated to produce a period of 40kHz on RC1. RC2 is the receiving pin,
trying to capture the signal using CCP1CON=0b00000101.
Code:
#include <p18f2455.h>
#include <delays.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config LVP = OFF
#pragma config MCLRE = ON
#pragma interrupt MyHighInt
#pragma code high_vector=0x08
void MyHighInt(void);
void high_vector(void);
void enable_interrupts(void);
void disable_interrupts(void);
void ultrasonic(void);
void display(unsigned int value);
void welcome();
void clearLCD();
void writeData(unsigned char data);
void sendData(unsigned char data);
void writeString(const char rom *str);
void putdec(unsigned int n);
unsigned int T1_O = 0; //timer1 overflow updated in interrupt routine
unsigned int t_capL = 0; //timer1 low
unsigned int t_capH = 0; //timer1 high
unsigned int t_capO = 0; //timer1 overflow
unsigned int CapVal = 0; //capture
unsigned short CapInt = 0; //captured something in interrupt routine
unsigned short CapOn = 1; //capture only 1st value
#define send PORTCbits.RC1
#define LCDData PORTB
#define rs PORTAbits.RA3
#define rw PORTAbits.RA2
#define en PORTAbits.RA5
void high_vector(void)
{
_asm GOTO MyHighInt _endasm
}
#pragma code
void MyHighInt(void)
{
if(PIR1bits.TMR1IF == 1)
{
PIR1bits.TMR1IF = 0; //clear timer1 overflow bit
T1_O++;
}
if(PIR1bits.CCP1IF == 1)
{
PIR1bits.CCP1IF = 0; //clear capture flag
if(CapOn == 1)
{
CapOn = 0;
t_capL = CCPR1L;
t_capH = CCPR1H;
t_capO = T1_O;
CapInt = 1;
}
}
}
void main(void)
{
unsigned int val, s1, s2, tH, tL, tO;
unsigned long calc = 0;
CCP1CON = 0b00000101; //CCP to capture every rising edge
T1CONbits.TMR1ON = 1; //timer1 on
ADCON0 = 0;
ADCON1 = 0x0F;
PORTB = 0;
TRISB = 0;
TRISCbits.TRISC1 = 0; //
TRISCbits.TRISC2 = 1; //receive US signal
// LCD
TRISAbits.TRISA3 = 0;
TRISAbits.TRISA2 = 0;
TRISAbits.TRISA5 = 0;
rs = 0;
rw = 0;
en = 0;
CapInt = 0; //reset capture indicator
for(;;)
{
CapOn = 1; //allow one capture value
tO = T1_O; //get the current value
tH = TMR1H;
tL = TMR1L;
t_capL = 0; t_capH = 0; t_capO = 0; //initialize capture
ultrasonic();
enable_interrupts();
display(val);
disable_interrupts();
if(CapInt == 0) //no echo??
{
enable_interrupts();
display(val);
disable_interrupts();
}
else if(CapInt == 1) //captured anything??
{
CapInt = 0; //reset for next time
s1 = (t_capH - tH);
s2 = (t_capL - tL);
calc = ((s1<<8))+s2;
calc *= 34;
calc /= 10000; //(1/20MHz)*340m/s*100cm/m*2
val = (int)calc;
display(val);
}
clearLCD();
}
}
void enable_interrupts(void)
{
PIR1bits.TMR1IF = 0; //timer1
PIR1bits.CCP1IF = 0; //capture
PIE1bits.CCP1IE = 1; //interrupt enable
INTCONbits.GIE = 1; //enable global interrupt
INTCONbits.PEIE = 1; //enable peripheral interrupt
}
void disable_interrupts(void)
{
INTCONbits.GIE = 0; //disable global interrupt
INTCONbits.PEIE = 0; //disable peripheral interrupt
}
void ultrasonic(void)
{
send = 1;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
Delay1TCY();
send = 0;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
send = 1;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
Delay1TCY();
send = 0;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
send = 1;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
Delay1TCY();
send = 0;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
send = 1;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
Delay1TCY();
send = 0;
Delay10TCYx(6);
Delay1TCY();
Delay1TCY();
}
void display(unsigned int value) {
welcome();
sendData(0xC0); // line 2, position 0
writeString("Dist:");
sendData(0xC5);
putdec(value);
Delay1KTCYx(5000); //wait for 1second
}
void welcome()
{
Delay1KTCYx(250); // Wait 20ms
sendData(0x38); // Set LCD to 8-bit operation, 2-line display and 5 x 8 dot character font
Delay1KTCYx(250); // Wait 2ms
sendData(0x0E); // Turn LCD display off, cursor off and blinker off
Delay1KTCYx(15); // Wait 2ms
sendData(0x01); // Clear LCD display
Delay1KTCYx(15); // Wait 2ms
sendData(0x06); // Set LCD entry mode to increment by one and to shift the cursor to the right. No display shift.
sendData(0x80);
writeString("Ultrasonic in cm");
}
void clearLCD()
{
Delay1KTCYx(250); // Wait 20ms
sendData(0x38); // Set LCD to 8-bit operation, 2-line display and 5 x 8 dot character font
Delay1KTCYx(250); // Wait 2ms
sendData(0x0E); // Turn LCD display off, cursor off and blinker off
Delay1KTCYx(15); // Wait 2ms
sendData(0x01); // Clear LCD display
Delay1KTCYx(15); // Wait 2ms
sendData(0x06); // Set LCD entry mode to increment by one and to shift the cursor to the right. No display shift.
}
void sendData(unsigned char data) {
LCDData = data;
rs = 0;
rw = 0;
en = 1;
Delay1KTCYx(1);
en = 0;
}
void writeData(unsigned char data) {
LCDData = data;
rs = 1;
rw = 0;
en = 1;
Delay1KTCYx(1);
en = 0;
}
void writeString(const char rom *str) {
while( *str ) {
writeData(*str);
str++;
}
}
void putdec(unsigned int n)
{
unsigned int rem = n % 10;
unsigned int quot = n / 10;
if (quot > 0)
{
putdec(quot);
}
writeData(rem + '0');
}
Could someone please explain what I am doing wrong here? How can I fix
the problem so I can display a correct range??