顯示具有 RTOS 標籤的文章。 顯示所有文章
顯示具有 RTOS 標籤的文章。 顯示所有文章

2023年8月14日 星期一

RFID-RC522 module with ESP32 using Arduino IDE2

Purpose:

想利用ESP32+RFID-RC522來學習做一套門禁系統, 當感應到認可的卡片時, 可開門允許通過, 否則則警示非法卡片.

I want to use ESP32+RFID-RC522 to learn to make an access control system. When an approved card is sensed, the door can be opened to allow passage, otherwise it will warn of illegal cards.

Fundamental:

RFID 是一種無線通訊技術,以無線電波傳遞訊息,只要在電波範圍內,即可傳送訊號,不會傳輸屏障之問題。這種設備的運作為一個讀卡設備會發出一個電磁場,而感應卡內部有線圈,當線圈靠近磁場時,會產生感應電流,就可以做為電力傳輸資訊。另外,感應卡平常沒有靠近場時,內部晶片根本沒有電力可以工作,不用擔心卡片放在一起資料不見。
RFID設備所使用的頻段分為低頻(LF,125KHz)、高頻(HF,13.56MHz)、 超高頻(UHF,868~915MHz)、微波(Microwave,2.45 & 5.814GHz),各個頻 段的設備有不同的物理特性,如讀取的距離與讀取的速度,因此在不同應用情境中會採用不同頻段的設備。

RFID is a wireless communication technology that uses radio waves to transmit information. 
As long as it is within the range of the radio waves, the signal can be transmitted without the problem of transmission barriers. 
The operation of this kind of equipment is that a card reading device will emit an electromagnetic field, and there is a coil inside the proximity card. 
When the coil is close to the magnetic field, an induced current will be generated, which can be used as power to transmit information. 
In addition, when the proximity card is not close to the field, the internal chip has no power to work at all, so there is no need to worry about the data missing when the cards are put together.
The frequency bands used by RFID equipment are divided into low frequency (LF, 125KHz), high frequency (HF, 13.56MHz), ultra high frequency (UHF, 868~915MHz), microwave (Microwave, 2.45 & 5.814GHz), the equipment of each frequency band is Different physical characteristics, such as reading distance and reading speed, so devices with different frequency bands will be used in different application scenarios.

圖一: RFID-RC522感應器13.56MHz
圖二: 感應卡MIFARE卡

RFID感應器是頻率為13.56MHz的 RFID-RC522,而他的感應卡為MIFARE卡,MIFARE卡又有分不同儲存容量的卡。MIFARE S50 內部儲存容量1Kbyte,MIFARE S70 內部儲存容量 4Kbytes,各劃分為 16 區與 64 區,每區都有獨立的 A / B 兩層存取控制密碼,每區有4個BLOCK,每個BLOCK有16個字節。
The RFID sensor is an RFID-RC522 with a frequency of 13.56MHz, and its proximity card is a MIFARE card, and the MIFARE card has different storage capacities. 
The internal storage capacity of MIFARE S50 is 1Kbyte, and the internal storage capacity of MIFARE S70 is 4Kbytes. 
Each area is divided into 16 areas and 64 areas. Each area has an independent A / B two-layer access control password. Each area has 4 BLOCKs. 16 bytes.
圖: Read Data


Bill of Material :
圖: RFID-RC522感應器13.56MHz
圖: 感應卡MIFARE卡
圖:ESP32
Circuit:

YouTube Demo:


Code Introduce:

#include <SPI.h>
#include <MFRC522.h>
//----------------------------------------------------------------------
//--------- 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 sensor_Flag = 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;
  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;
//-------------------------------------
//Typical pin layout used:
//* -----------------------------------------------------------------------------------------
// *             MFRC522                    
// *             Reader/PCD   ESP32          
// * Signal      Pin          Pin          
// * --------------------------------------
// * RST/Reset   RST          21            
// * SPI SS      SDA(SS)      5            
// * SPI MOSI    MOSI         23
// * SPI MISO    MISO         19
// * SPI SCK     SCK          18
//------ESP32 RFID setting ----------------
const int SPI_CS_PIN = 5;
const int INT_PIN = 21;

MFRC522 mfrc522;
MFRC522::MIFARE_Key key;
//16(sector),4(block)
byte sector = 15;  
byte block = 0;    

byte blockData[]    = {
        0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
        0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
        0x09, 0x0a, 0xff, 0x0b, //  9, 10, 255, 11,
        0x0c, 0x0d, 0x0e, 0x0f  // 12, 13, 14, 15
    };

byte buffer[18];

MFRC522::StatusCode status;

