|
|
View previous topic :: View next topic |
Author |
Message |
jwoo
Joined: 22 Dec 2017 Posts: 5
|
[solved] Using 2 HC-SR04 with Pic16F877A |
Posted: Fri Dec 22, 2017 9:12 am |
|
|
Hello friends. I am trying to use the LM35 to take the temperature value to the LCD screen and to use the two distance sensors to do the counting. The distance sensors work separately well, the first sensor increases the number of people according to the specified distance, and the second decreases the number of people. My problem is that I can not use two distance sensors together, they are continuously increasing when they are working together. I expect your answers, thank you.
Code: | #define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_ENABLE_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_D6
//End LCD module connections
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#device ADC=10
#use delay(clock = 4MHz)
#include <lcd.c>
#use fast_io(b)
#use fast_io(d)
int sum=0;
char temperature[] = " 00.0 C";
unsigned int16 temp,i,distance;
void main(){
setup_adc(ADC_CLOCK_INTERNAL); // ADC Module uses its internal oscillator
setup_adc_ports(AN0); // Configure AN0 pin as analog
set_adc_channel(0); // Select channel 0 (AN0)
output_b(0);
set_tris_b(0b00000010); //RB1 as a input
set_tris_b(0b00001000); //RB3 as a input
lcd_init(); // Initialize LCD module
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2);
set_timer1(0);
lcd_putc('\f'); // Clear LCD
lcd_gotoxy(1, 1); // Go to column 1 row 1
printf(lcd_putc, "Temperature:");
//lcd_gotoxy(1, 2);
//lcd_putc("Distance:");
while(TRUE){
delay_ms(1000);
temp = read_adc() * 0.489; // Read analog voltage and convert it to degree celsius (0.489 = 500/1023)
if (temp > 99)
temperature[0] = 1 + 48; // Put 1 (of hundred)
else
temperature[0] = ' '; // Put space
temperature[1] = (temp / 10) % 10 + 48;
temperature[2] = temp % 10 + 48;
temperature[5] = 223; // Degree symbol
lcd_gotoxy(12, 1); // Go to column 5 row 2
printf(lcd_putc, temperature); // Display LM35 temperature result
// distance sensor
i = 0;
output_high(PIN_B0);
delay_us(10);
output_low(PIN_B0);
set_timer1(0);
while(!input(PIN_B1) && (get_timer1() < 1000));
while(input(PIN_B1) && (i < 25000))
i = get_timer1(); // Store Timer1 value in i
distance = (i/58); // Calculate the distance
lcd_gotoxy(1, 2);
if(distance <= 10)
{
sum ++;
}
printf(lcd_putc,"Kisi = %d", sum);
i = 0;
output_high(PIN_B2);
delay_us(10);
output_low(PIN_B2);
set_timer1(0); // Reset Timer1
while(!input(PIN_B3) && (get_timer1() < 1000));
while(input(PIN_B3) && (i < 25000))
i = get_timer1(); // Store Timer1 value in i
distance = (i/58); // Calculate the distance
lcd_gotoxy(1, 2);
if(distance <= 10)
{
sum --;
}
printf(lcd_putc,"Kisi = %d", sum);
}
} |
Last edited by jwoo on Mon Jan 01, 2018 1:48 pm; edited 2 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Fri Dec 22, 2017 9:46 am |
|
|
Each will 'see' the signal from the other. This is inherent. Think about an echo in a room. One sound source, one echo. However if you have two sound sources you will hear the echo from one, and also the echo (and the sound itself) from the other.
You can use multiple sensors (provided they are aimed away from each other), by using time. You pulse one, and wait for it to see it's reply, then pulse the next and get it's reply. With a time gap between the sensors. The time gap needs to be long enough for all echoes from the first to have ceased before you look at the second. |
|
|
jwoo
Joined: 22 Dec 2017 Posts: 5
|
|
Posted: Sat Dec 23, 2017 8:52 am |
|
|
Ttelmah wrote: |
You can use multiple sensors (provided they are aimed away from each other), by using time. You pulse one, and wait for it to see it's reply, then pulse the next and get it's reply. With a time gap between the sensors. The time gap needs to be long enough for all echoes from the first to have ceased before you look at the second. |
I tried it with delay command, but again I did not succeed, the number of people on the screen constantly increases and decreases. So the sum value equals 0. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sat Dec 23, 2017 9:42 am |
|
|
How are you implementing "delay command" ?
You've got two people counts which sum to zero.
Where do you get negative people from?
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Sat Dec 23, 2017 9:58 am |
|
|
comments
1) this...
setup_adc(ADC_CLOCK_INTERNAL);
is probably wrong. Please read the ADC section,look at the table of valid clock selections....
2) tidy up your code by using functions. You've got 5 main parts, so it's easy for each to have it's own function
a) read LM35
b) read people sensor #1
c) read people sensor #2
d) display temperature
e) display people count
By doing this you make main() code easier to read and debug. Also helps us 'old guys' figure out why your code doesn't work !
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Sat Dec 23, 2017 11:51 am |
|
|
Also:
Code: |
set_tris_b(0b00000010); //RB1 as a input
set_tris_b(0b00001000); //RB3 as a input
|
You do realise that TRIS is not cumulative?. The second function overrides the first....
To set RB1 and RB3 as inputs you want:
Code: |
set_tris_b(0b00001010); //RB3 & RB1 as a inputs
|
You have RB1 actually set as an output. No wonder the second module doesn't actually work.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Sat Dec 23, 2017 12:37 pm |
|
|
THAT'S the problem with trying to be 'clever' and use 'fast_IO()' unless you get it right you'll cause hours if not DAYS of pain trying to code/recode/recompile/retest/repeat...to get even the simplest code to work.
The ONLY time you need to use fast_IO is a) very,very time critical code and/or b) very small codespace( small program memory ) |
|
|
jwoo
Joined: 22 Dec 2017 Posts: 5
|
|
Posted: Thu Dec 28, 2017 12:49 pm |
|
|
Thank you for your answers. I used an old function on the site to calculate the distance, and the system works fine with the delay when I use it. However, I don't want the second sensor to work on the first sensor job, or I don't want the first sensor to run when the second sensor runs. How can I do that?
Code: | #define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_ENABLE_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_D6
//End LCD module connections
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#device ADC=10
#use delay(clock = 4MHz)
#include <lcd.c>
#define trig1 pin_b0
#define echo1 pin_b1
#define trig2 pin_b2
#define echo2 pin_b3
int sum=0;
char temperature[] = " 00.0 C";
unsigned int16 temp,distance,distance1;
int16 get_range(int16 trigger,int16 echo)
{
int16 count=0;
while(input(echo)); //This will wait if the unit is still
output_high(trigger);
delay_us(10);
output_low(trigger); //10uSec trigger pulse
while ((input(echo)==0)); //wait for distance/time pulse to be raised
set_timer1(0); //initiate timer once the distance/time pulse starts
while ((input(echo)==1) && ((count=get_timer1())<15000)) ;
//It is the positive pulse width of the return signal that defines distance
if (count>=15000)
return 420;
//at your clock rate, timer1/8, counts every 1.6uSec
//distance in cm is then approx count/36
return count/36;
}
void main(){
setup_adc_ports(AN0); // Configure AN0 pin as analog
setup_adc(adc_clock_div_32); // ADC clock frequency fosc/32
set_adc_channel(0); // Select channel 0 (AN0)
delay_us(20);
lcd_init(); // Initialize LCD module
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2);
set_timer1(0);
lcd_putc('\f'); // Clear LCD
lcd_gotoxy(1, 1); // Go to column 1 row 1
printf(lcd_putc, "Temperature:");
while(TRUE){
delay_ms(1000);
temp = read_adc() * 0.489; // Read analog voltage and convert it to degree celsius (0.489 = 500/1023)
if (temp > 99)
temperature[0] = 1 + 48; // Put 1 (of hundred)
else
temperature[0] = ' '; // Put space
temperature[1] = (temp / 10) % 10 + 48;
temperature[2] = temp % 10 + 48;
temperature[5] = 223; // Degree symbol
lcd_gotoxy(12, 1); // Go to column 5 row 2
printf(lcd_putc, temperature); // Display LM35 temperature result
// distance sensor
distance=get_range(trig1,echo1); //function one
lcd_gotoxy(1, 2);
if(distance <= 10)
{
sum ++;
}
printf(lcd_putc,"Kisi = %d", sum);
delay_ms(3000);
distance1=get_range(trig2,echo2); //function two
lcd_gotoxy(1, 2);
if(distance1 <= 10)
{
sum --;
}
printf(lcd_putc,"Kisi = %d", sum);
}
delay_ms(1000);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Thu Dec 28, 2017 1:44 pm |
|
|
What you post now ought to work. Unless I'm missing something.
Unless you physically switch the sensor supplies off, they are always going to hear the other signal, but with the delays between this doesn't matter. You would have to use different sensors for them not to hear each other.
There are some timing problems possible because of using the variable for the pin names. Understand that it takes a lot of clock cycles to use a variable like this, so (for instance) the actual trigger pulse width will be much longer than required. Similarly the tests will have extra delays.
Honestly, just use the standard function without variables and generate two copies for the different pins. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|