顯示具有 Arduino開發 標籤的文章。 顯示所有文章
顯示具有 Arduino開發 標籤的文章。 顯示所有文章

2026年2月22日 星期日

Arduino Mega2560 EEPROM 的應用

問題: arduino mega2560 接電源接頭 跟 UART後設定完後斷開UART後設定值不見的問題 
在 Arduino 設計中,當序列埠 (Serial Port) 被開啟或關閉(例如拔掉 USB 或關閉序列監控視窗)時,DTR 訊號會觸發晶片重設。
這通常是因為 Arduino Mega 2560 的預設自動重設 (Auto-Reset) 機制,以及變數儲存在 RAM (隨機存取記憶體) 中導致的。
可以使用內建的 EEPROM 來保存設定!!
引入函式庫:#include <EEPROM.h>。
儲存設定:使用 EEPROM.put(address, data)。
讀取設定:在 setup() 中使用 EEPROM.get(address, data) 載入舊值。

#include <EEPROM.h>
// ==========================================================
// EEPROM 記憶體位址定義
// ==========================================================
const int MAGIC_NUMBER_ADDR = 0;
const int SETTINGS_ADDR = sizeof(byte); // 設定結構體的起始位址

const byte MAGIC_VALUE = 0xAC; // 自訂一個魔術數字

const int NUM_RELAYS = 16;
// ==========================================================
// 1. 定義設定的結構體
// ==========================================================
struct RelaySettings {
  byte orgConfigNumber;
  byte AllRelayFlag;
  byte RunConfigFlag;
  byte ConfigNumber;
  uint8_t ConfigFlag[NUM_RELAYS];
  unsigned long DelayTime ;  //--設定 relay1~16延遲打開時間
  unsigned long OnTime_Arr[NUM_RELAYS];
  unsigned long OffTime_Arr[NUM_RELAYS];
};

// ==========================================================
// 宣告一個全域變數來存放我們的設定
// ==========================================================
RelaySettings relayConfig;

// ==========================================================
// 輔助函數:載入您指定的預設值,並將其寫入 EEPROM
// ==========================================================
void SaverelayConfig() {
// 使用 EEPROM.put() 將整個結構體一次性寫入 EEPROM
  EEPROM.put(SETTINGS_ADDR, relayConfig);
 
  // 寫入魔術數字,標記 EEPROM 已被成功初始化
  EEPROM.put(MAGIC_NUMBER_ADDR, MAGIC_VALUE);

  Serial.println("已成功載入並儲存到 EEPROM。");

  }

void setup() {
Serial.println("\n--- Arduino EEPROM 陣列範例啟動 ---");
// ========================================================== // 檢查 EEPROM 中的魔術數字,判斷陣列資料是否有效 // ========================================================== byte storedMagicValue; EEPROM.get(MAGIC_NUMBER_ADDR, storedMagicValue); if (storedMagicValue == MAGIC_VALUE) { // 如果魔術數字匹配,表示 EEPROM 已經被初始化過,可以安全讀取陣列 Serial.println("偵測到有效設定,從 EEPROM 載入..."); EEPROM.get(SETTINGS_ADDR, relayConfig); } else { // 如果不匹配,表示首次運行或資料損毀,則載入預設值並存入 EEPROM Serial.println("EEPROM 無有效設定,載入預設值並儲存..."); loadDefaultsAndSave(); } printCurrentSettings(); // 顯示目前載入的設定 Serial.println("\n輸入 'reset' 將所有設定恢復為預設值。");

}











2026年2月2日 星期一

Arduino Mega2560 產品 Burn-In 燒機設計

依照專案需求
1. 同時16 port relay 切換電源
2. 有10組 Config 設定 可執行不一樣的開機跟關機時間
3. 治具端 有兩顆 按鍵 a. 當下的config 開始執行 b. 停止執行
4. 上位機設定程式, 可設定10組的config值
硬體: 
1. Mega2560 => FW 設計
2. 16 port 5VDC relay board 
上位機程式設計:


Demo:


2025年11月28日 星期五

Microchip PAC1934 - ADM00805 與 Arduino 通訊

ADM00805評估板
ADM00805具有USB連接器,用於連接到電腦進行裝置通訊。給PAC1934裝置供電有兩種方式:
一是透過USB連接器直接由VBUS供電,
二是透過VDD的外部連接供電。
利用板上MCP2221 USB轉I2C橋接器,可透過USB提供I2C通訊。
另外還有一個連接器,透過此連接器可以將VDD_IO、接地、SDA和SCL連接到PC主機板或Linux系統等外部源,可直接實現I2C通訊。有關使用直接I2C連接的重要詳細信息
Microchip_PAC193x Arduino_Library
The PAC1934 is a four channel power/energy monitor with current sensor amplifier and bus voltage monitors that feed high resolution ADCs.  Digital circuitry performs power calculations and energy accumulation.  The PAC1934 enables energy monitoring with integration periods from 1 ms to up to 36 hours.  Bus voltage, sense resistor voltage, and accumulated proportional power are stored in registers for retrieval by the system master or embedded controller. This library supports all the 4 channels on the PAC1934.  Source: http://ww1.microchip.com/downloads/en/DeviceDoc/PAC193x_Arduino_Library_v1_0_0.zip

透過Arduino的I2C與ADM00805連接去量測電壓與電流

將上述連結的Arduino Library 的Microchip_PAC193x sample upload 到Mega2560板子上就可以看到輸出了!!






2024年2月23日 星期五

雷達產品測試站別規劃

一個產品的產出在生產流程上, 脫離不了從 繪製PCB線路圖 -- Layout Gerber --製作PCB板 --SMT 打件 -- PCBA 測試 --組裝 --成品測試 --包裝出貨
在生產測試的環節中
PCBA測試規劃有
F1站--量測板端輸入電壓電流, 各LDO分壓電壓點, Download產品FW, 測試板子功能, 寫入產品序號
產測工程師需要完成治具(輔助生產的流程)的製作以及產測程式的撰寫
接線前
接線後

測試程式畫面測試規劃

測試程式畫面測試規格
成品測試
F4站--燒錄產品FW, 測試客戶端功能


2023年10月29日 星期日

Arduino Mega2560 Test Fixture Application

Purpose:

1. 兩個按鍵作為進出平台的開關 另一按鍵為平台上另一上下動作的開關
2. 完成所有動作後按任一進出按鍵就進行退出動作在退出時 蜂鳴器要發聲
3. 完成進入動作 COUNTER 要記數加一次為了控制頂針壓合次數
4. 手動跟程式控制同時可以動作

1. Two buttons serve as switches for entering and exiting the platform. The other button serves as another switch for up and down movements on the platform.
2. After completing all actions, press any entry or exit button to exit. The buzzer will sound when exiting.
3. After completing the entry action COUNTER, the count needs to be added once in order to control the number of times the ejection pin is pressed.
4. Manual and program control can be performed at the same time

Architecture:

零件配置:
1. Arduino Mega2560 控制板

2. 8 Port Relay board
3. 3 個 push button
4. 3個氣壓控制閥
5. 1個蜂鳴器
6. 次數記數器
7. 4個氣壓缸
8. ACto12VDC變壓器
YouTube Demo;
Mega2560 Code:
#include <Arduino_FreeRTOS.h>
//---------------structure ----------------------------------------
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t LEDFlag=1;
  uint8_t BTFlag = 0;
  uint8_t ServoFlag = 0;
  uint8_t CloseFlag=0;
  uint8_t InFlag=0;
  uint8_t OutFlag=0;
  uint8_t UpFlag=0;
  uint8_t Up1Flag=0;
  uint8_t Up2Flag=0;
  uint8_t Buzzer_Flag=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;
const uint8_t F_PIN = 12;
int buzzerPin=11;
//----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;
//---------治具定義------------------------------------------
uint8_t In1_B_Pin = 47;  
uint8_t In2_B_Pin = 49;
uint8_t Up_B_Pin = 51;

uint8_t In_S_Pin = 23;
uint8_t Out_S_Pin = 25;
uint8_t UpDown1_S_Pin = 27;
uint8_t UpDown2_S_Pin = 29;
//----relay--------
uint8_t InOut_V_Pin = 22;
uint8_t UpDown1_V_Pin = 24;
uint8_t UpDown2_V_Pin = 26;

uint8_t SPK_O_Pin = 28;  //30預留 12V relay
//uint8_t Count_O_Pin = 30;
uint8_t Count_O_Pin = 32;
//----------------------------------------------------
uint8_t DUTPin = 23;
uint8_t Sensor1Pin = 23;
uint8_t Sensor2Pin = 25;
uint8_t Sensor3Pin = 27;
uint8_t Sensor4Pin = 29;
//-------------------------------------------
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);
  pinMode(Sensor1Pin,INPUT_PULLUP); //23
  pinMode(Sensor2Pin,INPUT_PULLUP); //25
  pinMode(Sensor3Pin,INPUT_PULLUP); //27
  pinMode(Sensor4Pin,INPUT_PULLUP); //29
  //----治具 ----------------
  pinMode(In_S_Pin,INPUT_PULLUP); //23
  pinMode(Out_S_Pin,INPUT_PULLUP); //25
  pinMode(UpDown1_S_Pin,INPUT_PULLUP); //27
  pinMode(UpDown2_S_Pin,INPUT_PULLUP); //29
  pinMode(In1_B_Pin,INPUT_PULLUP); //47
  pinMode(In2_B_Pin,INPUT_PULLUP); //49
  pinMode(Up_B_Pin,INPUT_PULLUP); //51
  //----relay--------
  pinMode(InOut_V_Pin, INPUT);   //22
  pinMode(UpDown1_V_Pin, INPUT); //24
  pinMode(UpDown2_V_Pin, INPUT); //26
  pinMode(SPK_O_Pin, INPUT);     //28 //30預留 12V relay
  pinMode(Count_O_Pin, INPUT);   //32
 // 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)
  {
//---------Fixture -------------------------
    vFixtureTask();   
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);
      }
    }
  }
  //------fixture --------
  if(strstr(data, "IN") != NULL )
  {
     if( (digitalRead(Out_S_Pin) == LOW) && flag.Up1Flag==0 && flag.Up2Flag==0)
     {
       flag.InFlag=3;
       pinMode(InOut_V_Pin , OUTPUT);
       digitalWrite(InOut_V_Pin , HIGH);    //in進
     }
     else
     {
       Serial.println(F("PLS OUT Fixture first!!"));
     }
  }
 
  if(strstr(data, "OUT") != NULL)
  {
     if( (digitalRead(In_S_Pin) == LOW) && flag.Up1Flag==0 && flag.Up2Flag==0)
     {
       flag.InFlag=5;
       pinMode(InOut_V_Pin , OUTPUT);
       digitalWrite(InOut_V_Pin , LOW); //出
     }
     else
     {
      Serial.println(F("PLS IN Fixture first!!"));
     }
  }
 
  if(strstr(data, "UP1") != NULL)
  {
     //if((flag.InFlag==2 || flag.InFlag==3) && flag.Up1Flag==1 && flag.Up2Flag==0 )
     if((flag.InFlag==2 || flag.InFlag==3) && (digitalRead(UpDown1_S_Pin ) == LOW) && flag.Up2Flag==0 )
     {
      pinMode(UpDown1_V_Pin , OUTPUT);
      digitalWrite(UpDown1_V_Pin , HIGH); //UP1
      flag.Up1Flag=0;
     }
     else
     {
      Serial.println(F("PLS DWON1 Fixture first!!"));
     }
  }

  if(strstr(data, "DOWN1") != NULL)
  {
     if((flag.InFlag==2 || flag.InFlag==3) && flag.Up1Flag==0 && flag.Up2Flag==0 )
     {
      pinMode(UpDown1_V_Pin , OUTPUT);
      digitalWrite(UpDown1_V_Pin , LOW); //UP1
      flag.Up1Flag=1;
     }
     else
     {
      Serial.println(F("PLS UP1 Fixture first!!"));
     }
  }

  if(strstr(data, "UP2") != NULL)
  {
     if((flag.InFlag==2 || flag.InFlag==3) && flag.Up1Flag==1 )
     {
       //Serial.println("flag.InFlag"+String(flag.InFlag));
       //Serial.println("flag.Up1Flag"+String(flag.Up1Flag));
       //Serial.println("flag.Up2Flag"+String(flag.Up2Flag));
       
       if((digitalRead(UpDown2_S_Pin) == LOW))
       {
         pinMode(UpDown2_V_Pin , OUTPUT);
         digitalWrite(UpDown2_V_Pin , HIGH); //UP1
         flag.Up2Flag=0;
       }
       
     }
     else
     {
       Serial.println(F("PLS DWON2 Fixture first!!"));
     }
  }

  if(strstr(data, "DOWN2") != NULL)
  {
     //Serial.println("flag.InFlag"+String(flag.InFlag));
     //Serial.println("flag.Up1Flag"+String(flag.Up1Flag));
     //Serial.println("flag.Up2Flag"+String(flag.Up2Flag));
     
     if((flag.InFlag==2 || flag.InFlag==3) && flag.Up1Flag==1 && flag.Up2Flag==0 )
     {
       pinMode(UpDown2_V_Pin , OUTPUT);
       digitalWrite(UpDown2_V_Pin , LOW); //UP1
       flag.Up2Flag=1;
       pinMode(Count_O_Pin , OUTPUT);
       digitalWrite(Count_O_Pin  , LOW);  
       delay(500);
       digitalWrite(Count_O_Pin  , HIGH);
     }
     else
     {
       Serial.println(F("PLS UP2 Fixture first!!"));
     }
  }
  //-----------fixture end---------------------------------------------
}
//------ vFixtureTask start --------------------------------
void vFixtureTask()
{
 
  if( (digitalRead(In1_B_Pin) == LOW && digitalRead(In2_B_Pin) == LOW ) && (flag.InFlag==5 || flag.InFlag==1 || flag.InFlag==9) )
  {
    flag.InFlag=1;
    pinMode(InOut_V_Pin , OUTPUT);
    digitalWrite(InOut_V_Pin  , HIGH);   //In 因為氣壓跟之前反接 所以 HIGH進

    if(digitalRead(In_S_Pin) == LOW)  
    {
      flag.InFlag=2;
      //Serial.println(flag.InFlag);
      //Serial.println(F("ok>"));
    }
  }

  if( (digitalRead(In_S_Pin) == LOW ) && ( flag.InFlag==2 ) )
  {
    pinMode(UpDown1_V_Pin, OUTPUT);
    digitalWrite(UpDown1_V_Pin , LOW);   //DOWN
    if(digitalRead(UpDown1_S_Pin) == LOW)  
    {
      flag.Up1Flag = 1;  //1在下面 0在上面
      //Serial.println(F("UpDown1_S_Pin"));
      //Serial.println(F("ok>"));
      pinMode(UpDown2_V_Pin, OUTPUT);
      digitalWrite(UpDown2_V_Pin , LOW);   //DOWN
      if(digitalRead(UpDown2_S_Pin) == LOW)  
      {
        flag.Up2Flag = 1;
        //Serial.println(F("UpDown2_S_Pin"));
        //Serial.println(F("ok>"));
        pinMode(Count_O_Pin , OUTPUT);
        digitalWrite(Count_O_Pin  , LOW);  
        delay(1000);
        flag.InFlag = 3;
        //Serial.println(flag.InFlag);
        //Serial.println(F("ok>"));
        digitalWrite(Count_O_Pin  , HIGH);
        //flag.OutFlag = 0;          
      }
    }
  }
  //if( (digitalRead(In1_B_Pin) == HIGH || digitalRead(In2_B_Pin) == HIGH ) && (flag.InFlag==0 || flag.InFlag==1 ) )
  if( (digitalRead(In1_B_Pin) == HIGH || digitalRead(In2_B_Pin) == HIGH ) && ( flag.InFlag == 1 ) )
  {
    //flag.InFlag=8;
    //Serial.println(flag.InFlag);
    //Serial.println(F("ok>"));
   
    pinMode(SPK_O_Pin , OUTPUT);
    digitalWrite(SPK_O_Pin , LOW);   //SPK
   

    pinMode(UpDown2_V_Pin, OUTPUT);
    digitalWrite(UpDown2_V_Pin, HIGH);   //上
    delay(300);
    pinMode(UpDown1_V_Pin, OUTPUT);
    digitalWrite(UpDown1_V_Pin , HIGH);   //上
    delay(300);
    pinMode(InOut_V_Pin , OUTPUT);
    digitalWrite(InOut_V_Pin  , LOW);   //出
   
    digitalWrite(SPK_O_Pin , HIGH);   //SPK

    if(digitalRead(Out_S_Pin) == LOW)  
    {
      digitalWrite(SPK_O_Pin , HIGH);   //SPK
      flag.InFlag=9;
      flag.Up1Flag = 0;
      flag.Up2Flag = 0;
    }
  }

  if( (digitalRead(In1_B_Pin) == LOW || digitalRead(In2_B_Pin) == LOW ) && (digitalRead(In_S_Pin) == LOW && flag.InFlag==0) )
  {
    //Serial.println(F("Out_S_Pin"));
    //Serial.println(F("ok>"));
    flag.InFlag=5;
    pinMode(InOut_V_Pin , OUTPUT);
    digitalWrite(InOut_V_Pin  , LOW);   //出
  }

  //if( (digitalRead(In1_B_Pin) == LOW || digitalRead(In2_B_Pin) == LOW ) && (flag.InFlag==2 || flag.InFlag==3) )
  if( (digitalRead(In1_B_Pin) == LOW || digitalRead(In2_B_Pin) == LOW ) && (flag.InFlag==3) )
  {
    flag.InFlag=1;
  }

  if( (digitalRead(Up_B_Pin ) == LOW ) && flag.Up2Flag == 1  && flag.Up1Flag == 1)
  {
    pinMode(UpDown2_V_Pin, OUTPUT);
    digitalWrite(UpDown2_V_Pin, HIGH);   //上
    delay(300);
    flag.Up2Flag=0;
  }
  else if( (digitalRead(Up_B_Pin ) == LOW )  && flag.Up2Flag == 0 && flag.Up1Flag == 1)
  {
    pinMode(UpDown2_V_Pin, OUTPUT);
    digitalWrite(UpDown2_V_Pin, LOW);   //下
    if(digitalRead(UpDown2_S_Pin) == LOW)  
    {
        flag.Up2Flag=1;
    }
  }
}
//-------------------------------------------



2023年9月10日 星期日

Inductive trash can with ESP32

Purpose:

利用手上ESP32板子為主架構搭配PIR HC-SR505 sensor感應去控制servo motor旋轉角度另添加一塊充電模組可以完成一個充電式感應垃圾桶!!

Using the ESP32 board as the main structure with the PIR HC-SR505 sensor to control the rotation angle of the servo motor, and adding a charging module to complete a rechargeable inductive trash can!!

BOM:

Figure1 PIR HC-SR505

Figure2 充電鋰電池

Figure3 ESP32
                                                                   

Figure4 充電板
Circuit:
Figure5 整體架構
YouTube Demo:
演示影片
Code Introduce:
#include <ESP32Servo.h>
#include <BluetoothSerial.h>
//--------- Flag structure --------------------------------------
typedef struct _vFlag
{
  uint8_t LEDFlag=1;
  uint8_t BTFlag = 0;
  uint8_t ServoFlag = 0;
  uint8_t PIR_Flag = 1;
  uint8_t PIR_status = 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;
//------------------------------------------------
#define LED_BUILTIN 2
BluetoothSerial SerialBT;
//------------------------------------------------
Servo myservo;  // create servo object to control a servo
// Recommended PWM GPIO pins on the ESP32 include 2,4,12-19,21-23,25-27,32-33
int servoPin = 13;
//-----------------------
int inPin = 22;  //PIR pin
//-------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(inPin, INPUT);
  SerialBT.begin("BT_Servo");    // BTName
  myservo.setPeriodHertz(50);    // standard 50 hz servo
  myservo.attach(servoPin, 500, 2400); // attaches the servo on pin 13 to the servo object
  myservo.write(0);
}
//-----------------------------------------
void loop()
{
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    if(flag.LEDFlag == 1)  //flash LED
    {
      digitalWrite(LED_BUILTIN, HIGH);
      vTaskDelay(300);
      digitalWrite(LED_BUILTIN, LOW);
      vTaskDelay(300);
    }
    if (flag.PIR_Flag == 1)  //start PIR detect
    {
      Serial.println(flag.PIR_status);
      if(digitalRead(inPin) == HIGH)
      {  
        if(flag.PIR_status==0)
        {
          Serial.println("Presence detected");
          myservo.write(100);
          flag.PIR_status=1;
          vTaskDelay(20);    
        }
      }
      else
      {
        if(flag.PIR_status==1)
        {
          Serial.println("No detected");
          myservo.write(0);
          flag.PIR_status=0;  
        }
      }
    }
    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
          //傳輸給藍芽
          SerialBT.println(Uart.line);
         
          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)
    while (SerialBT.available())
    {
      //讀取藍芽資料
      String BTdata = SerialBT.readString();
      //顯示在序列視窗
      Serial.println(BTdata);
      //char charBuf[BTdata.length() + 1];
      //BTdata.toCharArray(charBuf, BTdata.length());
      BTprocessCommand(BTdata); // do something with the command
      //processCommand(charBuf); // do something with the command
    }//while (BT.available())

  }
}
void BTprocessCommand(String data)
{
  if (data == "100")
  {
    Serial.println(F("SERVO_100"));
    myservo.write(100);
  }
  if (data == "10")
  {
    Serial.println(F("SERVO_10"));
    myservo.write(10);
    //myservo.detach();
  }
  if (data == "180")
  {
    Serial.println(F("SERVO_180"));
    myservo.write(180);
  }
  if (data == "50")
  {
    Serial.println(F("SERVO_50"));
    myservo.write(50);
    //myservo.detach();
  }
}
//----------------------------------------
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"));
  }
  //-------------- Servo --------------------
  if (strstr(data, "SERVO_5")!= NULL)
  {
    Serial.println(F("SERVO_5"));
    myservo.write(5);
    //myservo.detach();
  }
  if (strstr(data, "SERVO_10")!= NULL)
  {
    Serial.println(F("SERVO_10"));
    myservo.write(10);
  }
  if (strstr(data, "SERVO_50")!= NULL)
  {
    Serial.println(F("SERVO_50"));
    myservo.write(50);
  }
  if (strstr(data, "SERVO_100")!= NULL)
  {

    Serial.println(F("SERVO_100"));
    myservo.write(100);
  }
  if (strstr(data, "SERVO_180")!= NULL)
  {
    Serial.println(F("SERVO_180"));
    myservo.write(180);
  }
  if (strstr(data, "SERVO_270")!= NULL)
  {
    Serial.println(F("SERVO_270"));
    myservo.write(270);
  }
}
//------------------------------------------