成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【Arduino實驗室】NB的玩法,鴻蒙版遠程控制交通信號燈-ESP8266聯網

系統
文章由鴻蒙社區產出,想要了解更多內容請前往:51CTO和華為官方戰略合作共建的鴻蒙技術社區https://harmonyos.51cto.com

[[389181]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

Flag:如果本文閱讀量超過10000,或點贊+收藏超過100,我就推出鴻蒙版遠程控制信號燈以及其他智能硬件的文章!!

本文涉及到的源代碼和其他資源見附件!

【Arduino實驗室】中關于智能硬件的實驗在網上絕對是沒有的(有也是我發的),都由作者單獨設計。敬請期待后期的【鴻蒙實驗室】系列文章和視頻課程。

這個案例是將Python、PyQT6與Arduino結合。通過Arduino開發板控制3個LED(分別為紅黃綠3個顏色)來模擬交通信號燈。可以通過單擊PC端的三個燈控制Arduino開發板和3個LED。也可以點擊“自動”按鈕讓信號燈自動變換。本系統完全模擬真實的信號燈的自動切換過程。一開始紅燈亮6秒(為了減少一個完整變化周期的時間,并沒有讓信號燈亮過長時間),然后立刻切換到綠燈,繼續亮6秒。接下來綠燈閃爍6次(每1秒閃爍一次,一亮一滅),然后切換到黃燈,亮3秒,最后到紅燈(亮6秒),完成一個信號周期。如果點擊“停止”按鈕,信號燈會停止自動切換,但會在完成一個信號周期后停止。視頻演示見附件。

1. 需要準備哪些實驗設備和器材

本實驗需要準備的設備如下:

(1)PC一臺,系統可以是Windows、macOS或Linux,需要安裝Python環境和PyQt6、以及Arduino IDE;

(2)Arduino開發板一塊,推薦使用UNO;

(3)3個LED,建議紅、黃、綠各一個;

(4)ESP8266 Wi-Fi模塊一個,用于聯網;

(5)10K電阻一個;

(6)面包板一個,主要用于解決Arduino開發板接口不足的情況;

(7)杜邦線若干,可以多準備一些(最好有多種顏色),反正很便宜。需要兩類杜邦線:公對公、公對母;

2. ESP8266 Wi-Fi模塊與Arduino開發板連接

玩物聯網,其實涉及到硬件和軟件兩部分。硬件主要涉及到選擇和連接,一般并不涉及到硬件的設計和制作。本實驗的核心模塊是ESP8266,這是一個Wi-Fi模塊,價格非常便宜,國內價格在15到20元之間,某寶就有賣。

要做的第一步就是將ESP8266與Arduino開發板用杜邦線連接,程序是上傳到Arduino開發板上的,然后通過AT命令與ESP8266模塊交互。

ESP8266的樣子如圖1所示。這個模塊相對其他大多數模塊(如超聲波模塊、LED、按鈕等)要復雜一些,一共有8個管腳,也就是8個針。

ESP8288一般與Arduino開發板直接相連。Arduino開發板的樣子如圖2所示。管腳都是眼,所以需要若干公對母的杜邦線。

現在回到圖1的8個管腳,其實在開發階段,只需要連接其中的5個即可,在刷固件時,一般需要連接6個管腳(關于刷ESP8266固件的問題,我后面會寫文章介紹)。需要連接的5個管腳如下:

(1)3.3v:接到Arduino開發板的3.3v插孔上,記住,一定是3.3v,不要接在5v上,否則你還需要再買一塊ESP8266,切記、切記、切記;

(2)EN:同樣需要接到3.3v上,但Arduino開發板只有一個3.3v插孔,所以需要借助面包板;

(3)GND:接在Arduino開發板的GND插孔(一般有3個,插如任意一個GND插孔即可);

(4)TX:通常接在一個軟串口,本例接到8上;

(5)RX:通常接在一個軟串口,本例接到9上;

3. 模擬連接ESP8266與Arduino開發板

在正式連接之前,最好先用Fritzing模擬連接下,相當于畫個草圖,以免接錯。連接完成的效果如圖3所示。

這里要說明的是,EN與3.3v都需要接到Arduino開發板的3.3v管腳上,但Arduino開發板只有一個3.3v管腳,所以首先將Arduino開發板的3.3v管腳通過杜邦線(圖3中紅色的線)連接到面包板,然后EN與3.3v再通過杜邦線插入面包板中(兩根橙色的線),要記住,其中一根橙色的線要與紅色線在同一列,另外一根橙色的線在另一列,并讓這兩列用給一個10K的電阻相連,為了不讓ESP8266的EN和3.3v兩個管腳由于直接連通而短路。注意,一定要用電阻相連,推薦是10K歐的電阻。

4. 連接3個LED

LED的連接就簡單的多,LED如圖4所示。

短一些(左側)的管腳接地,長一些(右側)的管腳接某個數字管腳,本例綠、黃、紅分別接在了7、6、5管腳。由于Arduino開發板只有3個GND管腳,而ESP8266已經占用了一個,所以仍然需要借助面包板擴展GND管腳?;驹硎菍ND通過杜邦線與面包板連接(本例中的黑線),然后將3個LED的GND端都通過杜邦線插入與黑色杜邦線在面包板位置的同一列的其他插孔。最終的效果如圖5所示。

5. 在Arduino開發板上創建TCP服務器

ESP8266與Arduino交互通常有如下2種方式:

(1)ESP8266作為服務器;

(2)ESP8266作為客戶端;

本實驗采用了第1種方式,第2種方式后面我會寫文章介紹。

不管采用哪一種方式,首先要讓ESP8266上網。通常是連接家中的無線路由器,或用手機做的熱點。設置ESP8266需要通過AT命令,其實就是一組解釋執行的命令,與DOS命令類似。

ESP8266在出廠時的波特率是115200,所以執行AT命令,必須在這個波特率下。在setup函數中使用下面的代碼設置波特率,以及執行AT命令連接路由器。

  1. #include <SoftwareSerial.h> 
  2. SoftwareSerial wifi(WIFI_RX, WIFI_TX);   //RX, TX 
  3. void setup() { 
  4.   Serial.begin(9600); 
  5.   wifi.begin(115200); 
  6.   Serial.println("system is ready!"); 
  7.   wifi.println("AT+CWMODE=3\r\n");                             // 設置ESP8266的模式,3表示既可以作為路由器模式(AP),為其他設備提供用于上網的Wi-Fi,也可以作為普通的設備建立TCP連接 
  8.   delay(500); 
  9.   wifi.println("AT+CIPMUX=1\r\n"); 
  10.   delay(500); 
  11. wifi.println("AT+CWJAP=\"路由器名\",\"路由器密碼\"\r\n");       //連接路由器,請更換自己的路由器明和路由器密碼 
  12.  delay(500); 
  13.  wifi.println("AT+CIPSERVER=1,5000\r\n");                      // 啟動TCP服務,端口號是5000 
  14.  delay(500); 

這里的wifi負責與軟串口通信(通常硬串口主要用于刷固件),wifi.println函數用于執行AT命令。要注意,每執行一條AT命令,要等待一定的時間,這里是500毫秒。

當第一遍執行完,除非Arduino開發板重啟或重新上傳程序,否則setup函數只會執行一次。以后可以將連接路由器的代碼去掉了,因為ESP8266是有記憶功能的,這種配置性質的AT命令,執行完,會將執行結果記錄在案。所以下一次重啟ESP8266模塊時,不管執行不執行這條AT命令,ESP8266都會自動連接路由器。

不過其他代碼應該保留,因為這些代碼的執行結果是不會記錄在案的,當重啟ESP8266模塊時,需要重新執行這些AT命令來建立TCP服務。

經過測試,ESP8266在115200波特率的情況下,通過Wi-Fi傳輸數據容易出現亂碼,所以需要使用下面的代碼將ESP8266模塊的波特率強行改成9600,這樣數據傳輸非常穩定。

  1. wifi.println("AT+CIOBAUD=9600\r\n"); 

在Arduino開發板上建立TCP服務器的完整代碼如下:

  1. #include <SoftwareSerial.h> 
  2.  
  3. #define WIFI_TX       9 
  4. #define WIFI_RX       8 
  5. #define LED_RED       7 
  6. #define LED_YELLOW    6 
  7. #define LED_GREEN     5 
  8. SoftwareSerial wifi(WIFI_RX, WIFI_TX);   //RX, TX 
  9.  
  10. String command = "";             //  接收客戶端發過來的數據 
  11.  
  12. void setup() { 
  13.   //5、6、7三個管腳設置為輸出,以便輸出高電平來點亮LED 
  14.   pinMode(LED_RED, OUTPUT); 
  15.   pinMode(LED_YELLOW, OUTPUT); 
  16.   pinMode(LED_GREEN, OUTPUT); 
  17.   // 先將5、6、7三個管腳設置為低電平,默認LED是滅的狀態 
  18.   digitalWrite(LED_RED, LOW); 
  19.   digitalWrite(LED_YELLOW, LOW); 
  20.   digitalWrite(LED_GREEN, LOW); 
  21.  
  22.   Serial.begin(9600); 
  23.   wifi.begin(9600);     // 已經改成9600了,所以這里通過9600波特率與客戶端通過Wi-FI傳輸維護局 
  24.   Serial.println("system is ready!"); 
  25.  
  26.   wifi.println("AT+CWMODE=3\r\n"); 
  27.   delay(500); 
  28.   wifi.println("AT+CIPMUX=1\r\n"); 
  29.   delay(500); 
  30.   wifi.println("AT+CIPSERVER=1,4999\r\n"); 
  31.   delay(500); 
  32. // 該函數會不斷循環調用 
  33. void loop() { 
  34.   // 從客戶端(PC端)讀取發過來的數據   
  35.   while (wifi.available() > 0) { 
  36.     command += char(wifi.read());    
  37.     delay(4); 
  38.   } 
  39.   // 如果數據不為空,繼續處理 
  40.   if (command != "") { 
  41.     // 將接收到的命令輸出到串口監視器   
  42.     Serial.println(command); 
  43.     // 命令會自動加上一個前綴+IPD,如果包含這個前綴,才是傳過來的命令 
  44.     if (command.indexOf("+IPD") > -1) 
  45.     { 
  46.       if (command.indexOf("close_red") > -1) 
  47.       { 
  48.         digitalWrite(LED_RED, LOW); //0 燈滅 
  49.         Serial.println("close_red"); 
  50.       } 
  51.       else if (command.indexOf("close_yellow") > -1) 
  52.       { 
  53.         digitalWrite(LED_YELLOW, LOW); //0 燈滅 
  54.         Serial.println("close_yellow");      
  55.       } 
  56.       else if (command.indexOf("close_green") > -1) 
  57.       { 
  58.         digitalWrite(LED_GREEN, LOW); //0 燈滅 
  59.         Serial.println("close_green"); 
  60.       } 
  61.       else if (command.indexOf("open_red") > -1) 
  62.       { 
  63.         digitalWrite(LED_RED, HIGH);   //1 燈亮 
  64.         Serial.println("open_red");     
  65.       } 
  66.       else if (command.indexOf("open_yellow") > -1) 
  67.       { 
  68.         digitalWrite(LED_YELLOW, HIGH);   //1 燈亮 
  69.         Serial.println("open_yellow"); 
  70.       } 
  71.       else if (command.indexOf("open_green") > -1) 
  72.       { 
  73.         digitalWrite(LED_GREEN, HIGH);   //1 燈亮 
  74.         Serial.println("open");    
  75.       } 
  76.     } 
  77.     command = ""
  78.   } 

閱讀這段代碼要注意,這里提供了6個命令:close_red(紅色LED滅燈)、open_red(紅色LED亮燈)、close_yellow(黃色LED滅燈)、open_yellow(黃色LED亮燈)、close_green(綠色LED滅燈)、open_green(綠色LED亮燈)。只要command中包含著6個命令字符串中的一個,就確定客戶端發出了該命令。

然后使用Arduino IDE上傳程序即可(別忘了選擇開發板和端口)

PS:如果要改變端口號,可以直接修改5000,然后需要重啟Arduino開發板(當然,ESP8266也會重啟),這樣就會再次執行setup函數來重新啟動TCP服務。

6. 編寫Python程序

這里編寫客戶端程序,使用PyQt6編寫UI、使用Python編寫全部業務邏輯,由于代碼比較多,所以只給出了核心代碼,基本原理就是Python通過TCP Socket API連接ESP8255中的TCP Server,然后不斷發送上一節給出的6個命令。

  1. import TrafficLight1 
  2. import sys 
  3. import socket 
  4. from PyQt6.QtWidgets import QApplication,QMainWindow,QMessageBox 
  5. from PyQt6 import  QtGui 
  6. from PyQt6.QtCore import QThread 
  7.  
  8. ""
  9. 講師:李寧(蒙娜麗寧) 
  10. 微信:unitymarvel 
  11. 微信公眾號:極客起源 
  12. B站:https://space.bilibili.com/477001733 
  13. ""
  14. # 線程類,用于自動切換信號燈 
  15. class WorkThread(QThread): 
  16.  
  17.     def __init__(self, events): 
  18.         super(WorkThread, self).__init__() 
  19.         self.events = events 
  20.         self.running = False 
  21.  
  22.     def run(self): 
  23.         # 先關閉所有的信號燈 
  24.         self.events.close_all_light() 
  25.         # 開始自動切換信號燈 
  26.         while self.running: 
  27.             # 紅色信號燈打開6秒 
  28.             self.events.open_light("red"
  29.             QThread.msleep(6000) 
  30.             self.events.close_light("red"
  31.             QThread.msleep(200) 
  32.             # 綠色信號燈打開5秒 
  33.             self.events.open_light("green"
  34.             QThread.msleep(6000) 
  35.             # 綠色信號燈閃爍5次 
  36.             count = 0 
  37.             while count < 5: 
  38.                 self.events.close_light("green"
  39.                 QThread.msleep(500) 
  40.                 self.events.open_light("green"
  41.                 QThread.msleep(500) 
  42.                 count += 1 
  43.             self.events.close_light("green"
  44.             QThread.msleep(200) 
  45.             # 黃色信號燈顯示2秒 
  46.             self.events.open_light("yellow"
  47.             QThread.msleep(3000) 
  48.             self.events.close_light("yellow"
  49.             QThread.msleep(200) 
  50.         self.events.close_all_light() 
  51.         print("退出自動運行狀態"
  52.  
  53.  
  54. # 包含UI事件的代碼 
  55. class Events: 
  56.     def __init__(self, ui): 
  57.         self.ui = ui 
  58.         self.connected = False   # 是否已經與Arduino建立了連接 
  59.         self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 聲明協議類型,不寫類型使用默認的 
  60.         self.workThread = WorkThread(self) 
  61.     def close_all_light(self): 
  62.         self.close_light("red"
  63.         QThread.msleep(200) 
  64.         self.close_light("yellow"
  65.         QThread.msleep(200) 
  66.         self.close_light("green"
  67.         QThread.msleep(200) 
  68.     # 打開LED(color參數用于指定打開哪一個顏色的信號燈)     
  69.     def open_light(self, color): 
  70.         if self.connected: 
  71.             self.client.sendall(("open_" + color).encode()) 
  72.             if color == 'red'
  73.                 self.ui.labelRedLight.setPixmap(QtGui.QPixmap("")) 
  74.                 self.ui.labelRedLight.state = "open" 
  75.             elif color == 'yellow'
  76.                 self.ui.labelYellowLight.setPixmap(QtGui.QPixmap("")) 
  77.                 self.ui.labelYellowLight.state = "open" 
  78.             elif color == 'green'
  79.                 self.ui.labelGreenLight.setPixmap(QtGui.QPixmap("")) 
  80.                 self.ui.labelGreenLight.state = "open" 
  81.             return True 
  82.         else
  83.             QMessageBox.warning(self.ui.centralwidget, "警告""請先連接Arduino,再打開燈"
  84.             return False 
  85.     # 關閉LED(color參數用于指定關閉哪一個顏色的信號燈)         
  86.     def close_light(self, color): 
  87.         if self.connected: 
  88.             self.client.sendall(("close_" + color).encode()) 
  89.             if color == 'red'
  90.                 self.ui.labelRedLight.setPixmap(QtGui.QPixmap("close_light.png")) 
  91.                 self.ui.labelRedLight.state = "close" 
  92.             elif color == 'yellow'
  93.                 self.ui.labelYellowLight.setPixmap(QtGui.QPixmap("close_light.png")) 
  94.                 self.ui.labelYellowLight.state = "close" 
  95.             elif color == 'green'
  96.                 self.ui.labelGreenLight.setPixmap(QtGui.QPixmap("close_light.png")) 
  97.                 self.ui.labelGreenLight.state = "close" 
  98.             return True 
  99.         else
  100.             QMessageBox.warning(self.ui.centralwidget, "警告""請先連接Arduino,再關閉燈"
  101.             return False 
  102.     # 點擊紅燈時觸發         
  103.     def red_light_mouse_press_event(self, event): 
  104.         if ui.labelRedLight.state == "open"
  105.             self.close_light("red"
  106.         elif ui.labelRedLight.state == "close"
  107.             self.open_light("red"
  108.     # 點擊黃燈時觸發         
  109.     def yellow_light_mouse_press_event(self, event): 
  110.         if ui.labelYellowLight.state == "open"
  111.             self.close_light("yellow"
  112.         elif ui.labelYellowLight.state == "close"
  113.             self.open_light("yellow"
  114.     # 點擊綠燈時觸發 
  115.     def green_light_mouse_press_event(self, event): 
  116.         if ui.labelGreenLight.state == "open"
  117.             self.close_light("green"
  118.         elif ui.labelGreenLight.state == "close"
  119.             self.open_light("green"
  120.     # 點擊“連接”按鈕時觸發,用于鏈接TCP Server 
  121.     def pushButton_connect_mouse_press_event(self, event): 
  122.         self.client.connect(('192.168.31.164', 4999)) 
  123.         self.connected = True 
  124.         self.ui.pushButtonConnect.setEnabled(False
  125.  
  126.         QMessageBox.information(self.ui.centralwidget, "消息""成功連接Arduino"
  127.     # 點擊“自動”按鈕觸發,用于開啟信號燈自動切換模式 
  128.     def pushButton_auto_mouse_press_event(self, event): 
  129.         self.workThread.running = True 
  130.         self.workThread.start() 
  131.         self.ui.pushButtonAuto.setEnabled(False
  132.         self.ui.pushButtonStop.setEnabled(True
  133.     # 點擊“停止”按鈕觸發,用于關閉信號燈自動切換模式 
  134.     def pushButton_stop_mouse_press_event(self, event): 
  135.         self.workThread.running = False 
  136.         self.ui.pushButtonAuto.setEnabled(True
  137.         self.ui.pushButtonStop.setEnabled(False
  138. # 用于初始化代碼 
  139. if __name__ == '__main__'
  140.     app = QApplication(sys.argv) 
  141.     ui = TrafficLight1.Ui_MainWindow() 
  142.     mainWindow = QMainWindow() 
  143.     ui.setupUi(mainWindow) 
  144.     events = Events(ui) 
  145.     ui.labelRedLight.state = "close" 
  146.     ui.labelYellowLight.state = "close" 
  147.     ui.labelGreenLight.state = "close" 
  148.     ui.labelRedLight.mousePressEvent = events.red_light_mouse_press_event 
  149.     ui.labelYellowLight.mousePressEvent = events.yellow_light_mouse_press_event 
  150.     ui.labelGreenLight.mousePressEvent = events.green_light_mouse_press_event 
  151.     ui.pushButtonConnect.mousePressEvent = events.pushButton_connect_mouse_press_event 
  152.     ui.pushButtonAuto.mousePressEvent = events.pushButton_auto_mouse_press_event 
  153.     ui.pushButtonStop.mousePressEvent = events.pushButton_stop_mouse_press_event 
  154.     ui.pushButtonStop.setEnabled(False
  155.     # 將所有組件的文本尺寸都設置為30px 
  156.     mainWindow.setStyleSheet("QWidget{font-size:30px}"); 
  157.     mainWindow.show() 
  158.     app.exec() 

現在整個系統都完事了,好好地享受我們的成果吧!
wifi_led演示(長).mp4.zip

源代碼.txt.zip

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2017-04-12 13:31:58

智能紅綠燈邁阿密交通

2021-06-01 09:39:58

智能交通物聯網IOT

2025-04-03 07:08:05

2020-06-10 07:59:44

漏洞攻擊黑客

2020-07-08 15:15:03

AndoridGoogle交通信號燈

2020-12-24 10:09:19

人工智能AI智能交通

2021-10-09 13:55:24

谷歌交通信號燈人工智能

2021-04-09 10:50:22

人工智能AI智能交通

2014-06-10 10:47:37

2023-06-29 14:43:32

2017-09-11 20:15:28

智慧交通視頻監控云平臺

2021-08-04 09:48:05

數字化

2024-03-18 09:54:32

開源AI模型

2023-09-18 14:41:56

2023-09-11 12:36:56

研究數據

2009-01-18 09:31:00

網絡故障網卡信號燈

2023-08-15 14:31:46

2015-02-06 09:23:52

賽可達實驗室網絡安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产毛片久久久久久久久春天 | 亚洲精品视频一区 | 色呦呦网站 | 欧美亚洲国产一区二区三区 | 夜夜骑天天干 | 黄色一级大片在线免费看产 | 人人草天天草 | 日韩av一区二区在线观看 | 放个毛片看看 | 久久大| www国产成人免费观看视频 | 午夜av成人 | 一级毛片视频 | 日韩一区二区在线视频 | 国产在线一区二区三区 | 祝你幸福电影在线观看 | 国产激情91久久精品导航 | 天堂在线免费视频 | 久久无毛 | 亚洲一区二区高清 | 日韩精品四区 | 91精品国产91久久久久久吃药 | 亚洲精品一区二区三区 | 日韩欧美精品在线 | 成人性视频免费网站 | 色综合久久久 | 日韩精品一区二区三区四区视频 | 亚洲欧美日韩高清 | 国产亚洲一区在线 | 一区二区中文字幕 | 一级毛片免费视频观看 | 米奇7777狠狠狠狠视频 | 欧美极品一区二区 | 麻豆av在线免费观看 | 中文字幕在线观看一区 | 国产露脸国语对白在线 | avmans最新导航地址 | 男人天堂99| 亚洲男女视频在线观看 | 精品国产乱码久久久久久丨区2区 | 久久精品99国产精品日本 |