嵌入式項目:STM32刷卡指紋智能門禁系統

?本文詳細介紹基于STM32的刷卡指紋智能門禁系統。

?獲取資料/指導答疑/技術交流/選題/幫助,請點鏈接:
https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt

1 系統功能

1.1 功能概述

????????本系統由STM32硬件端(下位機)和QT管理平臺(上位機)構成,兩者通過WiFi無線連接,采用TCP協議通信。

硬件端:STM32及外設模塊(RC522刷卡、AS608指紋、OLED顯示、ESP8266 WiFi、舵機開門、蜂鳴器、LED);

管理平臺:用QT實現并在電腦運行。

主要功能:系統登錄、建立連接及通信、錄入用戶、查看用戶、刪除用戶、刷卡開門、指紋開門、查看開門記錄、管理員開門、退出登錄等。

系統的管理員界面及STM32硬件端實物圖如下:

1.2 主要功能

1.2.1 系統登陸

運行管理平臺需要先登錄,登錄界面如下:

登錄后進入管理員系統,界面如下:

1.2.2 連接通信

????????上位機與下位機通信需要先建立連接,首先電腦要連接STM32硬件端WiFi模塊發射的WiFi(wifi: hello-esp8266,密碼:6個8),然后在管理員界面輸入IP并點擊連接,連接成功后在OLED屏上會顯示在線狀態,如下:

1.2.3 添加用戶

在管理員界面點擊“添加用戶”,再輸入用戶信息,點擊確定,然錄入新卡,接著采集指紋錄入(需采集2次并且一致),以上步驟無誤后提示錄入成功,如下:

1.2.4 查看用戶

在管理員界面點擊“用戶列表”可查看用戶,如下:

1.2.5 刪除用戶

在用戶列表上選中某個用戶,再點擊“刪除用戶”,即可將該用戶刪除,如下:

1.2.6 刷卡開門

用已錄入的卡去刷卡,能夠開門并在OLED屏顯示開門成功,如下:

1.2.7 指紋開門

用已錄入的指紋去刷指紋,能夠開門并在OLED屏顯示開門成功,如下:

1.2.8 管理員開門

在管理員界面點擊“開門”,可開門并在OLED屏顯示開門成功,如下:

1.2.9 查看開門記錄

在管理員界面點擊“歷史記錄”,可查看開門記錄,如下:

1.2.10 退出登陸

在管理員界面點擊“退出”,可退出管理員系統,回到登陸界面,如下:

2 系統硬件

2.1 原理圖

2.2 PCB

3 軟件實現

3.1 STM32軟件

3.1.1 主函數main

????????在main函數中,主要完成系統及外設模塊的初始化,還有一個重要的模塊:time service的初始化以及注冊3個不同間隔執行的函數,分別是0間隔(相當于while(1))、100ms間隔、1000ms的間隔執行,主體程序均可在這3個不同間隔執行的函數中運行。

Main程序如下:

int main(void)
{// 配置系統時鐘72M,使用外部晶振system_clock_config();delay_init();// 調試打印串口初始化usart_init(115200);printf("\n hello stm32.\r\n");/* 硬件模塊驅動初始化 */led_init();		//LED初始化beep_init();	//蜂鳴器初始化oled_init();	// OLED初始化rc522_init();	// RC522 rfid模塊初始化// 指紋模塊AS608初始化:usart3用于AS608usart3_init(AS608_UART_BAUDRATE, as608_data_recv);as608_init(usart3_send, as608_finger_event_cb);// wifi通信初始化wifi_proto_init();/* time service需要timer提供時鐘 */timsrv_init();TIM2_init(72-1, 1000-1, timer_timeout_cb);	// 1ms 定時TIM2_start();// 注冊任務,執行間隔以ms為單位timsrv_register_task(0, task_while);timsrv_register_task(100, task_100ms);timsrv_register_task(1000, task_1000ms);//舵機初始化:PWM3為舵機提供pwmpwm3_init(72-1, 20000-1);	//舵機要求:頻率1MHz,周期20mspwm3_start();servo_init(20000, pwm3_set_pulse);// 顯示主界面ui_show_destop();ui_show_online(false);memset(&g_sys_info, 0, sizeof(system_info_t));g_sys_info.work_mode = WORK_MODE_NORMAL;while(1){// 主任務:根據時間間隔執行注冊的任務timsrv_tasks_running();}
}

