CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

[solved] Using 2 HC-SR04 with Pic16F877A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jwoo



Joined: 22 Dec 2017
Posts: 5

View user's profile Send private message

[solved] Using 2 HC-SR04 with Pic16F877A
PostPosted: Fri Dec 22, 2017 9:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 9:46 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 23, 2017 8:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 23, 2017 9:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 23, 2017 9:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 23, 2017 11:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 23, 2017 12:37 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 28, 2017 12:49 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 28, 2017 1:44 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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