UncleRus / esp-idf-lib

Component library for ESP32-xx and ESP8266
https://esp-idf-lib.readthedocs.io/en/latest/
1.42k stars 439 forks source link

Using libraries in task and interrupt routine #111

Closed sonijprashant91 closed 3 years ago

sonijprashant91 commented 4 years ago

Device type

Framework version

Describe the bug Is it possible to use the libraries in two different tasks (1 Task und 1 Interrupt routine)? I'm using a TC95xx to mux 4 different I2C devices in a periodic task(freertos - task_read_TCA_Channels()). Additional if some gpio sets an interrupt I want to go to an Interrupt routine(taskAlertSignal):

Sometimes I got some errors which lead to kernel panic and restart: C:/esp-idf/components/freertos/queue.c:728 (xQueueGenericSend)- assert failed!

abort() was called at PC 0x400894ef on core 1 0x400894ef: xQueueGenericSend at C:/esp-idf/components/freertos/queue.c:728 (discriminator 5)

uint8_t channel = 0;
void task_read_TCA_Channels(void *arg)
{
    const char *TAG = "task_read_TCA_Channels";
    float insideTemp =42;
    float insideHumidity =2;
    uint8_t i2c_channel=44;

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    int64_t time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;

    TickType_t last_wakeup = xTaskGetTickCount();
    int32_t pressure_S0=43;
    int32_t pressure_S1=43;
    float temperature_S0=3;
    float temperature_S1=4;

    float bus_voltage=0, shunt_voltage=0, current=0, power =0; //INA values
    float atmos_pressure =950;
    float current_arr[20];
    float current_sum=0;

    while (1)
    {
      set_LED_color(OFF);
      for(channel=0; channel< 4;channel++)
      {
        tca9546_free_desc(&tca9546);
        ESP_ERROR_CHECK(tca9546_init_desc(&tca9546, I2C_NUM_0, Closedcube_Address, SCA_TCA9546A, SCL_TCA9546A));
        ESP_ERROR_CHECK(tca9546_set_channels(&tca9546,1<<channel));

        if(channel==0) 
        {
            esp_err_t err= ms5837_get_sensor_data(&ms5837_dev[channel], &pressure_S0, &temperature_S0);
            if(err != ESP_OK)
            {
              ESP_LOGI(TAG, "ERROR READ:  MSE preasure Sensor 0. Maybe not connected");
            }

        }
        if(channel==1)
        {
            esp_err_t err= ms5837_get_sensor_data(&ms5837_dev[channel], &pressure_S1, &temperature_S1);
            if(err != ESP_OK)
            {
              ESP_LOGI(TAG, "ERROR READ:  MSE preasure Sensor 1. Maybe not connected");
            }
          //ESP_ERROR_CHECK(ms5837_get_sensor_data(&ms5837_dev[i], &pressure_S1, &temperature_S1));
          //printf("S[%u]: pr %5.2f , temp %4.6f\n",i, (float)(pressure_S1/10),temperature_S1 );
        }
        if(channel==2)
        {
            continue;

        }
        if(channel==3) //HDC1080
        {
          insideTemp=hdc1080_get_temperature(&hdc1080_dev);
          insideHumidity= hdc1080_get_humidity(&hdc1080_dev);

        }

      }
      gettimeofday(&tv_now, NULL);
       time_us = (int64_t)tv_now.tv_sec * 1000L + (int64_t)tv_now.tv_usec/ 1000L;
      int32_t time_s = (int64_t)tv_now.tv_sec;     printf("%5.2f,%4.2f,%5.2f,%4.2f\n",(float)(pressure_S0/10- atmos_pressure),temperature_S0 ,(float)(pressure_S1/10- atmos_pressure),temperature_S1 );

    vTaskDelayUntil(&last_wakeup, 1000 / portTICK_PERIOD_MS);
    }
}

void taskAlertSignal()
{
    const char *TAG = "ALERT_Signal";
    //Read for 600 MS
    float current_arr[600];
    float current_sum=0;
    //Set Current sensor channel
    int cur_channel= 2;
    int p2_channel = 1;

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    int64_t time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
    struct timeval tv_now_array[600];

    TickType_t last_wakeup = xTaskGetTickCount();
    int32_t pressure_S1=43;
    float temperature_S1=4;

        // infinite loop
      for(;;) {
      current_sum=0;
      // wait for the notification from the ISR
      if(xSemaphoreTake(xSemaphore,portMAX_DELAY) == pdTRUE) {
       // tca9546_free_desc(&tca9546);
       // ESP_ERROR_CHECK(tca9546_init_desc(&tca9546, I2C_NUM_0, Closedcube_Address, SCA_TCA9546A, SCL_TCA9546A));

        set_LED_color(WHITE);
        ESP_ERROR_CHECK(tca9546_set_channels(&tca9546,1<<CURRENT_SENS));

        for(int j=0; j<600 ; j++)
        {
          ESP_ERROR_CHECK(ina219_get_current(&ina219_dev, &current_arr[j]));
          gettimeofday(&tv_now_array[j], NULL);
          current_sum+=current_arr[j];
        }
        //ESP_LOGW(TAG,"current_sum %f", current_sum);
        // READ OUT PR2

        gettimeofday(&tv_now, NULL);

        time_us = (int64_t)tv_now.tv_sec * 1000L + (int64_t)tv_now.tv_usec/ 1000L;
        int32_t time_s = (int64_t)tv_now.tv_sec;
        //printf("%ld:%ld, ", (long) time_s, (long ) time_us);

       // tca9546_free_desc(&tca9546);
       // ESP_ERROR_CHECK(tca9546_init_desc(&tca9546, I2C_NUM_0, Closedcube_Address, SCA_TCA9546A, SCL_TCA9546A));
        ESP_ERROR_CHECK(tca9546_set_channels(&tca9546,1<<PR1));

        //vTaskDelay(1);
        esp_err_t err= ms5837_get_sensor_data(&ms5837_dev[PR1], &pressure_S1, &temperature_S1);
        if(err != ESP_OK)
        {
          ESP_LOGW(TAG, "ERROR READ:  MSE preasure Sensor 1. Maybe not connected");
        }
        else
        {
          ESP_LOGI(TAG, "p1 %i",pressure_S1 );
        }

      printf("current_sum: %4.0f\n", current_sum);

        printf("Reset Channel back %i",channel);
        //Reset Channel of TCA 
       // tca9546_free_desc(&tca9546);
       // ESP_ERROR_CHECK(tca9546_init_desc(&tca9546, I2C_NUM_0, Closedcube_Address, SCA_TCA9546A, SCL_TCA9546A));
        ESP_ERROR_CHECK(tca9546_set_channels(&tca9546,1<<channel));
      }
    }

}
UncleRus commented 3 years ago

You are using the library completely wrong way. You don't need to recreate device descriptor in task_read_TCA_Channels() every cycle. Create it once and then call tca9546_set_channels() repeatedly in cycle. See examples how to do this.

Also your custom driver for MS5837 may be incompatible with i2cdev and conflicts with tca9546 and ina219 if they are connected to the same I2C bus.