2023年7月21日 星期五

ESP32 multi-core tasking execution application - Sound Sensor

ESP32 多核多工執行應用實例 

Purpose:

使用sound sensor去偵測外界環境的聲音大小若超過設定的闕值時, 就將本身的LED點亮, 變小時則LED就熄滅
This Project Use the sound sensor to detect the sound level of the ambient environment. If it exceeds the set threshold, the LED will be turned on ; otherwise, the LED will be turned off when it becomes smaller.


Sound sensor introduce:
The sound sensor is a module that monitors and detects the sound signals like voice, claps, snaps, knocks, etc. It is also known as an acoustic sensor or sound detector. Used in various applications such as security systems, monitoring systems, radios, telephones, mobile phones, computers, home automation systems, consumer electronic appliances, etc.
When the ambient sound intensity of the module does not reach the set threshold, OUT outputs a low level, and when the external ambient sound intensity exceeds the set threshold, the module OUT outputs a high level; The digital output OUT of the small board can be directly connected to the single-chip microcomputer, and the high and low levels are detected by the single-chip microcomputer, thereby detecting the sound of the environment
Circuit:

ESP32 Code Introduce:
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t BTFlag = 0;
  uint8_t DC_Flag = 0;
  uint8_t CANFlag = 0;
  uint8_t I2C_Flag = 0;
  uint8_t BMP180Flag = 0;
  uint8_t Sound_Flag = 0;
  uint8_t sensor_Flag = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t FunctionFlag = 0;
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//------LED------------------
#define LED_BUILTIN 2
//-----Sound sensor------------------
#define AIO_PIN1  34
#define DIO_PIN1  16
#define DATA_LEN 100
byte data1[DATA_LEN];
byte data2[DATA_LEN];
int dataIdx = 0;
int v1, v2;
int divFact = 4096 / 32;
//--------- uart structure --------------------------------------
//----------uart--------------
#define LINE_BUFFER_LENGTH 64
typedef struct _vUart
{
  char c;
  int lineIndex = 0;
  int line1Index = 0;
  int BTlineIndex = 0;
  bool lineIsComment;
  bool lineSemiColon;
  //char *line;
  char line[128];
  //char line1[128];
  char BTline[20];
  //char R_line[20];
  //char L_line[20];
  String inputString;
  String BTinputString;
  String S1inputString;
  int V[16];
  char ctemp[30];
  char I2C_Data[80];
  int DC_Spped = 50;
  float Voltage[16];
  int Buffer[128];
  int StartCnt = 0;
  int ReadCnt = 0;
  int sensorValue = 0;
} vUart;
vUart *Uart_Ptr;
vUart Uart;
//-------------------------------------
TaskHandle_t huart;
TaskHandle_t hfunction;

void vUARTTask(void *pvParameters);
void vFunctionTask(void *pvParameters);
//------------------------------------------------------------------------------
void initial()
{
  Serial.println(F("Create Task"));
  //----------------------------------------------------------------------
  xTaskCreatePinnedToCore(
    vUARTTask, "UARTTask" // A name just for humans
    ,
    1024 // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 3 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    &huart //handle
    ,
    0);

  xTaskCreatePinnedToCore(
    vFunctionTask, "FunctionTask"
    ,
    1024 // Stack size
    ,
    NULL, 1 // Priority
    ,
    &hfunction
    ,
    0);

  //----------------------------------------------------------------------
  //vTaskSuspend(hfunction); //暫停TASK運行
  //----------------------------------------------------------------------
}
//-------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  initial();
  pinMode(DIO_PIN1, INPUT);
  pinMode(AIO_PIN1, INPUT);
  //AIO_PIN1
  pinMode(LED_BUILTIN, OUTPUT);
  for (int i = 0; i < DATA_LEN; i++)
  {
    data1[i] = data2[i] = 0;
  }
 
}
//-----------------------------------------
void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  vTaskDelay(100);
  while(1)
  {
    if(flag.Sound_Flag==2)
    {
      for (int drawIdx = 0; drawIdx < DATA_LEN; drawIdx++)
      {
        Serial.print("data = ");
        Serial.println(data1[drawIdx]);
      }
    }
    vTaskDelay(10);
  }
}
//----------------------------------------
void processCommand(char *data)
{
  int len, xlen, ylen, zlen, alen;
  int tempDIO;
  String stemp;

  len = Uart.inputString.length();
  //---------------------------------------
  if (strstr(data, "VER") != NULL)
  {
    Serial.println(F("ESP32_20230710"));
  }
  //-------------- I2C --------------------
  if (strstr(data, "SOUND_ON") != NULL)
  {
    //vTaskResume(hfunction);
    flag.Sound_Flag = 1;
    Serial.println(F("SOUND_ON"));
  }
  if (strstr(data, "SOUND_OFF") != NULL)
  {
    flag.Sound_Flag = 0;
    Serial.println(F("SOUND_OFF"));
  }
  if (strstr(data, "SAMPLE_ON") != NULL)
  {
    flag.Sound_Flag = 2;
    Serial.println(F("SOUND_ON"));
  }

 
}
//-----------------------------------------

