Interfacing Multiple ultrasonic sensors with Tiva C Launch pad

areeg wrote on Friday, April 05, 2019:

I’m trying to interface 6 ultrasoinc sesnors with Tiva C launch pad using FreeRTOS this code is working for only onw sensor but I have some problems when I add more than one I get wrong readings and sometimes when connecting 2 sensors they return the same value

#include "FreeRTOS.h"
#include "task.h"
#include "UART.h"
#include "Ultrasoinc_2.h"
unsigned long Reading1=0;

TaskHandle_t  Ultrasonic_ReadingHandle=NULL;
TaskHandle_t  Utrasoinc_InterruptHandle=NULL;

// Task to send Trigger Every 20 ms
void Ultrasonic_Trigger( void * pvParameters )
{
    TickType_t xLastWakeTime;
    while(1)
    {
        // Enable interrupt on PB0 pin connected to ultrasonic Echo
        GPIO_PORTB_IM_R|=(1<<0);

        // Makes trigger pin high for 10 us then low to send trigger to ultrasonic
        Send_Trigger(1);
        xLastWakeTime = xTaskGetTickCount();
        vTaskDelayUntil(&xLastWakeTime,20);
    }
}

// Task Resumed from External interrupt at Port B
/* At first Echo Flag is low , get the time of rising edge on PB0 , the next time to enter the task echo flag is high ,
 * get time of falling edge and calculate the difference to get the distance measured
 */
void Ultrasoinc_Interrupt_B( void * pvParameters )
{
TickType_t Start;
for( ;; )
{
 taskENTER_CRITICAL();
 if (!Echo)
  {
  // Get rising Edge time
  Start=xTaskGetTickCount();
  Echo=1;
  }
  else
  {
  Echo=0;
  // Difference between rising and falling edges
  pulse = (unsigned long)((xTaskGetTickCount()-Start)*170/100);
  Delay_us(100);
  Reading1=pulse;
  }
 taskEXIT_CRITICAL();
 vTaskSuspend(NULL);
 }
}



int main(void)
   {

   xTaskCreate(Ultrasoinc_Interrupt_B,"Utrasoinc_Interrupt",150,NULL,1,&Utrasoinc_InterruptHandle);
   xTaskCreate(Ultrasonic_Trigger,"Ultrasonic_Reading",150,NULL,2,&Ultrasonic_ReadingHandle);
   // Enable system clock
           SYSCTL_RCGCGPIO_R|=(1<<0);
           SYSCTL_RCGCGPIO_R|=(1<<1);
           SYSCTL_RCGCGPIO_R|=(1<<4);
   // Initialize UART
           UART0_Init(9600,16000000);

   // Make Trigger pin output and Echo pin input and enable interrupts in echo pin
           Configure_Echo();
           Configure_Trigger();
           // NVIC register
           Enable_Ultrasionc_Interrupts();
           vTaskStartScheduler();

    while(1)
    {

    }

}
// External interrupt ISR
void Ultrasonic_PortB_Interrupt()
  {
    // Clear Flag
    GPIO_PORTB_ICR_R|= (1<<0);
    // Resume handling Task
    BaseType_t check;
    check = xTaskResumeFromISR(Utrasoinc_InterruptHandle);
    portYIELD_FROM_ISR(check);
  }

I don’t know how to read more than one sensor, as the task handling the interrupt is resumed from ISR so each sensor gives an interrupt enters the same task and I can’t determine the echo is comming from which sensor.
Is it better to have separate tasks to send trigger for each sensor?
Thanks

hs2sf wrote on Saturday, April 06, 2019:

I´d propose to use TaskNotification signalled by the ISR(s) to wake-up the sensor handling task waiting resp. blocking on its TaskNotification handle.
Simple, lean and the fastest way to manage ISR/task communcation.
Better don´t use suspend/resume for signalling events.