顯示具有 硬體電路學習 標籤的文章。 顯示所有文章
顯示具有 硬體電路學習 標籤的文章。 顯示所有文章

2023年12月18日 星期一

Bluetooth Speaker

Purpose:
利用現有BT audio receiver board來製作一台藍芽音箱, 從中學習到一些電子模組的焊接組合, Fusion360的3D繪製倒出圖檔到雷射切割機去做箱體的切割. 

INTRODUCTION
1. Bluetooth 5.0 Audio Receiver Board - Controllable Volume
This is a small size and cost-effective Bluetooth 5.0 Audio Receiver module with the auto-reconnect feature. It supports a wide-range power supply of 3.7V~24V and comes with a function button. Dial the button to the left and right to adjust volume, and press it to pause or play. You can use this module to remake your loudspeaker into wireless.



2. Mini Boost DC DC Step Up 1.5A Tegangan Fix Output Pilihan 5V 8V 9V 12V
Basic parameters
The output voltage can be set to 5V/8V/9V/12V, the default is 12V
Input voltage range: 2.5V- 5V
Output performance: Take 3.7V lithium battery input


3. Power Amp MINI SFT-9718 Stereo 60 Watt RMS. DC 12 V. - 15 V.
4. 喇吧與箱體



Circuit:



2023年11月10日 星期五

XBOX joystick modification with ESP32

Purpose:
This topic uses ESP32 to modify the broken XBOX Joystick and analyze the operating actions of two Joysticks and four Buttons (A, B, X, Y)! This topic is also about learning the parts of Joystick and Button!
這個專題是使用ESP32將壞掉的XBOX Joystick改裝, 把兩個Joystick和四個Button(A,B,X,Y)的操作動作解析出來! 這專題是另類的Joystick和Button零件的學習!

Tools: 

圖一: MutilMeter
Use MutilMeter to find the contact location of the Joystick and button, then spot weld it to the header connector and connect it to the designated pin of the ESP32.
利用MutilMeter來找出Joystick和button的接點位置, 然後將其點焊接到header接頭並連接至ESP32的指定腳位.

Fundamental:
Joystick
Dual-axis button rocker module, the rocker can move along the X-axis and Y-axis in two directions (VRx and VRy). Because of its internal variable resistance, it outputs a signal of 0-1023 when moving.
雙軸按鍵搖桿模組,搖桿可沿著 X軸 和 Y軸 兩個方向移動 (VRx 和 VRy)。因其內部的可變電阻,移動時,對外輸出 0-1023 的訊號。



YouTube Demo:

ESP32 Code:

#include <ezButton.h>
//-----Global variable---------------------------------------
#define LED_BUILTIN 2
//--------joystick------------------------------------------
#define VRX_PIN_L  33 // ESP32 pin GPIO33 (ADC)
#define VRY_PIN_L  32 // ESP32 pin GPIO32 (ADC)
#define VRX_PIN_R  35 // ESP32 pin GPIO35 (ADC)
#define VRY_PIN_R  34 // ESP32 pin GPIO34 (ADC)
#define SW_X       18
#define SW_Y       16
#define SW_A       17
#define SW_B       19

#define LEFT_THRESHOLD_L  2200  
#define RIGHT_THRESHOLD_L 900
#define UP_THRESHOLD_L    2200  
#define DOWN_THRESHOLD_L  900  

#define LEFT_THRESHOLD_R  2200  
#define RIGHT_THRESHOLD_R 900
#define UP_THRESHOLD_R    2200  
#define DOWN_THRESHOLD_R  900  

#define COMMAND_NO_L     0x00
#define COMMAND_LEFT_L   0x01
#define COMMAND_RIGHT_L  0x02
#define COMMAND_UP_L     0x04
#define COMMAND_DOWN_L   0x08

#define COMMAND_NO_R     0x00
#define COMMAND_LEFT_R   0x01
#define COMMAND_RIGHT_R  0x02
#define COMMAND_UP_R     0x04
#define COMMAND_DOWN_R   0x08

int valueX_L = 0 ; // to store the X-axis value
int valueY_L = 0 ; // to store the Y-axis value
int command_L = COMMAND_NO_R;
int valueX_R = 0 ; // to store the X-axis value
int valueY_R = 0 ; // to store the Y-axis value
int command_R = COMMAND_NO_R;
//----------------------------------------------