3.1.2 事件處理process

事務處理主要是上述time service注冊的3個不同間隔執行的函數,如下:

/* 0間隔執行,相當于while(1)執行 */
void task_while(void)
{//wifi接收數據處理wifi_data_handle();// 服務器協議處理server_proto_handle();}/* 每間隔100ms執行一次 */
void task_100ms(void)
{static uint8_t card_wait = 0;uint8_t card_id[8];int ret, i;//掃描讀卡,每次讀到卡間隔2Sif(card_wait == 0) {ret = rc522_read_card(card_id);if(ret == 0) {beep_on();timsrv_set_delay_work(100, beep_off);proto_0x11_sendCardnum(card_id);card_wait = 1;printf("get card: ");for(i=0; i<8; i++)printf("%02X ", card_id[i]);printf("\n");}}else{if(card_wait ++ >= 20)card_wait = 0;}//指紋模塊運行處理as608_run_process();
}/* 每間隔1000ms執行一次 */
void task_1000ms(void)
{static int num = 0;printf("%s: %d\r\n", __FUNCTION__, num);num ++;
}

3.1.3 外設事件處理

外設像WiFi、指紋模塊AS608等有事件回調的處理,如下:

//wifi模塊事件回調處理函數
int wifi_event_cb(wifi_event_e event, int param)
{printf("wifi event: %d, param: %d\n", event, param);switch(event){case WIFI_EVE_TCP_CONNECT: 		//TCP連接g_sys_info.online = true;led_on();ui_show_online(true);break;case WIFI_EVE_TCP_DISCONNECT: 	//TCP斷開g_sys_info.online = false;led_off();ui_show_online(false);break;default:break;}return 0;
}//指紋模塊事件回調處理函數
int as608_finger_event_cb(as608_event_e event, int param)
{printf("as608 event: %d, param: %d\n", event, param);switch(event){case AS608_EVE_GET_FINGER:	//檢測到指紋按下beep_on();timsrv_set_delay_work(100, beep_off);break;case AS608_EVE_SEARCH_FINGER:	//識別到識別proto_0x14_recognFingerId(param);break;case AS608_EVE_ADD_WAIT_FINGER:		//添加指紋:等待指紋break;case AS608_EVE_ADD_1ST_FINGER:	//添加指紋:采集第一個指紋beep_on();timsrv_set_delay_work(100, beep_off);proto_0x13_addFingerResult(1);break;case AS608_EVE_ADD_2ND_FINGER:	//添加指紋:采集第二個指紋beep_on();timsrv_set_delay_work(100, beep_off);proto_0x13_addFingerResult(2);break;case AS608_EVE_ADD_RESULT:	//添加指紋結果if(param == 0)proto_0x13_addFingerResult(0);elseproto_0x13_addFingerResult(4);break;case AS608_EVE_ADD_TIMEOUT:		//添加指紋超時proto_0x13_addFingerResult(3);break;default:break;}	return 0;
}

3.1.3 通信協議處理

????????STM32需要跟上位機QT交互,因此需要通信協議,以解析通信的內容及作相關處理。例如STM32端讀到卡片需發送給QT端以判斷是否開門、若要開門QT端還要發送開門指紋給STM32讓其執行開門動作。

STM32主動發送協議的部分代碼:

int proto_0x11_sendCardnum(unsigned char *cardnum)	//發送卡號
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;data_len += proto_add_param(data_buf, ID_CARD_NUM, 8, cardnum);proto_makeup_packet(0x11, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}
int proto_0x13_addFingerResult(unsigned char result)		//發送添加指紋結果
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;printf("add finger result %d\n", result);data_len += proto_add_param(data_buf, ID_ADD_FINGER_RES, 1, &result);proto_makeup_packet(0x13, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}int proto_0x14_recognFingerId(int id)	//發送識別到的指紋
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;data_len += proto_add_param(data_buf, ID_FINGER_ID, 4, (unsigned char *)&id);proto_makeup_packet(0x14, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}

STM32接收到協議的處理:

static int server_proto_dispatch(uint8_t *pack, int len)
{uint8_t cmd = 0;uint8_t *data = NULL;int data_len = 0;int ack_len = 0;int ret;ret = proto_packet_analy(pack, len, &cmd, &data_len, &data);if(ret != 0)return -1;printf("ptoto cmd: 0x%02x, pack_len: %d, data_len: %d\n", cmd, len, data_len);switch(cmd){case 0x03:ret = server_0x03_heartbeat(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x10:ret = server_0x10_opendoor(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x12:ret = server_0x12_toWorkmode(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x15:ret = server_0x15_delete_finger(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;default:printf("error: cmd 0x%02x not found!\r\n", cmd);break;}/* send ack data */if(ret==0 && ack_len>0){proto_makeup_packet(cmd, proto_tmp_buf, ack_len, proto_recv_buf, sizeof(proto_recv_buf), &data_len);server.send(proto_recv_buf, data_len);}return 0;
}

3.2 QT軟件

3.2.1 UI界面布局

在Qt creator中布局UI界面,如下:

3.2.2 按鈕槽函數處理

????????按鈕的槽函數是通過信號與槽機制實現的。當用戶點擊按鈕時,按鈕會發出一個?clicked()?信號,開發者可以將其連接到一個自定義的槽函數上,以處理按鈕點擊事件。

void MainWindow::on_connectBtn_clicked()	//點擊連接
{if(ui->connectBtn->isChecked()){QString svr_ip;svr_ip = ui->serverIpEdit->text();qDebug() << "server ip" << svr_ip;client->connectToHost(svr_ip, DEFAULT_SERVER_PORT);}else{client->disconnectFromHost();}
}void MainWindow::on_addUserBtn_clicked()	//添加用戶
{if(ui->addUserBtn->isChecked()){ui->userIdEdit->clear();ui->userNameEdit->clear();ui->phoneEdit->clear();ui->addUserWidget->setHidden(false);g_sys_info.work_mode = WORK_MODE_ADD_USER;g_sys_info.add_step = ADD_STEP_USERINFO;proto_0x12_toWorkmode(1, 1, 0);}else{to_destop_window();g_sys_info.work_mode = WORK_MODE_NORMAL;proto_0x12_toWorkmode(0, 0, 0);}
}void MainWindow::on_userListBtn_clicked()		//用戶列表
{if(ui->userListBtn->isChecked()){set_table_view(SQL_TABLE_USER);ui->tableView->setHidden(false);}else{ui->tableView->setHidden(true);}
}void MainWindow::on_delUserBtn_clicked()		//刪除用戶
{user_info_t user;QString tips;int id;if(!ui->userListBtn->isChecked())return;QModelIndex cur_index = ui->tableView->currentIndex();if(cur_index.row() == -1)return;id = sqlmodel->data(sqlmodel->index(cur_index.row(), 0)).toInt();memset(&user, 0, sizeof(user_info_t));sql_user_read(id, &user);tips = QString("是否刪除用戶<%1>?").arg(user.name);if(QMessageBox::No == QMessageBox::question(this, "注意", tips, QMessageBox::Yes|QMessageBox::No, QMessageBox::No))return;proto_0x15_delete_finger(user.finger);sql_user_del(id);sqlmodel->select();sqlmodel->submitAll();
}void MainWindow::on_historyBtn_clicked()		//歷史記錄
{if(ui->historyBtn->isChecked()){set_table_view(SQL_TABLE_HISTORY);ui->tableView->setHidden(false);}else{ui->tableView->setHidden(true);}
}void MainWindow::on_openDoorBtn_clicked()	//開門
{if(!mainwindow->tcp_connect)return;proto_0x10_opendoor(1);history_info_t history;memset(&history, 0, sizeof(history_info_t));QDateTime dtime = QDateTime::currentDateTime();QString str_dtime = dtime.toString("yyyy-MM-dd hh:mm:ss");history.time = dtime.toTime_t();strncpy(history.time_str, str_dtime.toLatin1().data(), TIME_STR_LEN);strncpy(history.name, "管理員", USER_NAME_LEN);sql_history_write(&history);
}void MainWindow::on_exitBtn_clicked()	//退出
{loginDialog_init();delete this;
}

3.2.3 SQL數據庫

用戶數據是用SQLite數據庫存儲的,建立2個數據表:用戶表(用戶信息)、記錄表(開門歷史);數據庫的操作就是插入添加、刪除、查詢等動作。

創建數據表:

static int sql_create_user_tbl(void)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("create table if not exists %1(""%2 int primary key not null,""%3 char(32),""%4 char(16), ""%5 char(32), ""%6 int);").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_PHONE).arg(SQL_COL_CARD).arg(SQL_COL_FINGER);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_create_history_tbl(void)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("create table if not exists %1(""%2 int primary key not null,""%3 char(32),""%4 int, ""%5 char(32), ""%6 char(32), ""%7 int);").arg(SQL_TABLE_HISTORY).arg(SQL_COL_TIME).arg(SQL_COL_TIME_STR).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_CARD).arg(SQL_COL_FINGER);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}添加、刪除、讀取:
int sql_user_add(user_info_t *user)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("insert into %1(%2,%3,%4,%5,%6) ""values(%7,'%8','%9','%10',%11);").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_PHONE).arg(SQL_COL_CARD).arg(SQL_COL_FINGER).arg(user->id).arg(user->name).arg(user->phone).arg(user->card).arg(user->finger);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_user_del(int id)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("delete from %1 where %2=%3;").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(id);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_user_read(int id, user_info_t *user)
{QString sql_cmd;int ret = -1;sql_mutex.lock();sql_cmd = QString("select * from %1 where %2=%3;").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(id);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;sql_mutex.unlock();return -1;}if(sqlquery->next()){user->id = sqlquery->value(0).toInt();strcpy(user->name, (char *)sqlquery->value(1).toString().toLocal8Bit().data());strcpy(user->phone, (char *)sqlquery->value(2).toString().toLocal8Bit().data());strcpy(user->card, (char *)sqlquery->value(3).toString().toLocal8Bit().data());user->finger = sqlquery->value(4).toInt();ret = 0;}sql_mutex.unlock();return ret;
}

獲取資料/指導答疑/技術交流/選題/幫助,請點鏈接:
https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt

如有任何問題,請聯系作者,謝謝!
- - - 曾哥,專注嵌入式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70596.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70596.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70596.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機畢業設計 ——jspssm504springboot 職稱評審管理系統

作者&#xff1a;程序媛9688 開發技術&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等。 &#x1f31f;文末獲取源碼數據庫&#x1f31f; 感興趣的可以先收藏起來&#xff0c;還有大家在畢設選題&#xff08;免費咨詢指導選題&#xff09;&#xf…

安裝VM和Centos

安裝VM 一、打開虛擬機 二、選擇典型 三、選擇光盤 四、指定虛擬機位置 五、設置磁盤大小并拆分為多個文件 六、完成 安裝Centos 一、上述過程完成后我們直接打開虛擬機 二、語言選擇中文 三&#xff0c;默認安裝位置并點擊完成 四、點擊開始安裝 五、點擊設置密碼 等待安裝…

【AI應用】數字人涉及的一些主要 AI 技術

【AI論文解讀】【AI知識點】【AI小項目】【AI戰略思考】【AI日記】【讀書與思考】【AI應用】 在 數字人搭建 過程中&#xff0c;涉及多個 AI 技術&#xff0c;包括 訓練微調、算法、圖像合成、聲音克隆&#xff0c;每個部分都決定了最終效果的真實度、交互流暢度和個性化能力。…

【嘗試使用python調用Seismic unix】

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、代碼總結 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 使用seismic unix嘗試建立界面&#xff0c;首先想到使用pyqt&#xff0c…

【安裝及調試舊版Chrome + 多版本環境測試全攻略】

&#x1f468;&#x1f4bb; 安裝及調試舊版Chrome 多版本環境測試全攻略 &#x1f310; &#xff08;新手友好版 | 覆蓋安裝/運行/調試全流程&#xff09; &#x1f570;? 【背景篇】為什么我們需要舊版瀏覽器測試&#xff1f; &#x1f30d; &#x1f310; 瀏覽器世界的“…

2. EXCEL中函數和公式《AI賦能Excel》

歡迎來到滔滔講AI。今天我們來學習和討論下函數和公式是什么&#xff0c;以及它們之間的區別。 點擊圖片查看視頻 2、AI賦能EXCEL-函數和公式 一、什么是函數 首先&#xff0c;我們來了解一下函數。函數是Excel中預定義的計算工具&#xff0c;能夠幫助我們快速進行各種計算。 …

Python常見面試題的詳解16

1. 如何強行關閉客戶端和服務器之間的連接&#xff1f; 在網絡編程中&#xff0c;有時需要強行中斷客戶端和服務器之間的連接。對于基于 TCP 協議的連接&#xff0c;由于其面向連接的特性&#xff0c;需要采取特定的步驟來確保連接被正確關閉&#xff1b;而 UDP 是無連接協議&a…

【深度學習】矩陣的核心問題解析

一、基礎問題 1. 如何實現兩個矩陣的乘法&#xff1f; 問題描述&#xff1a;給定兩個矩陣 A A A和 B B B&#xff0c;編寫代碼實現矩陣乘法。 解法&#xff1a; 使用三重循環實現標準矩陣乘法。 或者使用 NumPy 的 dot 方法進行高效計算。 def matrix_multiply(A, B):m, n …

在CentOS 7下部署NFS的詳細教程

在CentOS 7下部署NFS的詳細教程 NFS&#xff08;Network File System&#xff09;是一種分布式文件系統協議&#xff0c;允許用戶在網絡中的不同主機之間共享文件和目錄。NFS廣泛應用于Linux和Unix系統中&#xff0c;特別適合在集群環境中共享存儲資源。本文將詳細介紹如何在C…

js中的await與async的使用

以下兩個方法&#xff0c;區別只在有沒有catch&#xff0c;使用的時候卻要注意 // 封裝請求方法&#xff0c;同步loading狀態出去 export const fetchWithLoading async (fn: Function, params: any, loading: Ref) > {loading.value true;try {return await fn(params);…

Ubuntu服務器 /data 盤需要手動掛載的解決方案

服務器 /data 盤需要手動掛載的解決方案 如果重啟服務器后&#xff0c;發現 /data 盤 沒有自動掛載&#xff0c;通常是因為&#xff1a; /etc/fstab 配置文件 沒有正確設置 自動掛載。該磁盤 沒有被正確識別&#xff0c;需要手動掛載。文件系統錯誤 導致掛載失敗。 下面是解…

輸入搜索、分組展示選項、下拉選取,全局跳轉頁,el-select 實現 —— 后端數據處理代碼,拋磚引玉展思路

詳細前端代碼寫于上一篇&#xff1a;輸入搜索、分組展示選項、下拉選取&#xff0c;el-select 實現&#xff1a;即輸入關鍵字檢索&#xff0c;返回分組選項&#xff0c;選取跳轉到相應內容頁 —— VUE項目-全局模糊檢索 【效果圖】&#xff1a;分組展示選項 >【去界面操作體…

【SpringBoot】_統一功能處理:統一數據返回格式

目錄 1. 對所有返回類型方法進行統一數據返回類型處理 2. 部分返回類型方法存在的問題 3. 對兩種有誤的方法進行處理 仍以圖書管理系統為例。 創建Result對后端返回給前端的數據進行封裝&#xff0c;增加業務狀態碼與錯誤信息&#xff0c;將原本的數據作為data部分&#xff…

智能交通系統(Intelligent Transportation Systems):智慧城市中的交通革新

智能交通系統&#xff08;Intelligent Transportation Systems, ITS&#xff09;是利用先進的信息技術、通信技術、傳感技術、計算機技術以及自動化技術等&#xff0c;來提升交通系統效率和安全性的一種交通管理方式。ITS通過收集和分析交通數據&#xff0c;智能化地調度、控制…

Unity百游修煉(1)——FootBall詳細制作全流程

一、引言 游玩測試&#xff1a; Football 游玩測試 1.項目背景與動機 背景&#xff1a;在學習 Unity 的過程中&#xff0c;希望通過實際項目來鞏固所學知識&#xff0c;同時出于對休閑小游戲的喜愛&#xff0c;決定開發一款簡單有趣的小游戲加深自己的所學知識點。 動機&#…

QQ登錄測試用例報告

QQ登錄測試用例思維導圖 一、安全性測試用例 1. 加密傳輸與存儲驗證 測試場景&#xff1a;輸入賬號密碼并提交登錄請求。預期結果&#xff1a;賬號密碼通過加密傳輸&#xff08;如HTTPS&#xff09;與存儲&#xff08;如哈希加鹽&#xff09;&#xff0c;無明文暴露。 2. 二…

無人機實戰系列(三)本地攝像頭+遠程GPU轉換深度圖

這篇文章將結合之前寫的兩篇文章 無人機實戰系列&#xff08;一&#xff09;在局域網內傳輸數據 和 無人機實戰系列&#xff08;二&#xff09;本地攝像頭 Depth-Anything V2 實現了以下功能&#xff1a; 本地筆記本攝像頭發布圖像 遠程GPU實時處理&#xff08;無回傳&#…

讀取羅克韋爾AllenBradley Micro-Logix1400 羅克韋爾 CIP PCCC通信協議

通信協議實例下載 <-----實例下載 MicroLogix 1400的通信能力 MicroLogix 1400支持多種通信協議&#xff0c;包括CIP&#xff08;通過EtherNet/IP實現&#xff09;、Modbus RTU/TCP、DF1等4812。其硬件集成以太網端口&#xff0c;便于通過EtherNet/IP進行CIP通信15。 CIP…

Python游戲編程之賽車游戲6-5

1 碰撞檢測 在顯示了玩家汽車和“敵人”汽車之后&#xff0c;接下來就要實現玩家與“敵人”的碰撞檢測了。 代碼如圖1所示。 圖1 碰撞檢測代碼 第72行代碼通過pygame.sprite.spritecollideany()函數判斷P1和enemies是否發生了碰撞&#xff0c;如果發生碰撞&#xff0c;該函數…

【QT 網絡編程】HTTP協議(二)

文章目錄 &#x1f31f;1.概述&#x1f31f;2.代碼結構概覽&#x1f31f;3.代碼解析&#x1f338;Http_Api_Manager - API管理類&#x1f338;Http_Request_Manager- HTTP請求管理類&#x1f338;ThreadPool - 線程池&#x1f338;TestWindow- 測試類 &#x1f31f;4.運行效果&…