---
# System prepended metadata

title: ESP32學校專題
tags: [專題, MCU]

---

# ESP32學校專題
###### tags: `MCU``專題`
本專題應用到TCP/IP連線、ESP32外部中斷、ESP32 timer中斷
```c
#include<WiFi.h>
#include <lwip/sockets.h>

const int interruptPin = 13;  //中斷腳位，用於判斷鎖是否進入(觸動微動開關)
const int lockPin=4; //鎖的控制腳位
String connect_to_server="{\"COMMAND\": \"CONNECT\", \"client_type\": \"金城車站A1\", \"OPTION\": \"\", \"data\": \"\"}";
String RETURN = "{\"COMMAND\": \"SEND_DATA\", \"client_type\": \"金城車站A1\", \"OPTION\": \"RETURN\", \"data\": \"金城車站A1車號\"}";
String barrow1="{\"COMMAND\": \"SEND_DATA\", \"client_type\": \"金城車站A1\", \"OPTION\": \"BACK\", \"data\": \"[\"";
String barrow2=",\"金城車站A1\",\"success\",\"963\",]\"}";
hw_timer_t *Timer0_Cfg = NULL;

String line;
int count=0;
int lockTime=0;
bool flag = false;
bool flag2 = false;

const char *ssid = "mochawifi";
const char *password = "mocha777";

const IPAddress serverIP(192,168,108,40);//目標ip位址
uint16_t serverPort = 7000;

//設定esp32的port
WiFiServer server = WiFiServer(8080);

WiFiClient client;

//timer計時
void IRAM_ATTR Timer0_ISR(){
    count++;
    //Serial.println(count);
}

//使用中斷偵測鎖是否歸位(利用微動開關)
void IRAM_ATTR lock_In() {
  if(flag2==true){
    client.write(RETURN.c_str());
    Serial.println("鎖已進入");
    flag2=false;
  }
}
/*
void lock_Off(){
  Serial.println("鎖已退出");
  //client.write("Lockcheck""{\"msg\":\"一號鎖確認已退出\"}");
}
*/

void setup() {
  Serial.begin(115200);
  Serial.println();
  //設定輸出腳位、中斷腳位
  pinMode(lockPin, OUTPUT);
  digitalWrite(lockPin,HIGH);
  
  pinMode(interruptPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), lock_In, RISING);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), lock_Off, FALLING);

  // 每1000ms呼叫IRAM_ATTR Timer0_ISR
  Timer0_Cfg = timerBegin(0, 80, true);
  timerAttachInterrupt(Timer0_Cfg, &Timer0_ISR, true);
  timerAlarmWrite(Timer0_Cfg, 1000000, true);
  timerAlarmEnable(Timer0_Cfg);
  delay(10);

  //網路基礎設定
  WiFi.mode(WIFI_STA);
  WiFi.setSleep(false);

  //網路連線
  WiFi.begin(ssid,password);
  while(WiFi.status() != WL_CONNECTED){
    delay(2500);
    Serial.print(".");
  }
  
  Serial.println("connected");
  
  Serial.println();
  Serial.print("localIP:");
  Serial.println(WiFi.localIP());
  
  Serial.println();
  Serial.print("localPORT:");
  Serial.println("8080");
  
  Serial.println("Try to connect to server");
  
  Serial.println();
  int sockfd = lwip_socket(AF_INET,SOCK_STREAM,0);
  Serial.print("file descriptor:");
  Serial.println(sockfd);
  
  Serial.println();
  //如果連進server，將localIP、port、socket傳送給server以供訊息傳輸
  if(client.connect(serverIP,serverPort)){
    Serial.println("server connected");
    client.write(connect_to_server.c_str());
    /*
    client.write(sockfd);
    client.write(WiFi.localIP());
    client.write("8080");
    */
  }
  else
  {
    Serial.println("connection fail");
    client.stop();
    return;
  }
  
}

void loop() {
  //接收server訊息並顯示
  if(client.available()){
    line = client.readStringUntil('\n');
    Serial.print("msg from server:");
    Serial.println(line);
  }
  

  //依照伺服器訊息退鎖
  if(line.startsWith("1")){//收到serveer解鎖通知
    flag=true;
    flag2=true;
    lockTime=count;//開始計時退鎖時間
    digitalWrite(lockPin,LOW);//解鎖
    client.write((barrow1+line+barrow2).c_str());
    Serial.println("已通電");
    line=" ";
  }

  //退鎖後三秒自動上鎖
  if((count - lockTime) >= 3 && flag){//退鎖三秒後自動鎖回
    digitalWrite(lockPin,HIGH);
    Serial.println("已斷電");
    flag=false; 
  }
  
  client.write(Serial.readString().c_str());
}
```