int bValue_A = 0; // To store value of the button
int bValue_B = 0; // To store value of the button
int bValue_X = 0; // To store value of the button
int bValue_Y = 0; // To store value of the button
ezButton buttonA(SW_A);
ezButton buttonB(SW_B);
ezButton buttonX(SW_X);
ezButton buttonY(SW_Y);
//------------------------------------------------------------

//--------- Flag structure --------------------------------------
//----------------------------------------------------------
#define LINE_BUFFER_LENGTH 1024
typedef struct _vFlag
{
  uint8_t LEDFlag=0;
  uint8_t BTFlag=0;
}vFlag;
vFlag *flag_Ptr;
vFlag flag;
//--------- uart structure --------------------------------------
//----------uart--------------
typedef struct _vUart
{
  char c;
  int lineIndex = 0;
  int line1Index = 0;
  int BTlineIndex = 0;
  bool lineIsComment;
  bool lineSemiColon;
  char line[128];
  char BTline[20];
  String inputString;
  String BTinputString;
} vUart;
vUart *Uart_Ptr;
vUart Uart;
//-------------------------------------
TaskHandle_t hled;
TaskHandle_t huart;

void vLEDFlashTask(void *pvParameters);
void vUARTTask(void *pvParameters);

void initial()
{
  Serial.println(F("Create Task"));
  //----------------------------------------------------------------------
  // Now set up two tasks to run independently.
  xTaskCreatePinnedToCore(
    vLEDFlashTask, "LEDTask" // A name just for humans
    ,
    1024 // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    &hled //handle
    ,
    0);

  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);

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


void setup() {
  Serial.begin(9600);
  /**240(default 240 160 80 40 20 and 10Mhz)***/
  setCpuFrequencyMhz(160);
  initial();
  //-----------------------------------------------------------------
  buttonA.setDebounceTime(50); // set debounce time to 50 milliseconds
  buttonB.setDebounceTime(50); // set debounce time to 50 milliseconds
  buttonX.setDebounceTime(50); // set debounce time to 50 milliseconds
  buttonY.setDebounceTime(50); // set debounce time to 50 milliseconds
  //------------------------------------------------
  Serial.println(F("System On!"));
  //-------------------------------------------
}

void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while (1)
  {
    buttonA.loop(); // MUST call the loop() function first
    buttonB.loop(); // MUST call the loop() function first
    buttonX.loop(); // MUST call the loop() function first
    buttonY.loop(); // MUST call the loop() function first
    // Read the button value
    bValue_A = buttonA.getState();
    bValue_B = buttonB.getState();
    bValue_X = buttonX.getState();
    bValue_Y = buttonY.getState();

    if (buttonA.isPressed()) {
      Serial.println("The buttonA is pressed");
      // TODO do something here
    }
    if (buttonA.isReleased()) {
      Serial.println("The buttonA is released");
      // TODO do something here
    }
    if (buttonB.isPressed()) {
      Serial.println("The buttonB is pressed");
      // TODO do something here
    }
    if (buttonB.isReleased()) {
      Serial.println("The buttonB is released");
      // TODO do something here
    }
    if (buttonX.isPressed()) {
      Serial.println("The buttonX is pressed");
      // TODO do something here
    }
    if (buttonX.isReleased()) {
      Serial.println("The buttonX is released");
      // TODO do something here
    }
    if (buttonY.isPressed()) {
      Serial.println("The buttonY is pressed");
      // TODO do something here
    }
    if (buttonY.isReleased()) {
      Serial.println("The buttonY is released");
      // TODO do something here
    }
    //--------------------------------------------------------
    valueX_L = analogRead(VRX_PIN_L);
    valueY_L = analogRead(VRY_PIN_L);
    valueX_R = analogRead(VRX_PIN_R);
    valueY_R = analogRead(VRY_PIN_R);
    // converts the analog value to commands
    // reset commands
    command_L = COMMAND_NO_L;
    command_R = COMMAND_NO_R;
    // check left/right commands
   
    if (valueX_L > LEFT_THRESHOLD_L)
      command_L = command_L | COMMAND_LEFT_L;
    else if (valueX_L < RIGHT_THRESHOLD_L)
      command_L = command_L | COMMAND_RIGHT_L;
   
    // check up/down commands
    if (valueY_L > UP_THRESHOLD_L)
      command_L = command_L | COMMAND_UP_L;
    else if (valueY_L < DOWN_THRESHOLD_L)
      command_L = command_L | COMMAND_DOWN_L;


    // print command to serial and process command
   
    if (command_L & COMMAND_LEFT_L) {
      Serial.println("COMMAND LEFT_L");
      // TODO: add your task here
    }

    if (command_L & COMMAND_RIGHT_L) {
      Serial.println("COMMAND RIGHT_L");
      // TODO: add your task here
    }

    if (command_L & COMMAND_UP_L) {
      Serial.println("COMMAND UP_L");
      // TODO: add your task here
    }

    if (command_L & COMMAND_DOWN_L) {
      Serial.println("COMMAND DOWN_L");
      // TODO: add your task here
    }
   
    //-----------------------------------------------------
    if (valueX_R > LEFT_THRESHOLD_R)
      command_R = command_R | COMMAND_LEFT_R;
    else if (valueX_R < RIGHT_THRESHOLD_R)
      command_R = command_R | COMMAND_RIGHT_R;
   
    // check up/down commands
    if (valueY_R > UP_THRESHOLD_R)
      command_R = command_R | COMMAND_UP_R;
    else if (valueY_R < DOWN_THRESHOLD_R)
      command_R = command_R | COMMAND_DOWN_R;


    // print command to serial and process command
   
    if (command_R & COMMAND_LEFT_R) {
      Serial.println("COMMAND LEFT_R");
      // TODO: add your task here
    }

    if (command_R & COMMAND_RIGHT_R) {
      Serial.println("COMMAND RIGHT_R");
      // TODO: add your task here
    }

    if (command_R & COMMAND_UP_R) {
      Serial.println("COMMAND UP_R");
      // TODO: add your task here
    }

    if (command_R & COMMAND_DOWN_R) {
      Serial.println("COMMAND DOWN_R");
      // TODO: add your task here
    }
    //-----------------------------------------------------
  }//----while(1)-------------------------------------------

}
//--------------------------------------------------------
/*--------------------------------------------------*/
void vLEDFlashTask(void *pvParameters) // This is a task.
{
  (void)pvParameters;
 
  Serial.print(F("LEDTask at core:"));
  Serial.println(xPortGetCoreID());
  pinMode(LED_BUILTIN, OUTPUT);
  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    vTaskDelay(200);
    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
    vTaskDelay(200);
  }
}

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

  Serial.print(F("UARTTask at core:"));
  Serial.println(xPortGetCoreID());
  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 processCommand(char *data)
{
  int len, xlen, ylen, zlen, alen;
  char ctemp[20];

  len = Uart.inputString.length();
  if (strstr(data, "VER") != NULL)
  {
    Serial.println(F("W_ATE_Board_20231109"));
  }

}




2023年8月15日 星期二

ESP32 Temperature and Humidity I2C LCD Display

Purpose:

This Project 利用NTP pool.ntp.org server來抓取現在時間, 並利用DHT22溫溼度感應器, 將現在的時間和溫度, 濕度顯示在 I2C介面的LCD面板上.

This project use the NTP (Network Time Protocol) to capture the current time, and use the DHT22 temperature and humidity sensor to display the current time, temperature, and humidity on the LCD panel of the I2C interface.

Fundamental:

NTP

The Network Time Protocol (NTP) is a networking protocol for clock synchronization between computer systems over packet-switched, variable-latency data networks. 

NTP is a protocol designed to synchronize the clocks of computers over a network to a common timebase (usually UTC).

Coordinated Universal Time (UTC)

NTP意圖將所有參與電腦的協調世界時(UTC)時間同步到幾毫秒的誤差內。

pool.ntp.org來取得時間即可

網路時間協定(英語:Network Time Protocol,縮寫:NTP)

LCD

The LCD1602 comes in 2 possible configurations: I2C configuration and standard configuration. The I2C configuration is usually simpler to use. The default I2C address of the LCD1602 module is 0x27.

DHT22

Digital-output relative humidity & temperature sensor/module

DHT22 output calibrated digital signal. It utilizes exclusive digital-signal-collecting-technique and humidity

sensing technology, assuring its reliability and stability.Its sensing elements is connected with 8-bit single-chip computer.

Every sensor of this model is temperature compensated and calibrated in accurate calibration chamber and the calibration-coefficient is saved in type of programme in OTP memory, when the sensor is detecting, it will cite coefficient from memory.

Circuit:


YouTubeDemo:



Code Introduce:

#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
//----------------------------------------------------------------------
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);

#define NTP_SERVER     "pool.ntp.org"
#define UTC_OFFSET     0
#define UTC_OFFSET_DST 0
//---------------DHT22--------------------
#define DHTPIN 14
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
float Humidity;
float Temperature;
//--------- 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 RFIDWrite = 0;
  uint8_t RFIDRead = 0;
  uint8_t dht22 = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t FunctionFlag = 0;
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//--------- 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[128];
  char BTline[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;

//---------------------------------------------------------------------------------
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
//----------------------------------------------------------------
TaskHandle_t hled;
TaskHandle_t huart;
//------------------------------------------------------------------------------
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);

  //--------------- create task----------------------------------
  xTaskCreatePinnedToCore(
    vLEDTask, "LEDTask" // A name just for humans
    ,
    1024 // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    &hled //handle
    ,
    0);
  //----------------------------------------------------------------------
}

void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  initial();
  pinMode(LED_BUILTIN, OUTPUT);
  LCD.init();
  LCD.backlight();
  LCD.setCursor(0, 0);
  LCD.print("Connecting to ");
  LCD.setCursor(0, 1);
  LCD.print("WiFi ");

  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    spinner();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.println("Online");
  LCD.setCursor(0, 1);
  LCD.println("Updating time...");
  configTime(8*3600, 0, "pool.ntp.org","time.nist.gov"); // enable NTP for Taipei time
  //configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);

  dht.begin();
}

void loop()
{
  //

  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    if(flag.dht22==0)
    {
      for(int i=0;i<40;i++)
      {
        printLocalTime();
        delay(200);
      }
      LCD.clear();
      flag.dht22=1;
    }
   
   
    if(flag.dht22==1)
    {
      float h = dht.readHumidity();

      float t = dht.readTemperature();

      float f = dht.readTemperature(true);
     
      if (isnan(h) || isnan(t) || isnan(f))
      {
        Serial.println("Failed to read from DHT sensor!");
        return;
      }

      float hif = dht.computeHeatIndex(f, h);

      float hic = dht.computeHeatIndex(t, h, false);

      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" % ");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.print(" *C ");
      Serial.print(f);
      Serial.print(" *F ");
      Serial.print("Heat index: ");
      Serial.print(hic);
      Serial.print(" *C ");
      Serial.print(hif);
      Serial.println(" *F");

      String Line="Temp: "+String(t);
      String Line1="Humi: "+String(h);
      for(int i=16;i>=0;i--)
      {
        LCD.setCursor(i,0);
        LCD.print(Line);
        LCD.print(" ");
        LCD.setCursor(i,1);
        LCD.print(Line1);
        LCD.print(" ");
        delay(200);
      }
      delay(200);
      LCD.clear();
      flag.dht22=0;
    }
    vTaskDelay(5);
  }
}
//-------------------------------------------
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(5);
  }
}
//-------------------------------------------------------------------------
static void vLEDTask(void *pvParameters)
{
  (void)pvParameters;

  Serial.println(F("LEDTask at core:"));
  Serial.println(xPortGetCoreID());
  pinMode(LED_BUILTIN, OUTPUT);
  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    vTaskDelay(200);
    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
    vTaskDelay(200);
  }
}
//----------------------------------------
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_20230811"));
  }
  //-------------- RFID --------------------
  if (strstr(data, "DHT22_ON") != NULL)
  {
    flag.dht22 = 1;
    Serial.println(F("DHT22_ON"));
  }
  if (strstr(data, "DHT22_OFF") != NULL)
  {
    flag.dht22 = 0;
    Serial.println(F("DHT22_OFF"));
  }
 
}
//-----------------------------------------
void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    LCD.setCursor(0, 1);
    LCD.println("Connection Err");
    return;
  }
  //LCD.clear();
  LCD.setCursor(0, 0);
  LCD.println("Online");

  LCD.setCursor(8, 0);
  LCD.println(&timeinfo, "%H:%M:%S");

  LCD.setCursor(0, 1);
  LCD.println(&timeinfo, "%d/%m/%Y   %Z");
}

//----------------------------------------------
void spinner()
{
  static int8_t counter = 0;
  const char* glyphs = "\xa1\xa5\xdb";
  LCD.setCursor(15, 1);
  LCD.print(glyphs[counter++]);
  if (counter == strlen(glyphs)) {
    counter = 0;
  }
}
//-----------------------------------------


2023年7月6日 星期四

Arduino IDE 2 + ESP32 multiTask sample -- LED Section

Porpose:

The ESP32 comes with 2 Xtensa 32-bit LX6 microprocessors: core 0 and core 1. So, it is dual core. When we run code on Arduino IDE, by default, it runs on core 1. In this post we’ll show you how to run code on the ESP32 second core by creating tasks. You can run pieces of code simultaneously on both cores, and make your ESP32 multitasking.

Introduction:

The ESP32 comes with 2 Xtensa 32-bit LX6 microprocessors, so it’s dual core:

Core 0

Core 1

Some features to remember:

xTaskCreate() to create a task

xTaskCreatePinnedToCore() to create a task on a particular core

vTaskDelayUntil() to activate a task periodically

vTaskDelay() blocks a task for a certain number of clock ticks (uses pdMS_TO_TICKS to convert a duration into a number of ticks)

vTaskPrioritySet() changes the priority of a task

vTaskDelete() to delete a task

main.cpp

#include "main.h"

//-------------------------------------------------
void setup()
{
  Serial.begin(9600);

  Serial.println(F("init"));

  #ifdef ENABLE_LEDTASK
  initledTask();
  #endif

}

void loop()
{
  vTaskDelay(200);
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());

  while(1)
  {
    vTaskDelay(200);
  }

}

main.h

#ifndef __MAIN_H
#define __MAIN_H

#include <Arduino.h>

#include "configuration.h"
#include "public_structure.h"

// led Task stuff
#define ENABLE_LEDTASK
void initledTask(void);

//-----------------------------------------
#endif

ledtask.cpp

#include "main.h"
#include "ledTask.h"
#include "public_structure.h"

#ifdef ENABLE_LEDTASK
/** Forward dedclaration of the task handling LED */
TaskHandle_t hled;  //TaskHandler  -----   main extern

void ledTask(void *pvParameters);

int Led::addTwoInts(int a, int b)
{
  return a + b;
}

Led::Led(byte pin)
{
  this->pin = pin;
  init();
}

void Led::init()
{
  pinMode(pin, OUTPUT);
  off();
}

void Led::on()
{
  digitalWrite(pin, HIGH);
}

void Led::off()
{
  digitalWrite(pin, LOW);
}

Led led(LED_PIN);  //---need to using

void initledTask(void)
{
  // Create the task for the led flash
  xTaskCreatePinnedToCore(
    ledTask, "LED Task" // A name just for humans
    ,
    1024 // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    &hled //handle
    ,
    0);

  // Check the results
  if (hled == NULL)
  {
    Serial.println("Create Led task failed");
  }
  else
  {
    Serial.println("Led task up and running");
  }
}
//------------------------------------------------------------------------------
// Task blinking LED
void ledTask(void *pvParameters)
{
  Serial.print(F("LED Task at core:"));
  Serial.println(xPortGetCoreID());

  while(1)
  {
    led.on();
    //vTaskDelay((150L * configTICK_RATE_HZ) / 1000L);
    vTaskDelay(200);
    led.off();
    //vTaskDelay((150L * configTICK_RATE_HZ) / 1000L);
    vTaskDelay(200);
  }
}

#endif

ledtask.h

#ifndef __LEDTASK_H
#define __LEDTASK_H
#include <Arduino.h>

class Led
{
  private:
    byte pin;
    int a, b;
   
  public:
    // Setup pin LED and call init()
    Led(byte pin);

    // Setup the pin led as OUTPUT
    // and power off the LED - default state
    void init();
   
    // Power on the LED
    void on();

    // Power off the LED
    void off();

    int addTwoInts(int a, int b);
};

#endif

public_structure.h

#ifndef __MESSAGE_H
#define __MESSAGE_H

#include <Arduino.h>
#include "configuration.h"

//----------------------------------------------------------
typedef struct _vMessage_Type
{
  uint8_t messageId;
  //char *messageString;   //不行用會當機
  char messageString[128];
  char FWString[60];
} vMessage_Type;

extern vMessage_Type *message_Ptr;
extern vMessage_Type message;

typedef struct _vFlag
{
  uint8_t BTFlag = 0;
  uint8_t DC_Flag = 0;
  uint8_t CANFlag = 0;
  uint8_t I2C_Flag = 0;
  uint8_t JSONFlag = 0;
  uint8_t Radar_L_Flag = 0;
  uint8_t Radar_R_Flag = 0;
  uint8_t sensor_Flag = 0;
  uint8_t sensor1_Flag = 0;
  uint8_t initial_Flag = 0;
  uint8_t Tone_Flag = -1;
  uint8_t IR_RECV_Flag=0;
  uint8_t IR_SEND_Flag=0;
  uint8_t FunctionFlag = 1;
  uint8_t SendFlag = 0;
} vFlag;

extern vFlag *flag_Ptr;
extern vFlag flag;

//------------------------------------------------------------------------------
#endif

YouTube: