Multiple usage of ultrasonic HC-SR04 sensors

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
ghchc_4077826
Level 1
Level 1

Hello all,

I have a question regarding the ultrasonic HC-SR04 sensors and PSoC.

What I did until now:

I followed up the example from here: Intro to Cypress (Part 2): 3 Steps . It lights up an LED when the sensor detects an object at a specific distance. It's really simple to implement (for me because I'm a newbie to PSoC) and it works fine with one sensor. After this I tried to add one more sensor to work in the same time with the first one. What I did was to create 2 different functions with the same instructions but with different names that I tried to call them from the main function. The problem I encountered is that just one of the LED's is blinking. If I call both functions(for example): sensor1(); and after sensor2(); the PSoC seems to execute just the first one called.

My question would be: How can I attach  2 or more sensors to the PSoC to work all in the same time ?

P.S. When I put the instrunctions for both of the sensors in the same function, they work both without a problem.

Thank you in advance. Have a nice day!

pastedImage_0.png

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Oh, OK, how about changing your main.c like below then?

==========================

/* ========================================

* HC-SR04 test program for CY8CKIT-044

* For this appliation, VDD must be set to 5V

* Set J9 Jumper to 3+2.

* ========================================

*/

#include "project.h"

volatile int counter1, counter2;

int sensor1(void)

{

    CyDelay(500);

    TRIGGER1_Write(0);

    CyDelay(500);

//    for(;;) // <-- comment out

//    {        // <-- comment out

        TRIGGER1_Write(1);

        CyDelay(10u);    

        TRIGGER1_Write(0);

       

        while(ECHO1_Read()==0)

        {

        }

        counter1 = 0 ;

        while(ECHO1_Read()==1)

        {

            counter1++;

        }

        if(counter1 < 580)

        {

            LED1_Write(1);    

        }

        if(counter1>580)

        {

            LED1_Write(0);

        }    

//    }     // <-- comment out

}

int sensor2(void)

{

    CyDelay(500);

    TRIGGER2_Write(0);

    CyDelay(500);

//    for(;;)  // <-- comment out

//    {  // <-- comment out

        TRIGGER2_Write(1);

        CyDelay(10u);    

        TRIGGER2_Write(0);

       

        while(ECHO2_Read()==0)

        {

        }

        counter2 = 0 ;

        while(ECHO2_Read()==1)

        {

            counter2++;

        }

        if(counter2 < 580)

        {

            LED2_Write(1);    

        }

        if(counter2>580)

        {

            LED2_Write(0);

        }    

//    }     // <-- comment out

}

int main(void)

{   

    CyGlobalIntEnable; /* Enable global interrupts. */   

    for(;;) {

        sensor1() ;

        sensor2() ;

    }

}

/* [] END OF FILE */

==========================

moto

View solution in original post

0 Likes
5 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I tried using CY8CKIT-044.

As right now I have only 1 sensor, I tested one by one,

but both seems to be working.

I set the threshold distance to 12cm.

schematic

schematic.JPG

main.c

===================

/* ========================================

* HC-SR04 test program for CY8CKIT-044

* For this appliation, VDD must be set to 5V

* Set J9 Jumper to 3+2.

* ========================================

*/

#include "project.h"

#include <stdio.h>

/* https://keisan.casio.jp/exec/system/1231998943 */

#define MACH    346.513     /* Mach 1.0 at 25.0 */

#define MODE_IDLE      0

#define MODE_RUNNING   1

#define MODE_MEASURED  2

#define THRESHOLD      12.0 /* 12cm */

double threshold1 = THRESHOLD ;

double threshold2 = THRESHOLD ;

uint32_t length1 ;

uint32_t length2 ;

int measure1_flag ;

int measure2_flag ;

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_UartPutString(str) ; /* for PSoC 4 */

}

CY_ISR(echo1_rise_isr)

{

    echo1_rise_int_Disable() ;

    echo1_rise_int_ClearPending() ;

    echo1_fall_int_Enable() ;

    Timer1_WriteCounter(0) ;

    Timer1_Start() ;

}

CY_ISR(echo1_fall_isr)

{

    echo1_fall_int_Disable() ;

    echo1_fall_int_ClearPending() ;

    Timer1_Stop() ;

    length1 = Timer1_ReadCounter() ;

    measure1_flag = MODE_MEASURED ;

}

CY_ISR(echo2_rise_isr)

{

    echo2_rise_int_Disable() ;

    echo2_rise_int_ClearPending() ;

    echo2_fall_int_Enable() ;

    Timer2_WriteCounter(0) ;

    Timer2_Start() ;

}

CY_ISR(echo2_fall_isr)

{

    echo2_fall_int_Disable() ;

    echo2_fall_int_ClearPending() ;

    Timer2_Stop() ;

    length2 = Timer2_ReadCounter() ;

    measure2_flag = MODE_MEASURED ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    Clock_12MHz_Start() ;

    UART_Start() ;

   

    echo1_rise_int_ClearPending() ;

    echo1_rise_int_StartEx(echo1_rise_isr) ;

    echo1_rise_int_Disable() ;

   

    echo1_fall_int_ClearPending() ;

    echo1_fall_int_StartEx(echo1_fall_isr) ;

    echo1_fall_int_Disable() ;

   

    echo2_rise_int_ClearPending() ;

    echo2_rise_int_StartEx(echo2_rise_isr) ;

    echo2_rise_int_Disable() ;

   

    echo2_fall_int_ClearPending() ;

    echo2_fall_int_StartEx(echo2_fall_isr) ;

    echo2_fall_int_Disable() ;

   

    Timer1_Start() ;

    Timer2_Start() ;

}

/**

* pulse_trigger

* Generate 10us high pulse from trigger pin

*/

void pulse_trigger1(void)

{

    measure1_flag = MODE_RUNNING ;

    Timer1_Stop() ;

    Timer1_WriteCounter(0) ;

    echo1_rise_int_Enable() ;

    Trigger1_Write(1) ;

    CyDelayUs(10) ;

    Trigger1_Write(0) ;

}

void pulse_trigger2(void)

{

    measure2_flag = MODE_RUNNING ;

    Timer2_Stop() ;

    Timer2_WriteCounter(0) ;

    echo2_rise_int_Enable() ;

    Trigger2_Write(1) ;

    CyDelayUs(10) ;

    Trigger2_Write(0) ;

}

/**

* print_value

* Calculate distance from the duration

* Since the duration include both way of the trip

* to get the distance, the real duration is the half

* of the duration.

*

* distance = duration * MACH(m/s) * 100(cm) / (2 * 12000000(Hz)) ;

*

*/

void print_value(int num, uint32_t duration)

{

    double distance = 0.0 ;

   

    distance = (double)(duration) * MACH / 240000.0 ;

    sprintf(str, "%d: %d.%02dcm\n", num, (int)distance, (int)(100 * distance)%100) ;

    print(str) ;

}

/*

* doing only the conversion from the timer count to the distance(cm)

*/

double get_distance(uint32_t duration)

{

    double distance = 0.0 ;

   

    distance = (double)(duration) * MACH / 240000.0 ;

    return(distance) ;

}

void doSensor1(void)

{

    switch(measure1_flag) {

    case MODE_IDLE:

        pulse_trigger1() ;

        break ;

    case MODE_RUNNING:

        break ;

    case MODE_MEASURED:

        if (get_distance(length1) < threshold1) {

            LED1_Write(0) ;

        } else {

            LED1_Write(1) ;

        }

        measure1_flag = MODE_IDLE ;

        break ;

    default:

        measure1_flag = MODE_IDLE ;

        break ;

    }

}

void doSensor2(void)

{

    switch(measure2_flag) {

    case MODE_IDLE:

        pulse_trigger2() ;

        break ;

    case MODE_RUNNING:

        break ;

    case MODE_MEASURED:

        if (get_distance(length2) < threshold2) {

            LED2_Write(0) ;

        } else {

            LED2_Write(1) ;

        }

        measure2_flag = MODE_IDLE ;

        break ;

    default:

        measure2_flag = MODE_IDLE ;

        break ;

    }

}

int main(void)

{   

    init_hardware() ;

    for(;;) {

        doSensor1() ;

        doSensor2() ;

    }

}

===================

moto

0 Likes

I have no doubt that this is working, it also looks really well written looking at it from the beginner side but where I'm trying to use these sensors is to a small parking lot project (2 for the gates: entrance and exit, and 6 for the parking spots) and I don't want to make it way too complicated if you get my point.  I just wanna sense the presence of the object (cars in my case).  Also I'm still trying to understand how the interrupts are working so I can't fully understand your code unfortunately for me.

0 Likes

For me, the simple use of incrementing a counter and dividing it by 58 is enough to get what I need, the only problem is trying to work with more than 1 sensor in the same time which at this point I don't know how to make it work and be as simple as possible so I'm not getting lost in my code.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Oh, OK, how about changing your main.c like below then?

==========================

/* ========================================

* HC-SR04 test program for CY8CKIT-044

* For this appliation, VDD must be set to 5V

* Set J9 Jumper to 3+2.

* ========================================

*/

#include "project.h"

volatile int counter1, counter2;

int sensor1(void)

{

    CyDelay(500);

    TRIGGER1_Write(0);

    CyDelay(500);

//    for(;;) // <-- comment out

//    {        // <-- comment out

        TRIGGER1_Write(1);

        CyDelay(10u);    

        TRIGGER1_Write(0);

       

        while(ECHO1_Read()==0)

        {

        }

        counter1 = 0 ;

        while(ECHO1_Read()==1)

        {

            counter1++;

        }

        if(counter1 < 580)

        {

            LED1_Write(1);    

        }

        if(counter1>580)

        {

            LED1_Write(0);

        }    

//    }     // <-- comment out

}

int sensor2(void)

{

    CyDelay(500);

    TRIGGER2_Write(0);

    CyDelay(500);

//    for(;;)  // <-- comment out

//    {  // <-- comment out

        TRIGGER2_Write(1);

        CyDelay(10u);    

        TRIGGER2_Write(0);

       

        while(ECHO2_Read()==0)

        {

        }

        counter2 = 0 ;

        while(ECHO2_Read()==1)

        {

            counter2++;

        }

        if(counter2 < 580)

        {

            LED2_Write(1);    

        }

        if(counter2>580)

        {

            LED2_Write(0);

        }    

//    }     // <-- comment out

}

int main(void)

{   

    CyGlobalIntEnable; /* Enable global interrupts. */   

    for(;;) {

        sensor1() ;

        sensor2() ;

    }

}

/* [] END OF FILE */

==========================

moto

0 Likes

Yes! thats exactly what I did some minutes ago and I made it work! thank you for your fast reply ! maybe you can give me a contact of you or I will write you in private better, I still have some questions regarding this functions that I made.. your help would be welcome haha xD

0 Likes