//-------------------------------------------
void vUARTTask(void *pvParameters)
{
  (void)pvParameters;

  Serial.print(F("UARTTask at core:"));
  Serial.println(xPortGetCoreID());
  vTaskDelay(100);
  for (;;)
  {
    while (Serial.available() > 0)
    {
      Uart.c = Serial.read();
 
      if ((Uart.c == '\n') || (Uart.c == '\r'))
      { // End of line reached
        if (Uart.lineIndex > 0)
        { // Line is complete. Then execute!
          Uart.line[Uart.lineIndex] = '\0'; // Terminate string
          //Serial.println( F("Debug") );
          //Serial.println( Uart.inputString );
          processCommand(Uart.line); // do something with the command
          Uart.lineIndex = 0;
          Uart.inputString = "";
        }
        else
        {
          // Empty or comment line. Skip block.
        }
        Uart.lineIsComment = false;
        Uart.lineSemiColon = false;
        Serial.println(F("ok>"));
      }
      else
      {
        //Serial.println( c );
        if ((Uart.lineIsComment) || (Uart.lineSemiColon))
        {
          if (Uart.c == ')')
            Uart.lineIsComment = false; // End of comment. Resume line.
        }
        else
        {
          if (Uart.c == '/')
          { // Block delete not supported. Ignore character.
          }
          else if (Uart.c == '~')
          { // Enable comments flag and ignore all characters until ')' or EOL.
            Uart.lineIsComment = true;
          }
          else if (Uart.c == ';')
          {
            Uart.lineSemiColon = true;
          }
          else if (Uart.lineIndex >= LINE_BUFFER_LENGTH - 1)
          {
            Serial.println("ERROR - lineBuffer overflow");
            Uart.lineIsComment = false;
            Uart.lineSemiColon = false;
          }
          else if (Uart.c >= 'a' && Uart.c <= 'z')
          { // Upcase lowercase
            Uart.line[Uart.lineIndex] = Uart.c - 'a' + 'A';
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += (char)(Uart.c - 'a' + 'A');
          }
          else
          {
            Uart.line[Uart.lineIndex] = Uart.c;
            Uart.lineIndex = Uart.lineIndex + 1;
            Uart.inputString += Uart.c;
          }
        }
      }
    } //while (Serial.available() > 0)
    vTaskDelay(10);
  }
}
void vFunctionTask(void *pvParameters)
{
  (void)pvParameters;

  Serial.print(F("FunctionTask at core:"));
  Serial.println(xPortGetCoreID());
  vTaskDelay(100);

  for (;;) // A Task shall never return or exit.
  {
    if(flag.Sound_Flag==1)
    {
      if (digitalRead(DIO_PIN1) == HIGH)
      {
        digitalWrite(LED_BUILTIN, HIGH);
        Serial.println(1);
      }
      else
      {
        digitalWrite(LED_BUILTIN, LOW);
        Serial.println(0);
      }

    }
    if(flag.Sound_Flag==2)
    {
      v1 = analogRead(AIO_PIN1);
      //data1[dataIdx] = v1 / divFact;
      data1[dataIdx] = v1 ;
      dataIdx++;
      if (dataIdx > DATA_LEN - 1)
      {
        dataIdx = 0;
      }
    }
    vTaskDelay(1);
  }
}

Demonstration:
YouTube:










沒有留言:

張貼留言