struct RFIDTag {    
   byte uid[4];
   char *name;
};

struct RFIDTag tags[] = {  
   {{60,209,110,133}, "employee1"},
   {{0xD4,0xD3,0xC0,0x61}, "employee2"},
   {{0xDC,0x14,0xD3,0x38}, "ESP32"}
};

byte totalTags = sizeof(tags) / sizeof(RFIDTag);

char *reference;

//---------------------------------------------------------------------------------
#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);
  //----------------------------------------
  //----------------------------------------------------------------------
  //vTaskSuspend(hfunction); //暫停TASK運行
  //----------------------------------------------------------------------
}

void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  initial();
  SPI.begin();
  pinMode(INT_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
pinMode(16, OUTPUT);  //PASS
  pinMode(17, OUTPUT);
  mfrc522.PCD_Init(SPI_CS_PIN, INT_PIN);
  Serial.print(F("Reader "));
  Serial.print(F(": "));
  mfrc522.PCD_DumpVersionToSerial();
  Serial.println();
 
  for (byte i = 0; i < 6; i++)
  {
    key.keyByte[i] = 0xFF;
  }

}

void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    if(flag.RFIDWrite==1)
    {
      if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
      {
       
        Serial.print(F("Card UID:"));
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        Serial.println();
        Serial.print(F("PICC type: "));
        MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
        Serial.println(mfrc522.PICC_GetTypeName(piccType));
       
        writeBlock(sector, block, blockData);  
       
        mfrc522.PICC_HaltA();
        mfrc522.PCD_StopCrypto1();
      }
    }
   
    if(flag.RFIDRead==1)
    {
      if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
      {
        byte *id = mfrc522.uid.uidByte;
        byte idSize = mfrc522.uid.size;

        Serial.print(F("Card UID:"));
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
       
        Serial.println();
        Serial.print(F("PICC type: "));
        MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
        Serial.println(mfrc522.PICC_GetTypeName(piccType));  

        bool they_match = false;
        for (byte i=0; i<totalTags; i++)
        {
          if (memcmp(tags[i].uid, id, idSize) == 0)
          {
            Serial.println(tags[i].name);  
            they_match = true;
            break;
          }
        }


        if(they_match)
        {
          Serial.print(F("Access Granted!"));
digitalWrite(16, HIGH);
        }else
        {
          Serial.print(F("Access Denied!"));
digitalWrite(17, HIGH);
        }
 
        mfrc522.PICC_HaltA();  
vTaskDelay(1000);
        digitalWrite(16, LOW);
        digitalWrite(17, LOW);
      }
    }//---1
    if(flag.RFIDRead==2)
    {
      if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
      {
        // Dump debug info about the card; PICC_HaltA() is automatically called
        mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
       
      }
    }
    if(flag.RFIDRead==3)
    {
      if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
      {
       
        Serial.print(F("Card UID:"));
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        Serial.println();
        Serial.print(F("PICC type: "));
        MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
        Serial.println(mfrc522.PICC_GetTypeName(piccType));
       
        readBlock(sector, block, buffer);      

        mfrc522.PICC_HaltA();
        mfrc522.PCD_StopCrypto1();
      }
    }
    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 (;;)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    vTaskDelay(200);
    digitalWrite(LED_BUILTIN, 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, "RFID_WRITE_ON") != NULL)
  {
    flag.RFIDWrite = 1;
    flag.RFIDRead = 0;
    Serial.println(F("RFID_WRITE_ON"));
  }
  if (strstr(data, "RFID_WRITE_OFF") != NULL)
  {
    flag.RFIDWrite = 0;
    flag.RFIDRead = 0;
    Serial.println(F("RFID_WRITE_OFF"));
  }
  if (strstr(data, "RFID_READ_1") != NULL)
  {
    flag.RFIDRead = 1;
    flag.RFIDWrite = 0;
    Serial.println(F("RFID_READ_1"));
  }
  if (strstr(data, "RFID_READ_2") != NULL)
  {
    flag.RFIDRead =2;
    flag.RFIDWrite = 0;
    Serial.println(F("RFID_READ_2"));
  }
  if (strstr(data, "RFID_READ_3") != NULL)
  {
    flag.RFIDRead =3;
    flag.RFIDWrite = 0;
    Serial.println(F("RFID_READ_3"));
  }
  if (strstr(data, "RFID_READ_OFF") != NULL)
  {
    flag.RFIDRead = 0;
    flag.RFIDWrite = 0;
    Serial.println(F("RFID_READ_OFF"));
  }
}
//-----------------------------------------

void dump_byte_array(byte *buffer, byte bufferSize)
{
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void writeBlock(byte _sector, byte _block, byte _blockData[])
{
  if (_sector < 0 || _sector > 15 || _block < 0 || _block > 3) {
   
    Serial.println(F("Wrong sector or block number."));
    return;
  }

  if (_sector == 0 && _block == 0) {
    Serial.println(F("First block is read-only."));
    return;
  }

  byte blockNum = _sector * 4 + _block;
  byte trailerBlock = _sector * 4 + 3;  


  Serial.println(F("Authenticating using key A..."));
  status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
      Serial.print(F("PCD_Authenticate() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
  }

  Serial.print(F("Writing data into block ")); Serial.print(blockNum);
  Serial.println(F(" ..."));
  dump_byte_array(_blockData, 16); Serial.println();

  status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(blockNum, _blockData, 16);

  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Write() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  Serial.println(F("Data was written."));
}
//----------------------------------------------
void readBlock(byte _sector, byte _block, byte _blockData[])
{
  if (_sector < 0 || _sector > 15 || _block < 0 || _block > 3)
{
    Serial.println(F("Wrong sector or block number."));
    return;
  }

  byte blockNum = _sector * 4 + _block;  
  byte trailerBlock = _sector * 4 + 3;  

  // Authenticate using key A
  Serial.println(F("Authenticating using key A..."));
  status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
      Serial.print(F("PCD_Authenticate() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
  }

  byte buffersize = 18;
  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockNum, _blockData, &buffersize);

  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_read() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  Serial.print(F("Data in block ")); Serial.print(blockNum); Serial.println(F(":"));
  dump_byte_array(_blockData, 16); Serial.println();
  Serial.println();

  Serial.println(F("Data was read."));
}
//-----------------------------------------




2023年7月23日 星期日

Mega2560 FreeRTOS system -- Control Realy Board

 Purpose:

利用Mega2560的FreeRTOS library架構成多工的系統, 並利用serial monitor去執行指令, 控制Relay Board Module動作.

This project shows  how to Use the FreeRTOS library architecture of Mega2560 to build a multi-task system, and use the serial monitor to execute instructions and control the actions of the Relay Board Module.

Figure 1 : Function Connection

Fundamental:

Mega2560:

Microcontroller boards like the "Arduino Mega" rely on the ATmega2560 microcontroller. It includes 54 digital input/output pins, of which 16 are analog inputs, 14 are used as PWM outputs, hardware serial port (UART) - 4, crystal oscillator - 16MHz, one ICSP header, one power supply jack, a USB connection, and the RST button. This board basically contains everything needed to support a microcontroller. Therefore, the board can be powered by connecting it to a PC via a USB cable, battery, or AC-DC adapter. By installing a backplane, the board can be protected from accidental discharges.

Figure 2 : Mega2560 Board
Figure 3 : Mega2560 Board Pin Definition
Figure 4 : Mega2560 Board Pin Function
Figure 5 : Mega2560 Board Circuit

FreeRTOS:
FreeRTOS is a class of RTOS that is designed to be small enough to run on a microcontroller – although its use is not limited to microcontroller applications. FreeRTOS includes a kernel and a growing set of software libraries suitable for use across industry sectors and applications. With the help of FreeRTOS, you can do multitasking on a microcontroller based hardware!
The FreeRTOS can be very powerful by providing the microcontroller real time scheduling functionality, inter-task communication, timing and synchronization primitives.
For Arduino compatibility, we have ported FreeRTOS into the Arduino framework so that you are able to use FreeRTOS with your favorite Arduino boards.
Circuit:


Code Introduce:
#include <Arduino_FreeRTOS.h>
//---------------structure ----------------------------------------
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t LEDFlag=1;
  uint8_t BTFlag = 0;
  uint8_t ServoFlag = 0;
 
} vFlag;
vFlag *flag_Ptr;
vFlag flag;
//----------uart--------------
#define LINE_BUFFER_LENGTH 64
//--------- uart structure --------------------------------------
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;
//------------------------------------------------
const uint8_t LED_PIN = 13;
//----relay--------
uint8_t DIO_1 = 22;
uint8_t DIO_2 = 24;
uint8_t DIO_3 = 26;
uint8_t DIO_4 = 28;
uint8_t DIO_5 = 30;
uint8_t DIO_6 = 32;
uint8_t DIO_7 = 34;
uint8_t DIO_8 = 36;
//-------------------------------------------
char ctemp[20];
//------------------------------
TaskHandle_t hled;
TaskHandle_t huart0;
//------------------------------------------------------------------------------
void initial()
{
  Serial.println(F("Create Task"));
  //----------------------------------------------------------------------
  // create UART task
  xTaskCreate(vUARTTask, "UART Task", configMINIMAL_STACK_SIZE, NULL, 1, &huart0);
  // Check the results
 

  // create blink task
  xTaskCreate(vLEDFlashTask, "LED Task", configMINIMAL_STACK_SIZE, NULL, 2, &hled);
 
  //-------------------------------------------------------------------

}
void setup()
{
  Uart.inputString.reserve(60);
  initial();
  Serial.begin(9600);
  Serial.setTimeout(2000);
  Serial.println(F("init"));
  //-------------------------------------
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW); // Turn LED off.
  //---------------IO setting-----------------
  pinMode(DIO_1, INPUT);
  pinMode(DIO_2, INPUT);
  pinMode(DIO_3, INPUT);
  pinMode(DIO_4, INPUT);
  pinMode(DIO_5, INPUT);
  pinMode(DIO_6, INPUT);
  pinMode(DIO_7, INPUT);
  pinMode(DIO_8, INPUT);
 // start FreeRTOS
  Serial.println("Systom On!");
  vTaskStartScheduler();
  //if the scheduler start the code don't came here
  Serial.println(F("Die"));
  while (1)
    ;
}
//------------------------------------------------------------------------------
void loop()
{
 
}
//------------------------------------------------------------------------------
// high priority for blinking LED
void vLEDFlashTask(void *pvParameters)
{
  (void)pvParameters;

  pinMode(LED_PIN, OUTPUT);
  for (;;)
  {
    digitalWrite(LED_PIN, HIGH);                    // Turn LED on.
    vTaskDelay((150L * configTICK_RATE_HZ) / 1000L); // Sleep for 50 milliseconds.
    digitalWrite(LED_PIN, LOW);                      // Turn LED off.
    vTaskDelay((150L * configTICK_RATE_HZ) / 1000L); // Sleep for 150 milliseconds.
  }
}
//------------------------------------------------------------------------------
void vUARTTask(void *pvParameters)
{
  Uart.lineIsComment = false;
  Uart.lineSemiColon = false;

  while(1)
  {
    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)
  }
}
//------------------------------------------------------------------------------
//----reset-----------
void (*resetFunc)(void) = 0;
//---------------------------------------------------------
void processCommand(char *data)
{

  int len, xlen, ylen, zlen, alen;
  int tempDIO;
  String stemp;
  unsigned int i, j, Comma;

  int val, maxv, minv;
  unsigned long duration;
  float Vpp;

  len = Uart.inputString.length();

  //-------------RESET---------------
  if (strstr(data, "VER") != NULL)
  {
    //Serial.println(F("W_ATE_Board_20201021"));
    Serial.println(F("Mega_SERIAL_20230723"));
  }
  if (strstr(data, "RESET") != NULL)
  {
    Serial.println(F("Reset"));
    resetFunc();
  }
  //===-----------------DIO port 1----------------
  if (strstr(data, "DIO1") != NULL)
  {
    //-DIO11_LOW
    if (data[3] == '1')
    {
      for (int i = 0; i < len; i++)
      {
        if (data[i] == '_')
        {
          //Serial.println("test");
          //Serial.println(i);
          xlen = i;
        }
        //ctemp[i-4]=data[i];
      }
      for (int i = 4; i < xlen; i++)
      {
        ctemp[i - 4] = data[i];
      }
      ctemp[xlen - 4] = '\0';
      tempDIO = atoi(ctemp);
      //Serial.println(tempDIO);
      for (int i = (xlen + 1); i < len; i++)
      {
        ctemp[i - (xlen + 1)] = data[i];
      }
      ctemp[len - (xlen + 1)] = '\0';

      tempDIO = tempDIO * 2 + 20;
      pinMode(tempDIO, OUTPUT);
      //if(strstr(ctemp, "ON") != NULL)
      //if(strcmp(ctemp, "ON")==0)
      //if (strcmp(Uart.ctemp, "LOW") == 0)
      if (strstr(ctemp, "LOW") != NULL)
      {
        digitalWrite(tempDIO, LOW);
      }
      else if (strstr(ctemp, "ON") != NULL)
      {
        digitalWrite(tempDIO, LOW);
      }
      else if (strstr(ctemp, "HIGH") != NULL)
      {
        digitalWrite(tempDIO, HIGH);
      }
      else if (strstr(ctemp, "OFF") != NULL)
      {
        digitalWrite(tempDIO, HIGH);
      }
    }
  }
}

Demonstration:
YouTube: