# 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());
}
```