前言
智能小車,自娛自樂,希望通過該分享幫助更多愛好者們化繁為簡,待我完成到第三季,我將會把程序放出來拱大家使用,我準備分三季來實現,APP后臺部署在阿里小程序云,通過阿里云MQTT消息隊列服務,來完成指令控制,并實現事件日志機制。
第一季實現小車的控制目標
1、實現小車4驅控制
2、實現攝像頭實時查看,借助反向代理來完成內外網的通信
3、實現指令通過阿里云微消息隊列MQTT來交互
4、設計APP端的控制界面實現
第二季實現目標
1、實現攝頭云端控制
2、人臉檢測
3、打包容器
4、熱體紅外+超聲波測距+濕度溫度
第三季實現目標
思考中。。
第一季開發(fā)準備
硬件
開發(fā)準備
硬件
軟件
硬件連接
整體效果
環(huán)境部署
阿里云應用
云應用是面向小程序應用場景,為開發(fā)者提供的一鍵構建后端應用運行環(huán)境、后端服務部署、運維監(jiān)控等能力的一站式小程序部署服務。
我們需要申請一個云應用充當小程序的服務器以及fpc服務器。現在阿里推出繁星計劃,可以免費申請2個月的測試環(huán)境以及一個月的生產環(huán)境,無需申請,直接在應用界面新建新運用,創(chuàng)建詳情請參考文檔
在控制臺獲取服務器ip、用戶名(默認root)、密碼(需要修改默認密碼,然后重啟服務器),通過SSH工具連接,用于部署下面步驟
MJPG-Streamer
MJPG-Streamer是一個命令行應用程序,它將JPEG幀從一個或多個輸入插件復制到多個輸出插件。它可用于通過基于IP的網絡將JPEG文件從網絡攝像頭流式傳輸到各種類型的查看器,如Chrome,Firefox,Cambozola,VLC,mplayer和其他能夠接收MJPG流的軟件。
sudo raspi-config
sudo apt-get update sudo apt-get install subversion sudo apt-get install libjpeg8-dev sudo apt-get install imagemagick sudo apt-get install libv4l-dev sudo apt-get install cmake sudo apt-get install git
sudo git clone https://github.com/jacksonliam/mjpg-streamer.git cd mjpg-streamer/mjpg-streamer-experimental make all sudo make install
sudo wget http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc && sudo apt-key add ./lrkey.asc
修改sources.list,在末尾添加源,并安裝uv4l uv4l-raspicam,然后重啟
sudo nano /etc/apt/sources.list #末尾添加,保存 deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ wheezy main sudo apt-get update sudo apt-get install uv4l uv4l-raspicam sudo reboot
重啟之后:
sudo pkill uv4l sudo apt-get update sudo apt-get install uv4l-uvc sudo apt-get install uv4l-xscreen sudo apt-get install uv4l-mjpegstream sudo reboot
再一次重啟之后開啟視頻流服務
sudo modprobe bcm2835-v4l2 ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -n -y -f 25 -r 640x480" -o "./output_http.so -n -w /usr/local/www"
然后打開瀏覽器輸入:http://raspberry-ip-address:8080/?action=stream
應該就可以看到Raspberry Pi Camera采集的動態(tài)視頻了,延遲大概不超過0.8秒吧。
frp
frp是一個快速反向代理,可幫助您將NAT或防火墻后面的本地服務器暴露給Internet。截至目前,它支持tcp&udp以及http和https協(xié)議,其中請求可以通過域名轉發(fā)到內部服務。
wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-install-shell/master/frps/install-frps.sh -O ./install-frps.sh chmod 700 ./install-frps.sh ./install-frps.sh install
然后一直回車(默認配置),知道全部安裝完成。安裝成功截圖
frps start
查看frps版本號
frps -v
我這邊安裝的是version 0.20.0,客戶端也要安裝對應版本的
wget https://github.com/fatedier/frp/releases/download/v0.20.0/frp_0.20.0_linux_arm.tar.gz tar zxvf frp_0.20.1_linux_arm.tar.gz cd frp_0.14.1_linux_arm vi frpc.ini
修改 frpc.ini 文件
# frpc.ini [common] #服務器IP server_addr = x.x.x.x #服務器fpcs服務對應端口Bind port server_port = 5443 #服務端token oken = 你的服務端token [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000 #[]內名稱不能重復,標簽作用 [web_raspberry_web] type = http #端口號 對應本機視頻web服務器的端口 local_port = 8080 #配置穿透外網訪問域名,可設置多個 custom_domains = raspberry.你的域名.com
修改好frpc.ini后,啟動frpc客戶端。如果想在后臺運行,可在命令后加 &
./frpc -c frpc.ini
申請域名解析
將你的的域名主機記錄 raspberry A 記錄解析到你的服務器IP x.x.x.x
服務器部署 Nginx
Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。
Ubuntu16.04安裝及配置nginx
apt-get install build-essential apt-get install libtool
sudo apt-get update sudo apt-get install libpcre3 libpcre3-dev
apt-get install zlib1g-dev
4.安裝ssl依賴庫
apt-get install openssl
安裝nginx
#下載最新版本: wget http://nginx.org/download/nginx-1.16.0.tar.gz #解壓: tar -zxvf nginx-1.11.3.tar.gz #進入解壓目錄: cd nginx-1.11.3 #配置: ./configure --prefix=/usr/local/nginx #編輯nginx: make 注意:這里可能會報錯,提示“pcre.h No such file or directory”,具體詳見:http://stackoverflow.com/questions/22555561/error-building-fatal-error-pcre-h-no-such-file-or-directory 需要安裝 libpcre3-dev,命令為:sudo apt-get install libpcre3-dev #安裝nginx: sudo make install #啟動nginx: sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 注意:-c 指定配置文件的路徑,不加的話,nginx會自動加載默認路徑的配置文件,可以通過 -h查看幫助命令。 #查看nginx進程: ps -ef|grep nginx
在瀏覽器輸入 http://raspberry.你的域名.com:8080
出現頁面則nginx部署成功
配置測試頁面
新建一個index.html文件,用于測試頁面,內容如下
<html> <head> <meta name="generator" content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" /> <meta http-equiv="Content-Type" content="text/html;" charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" /> <meta http-equiv="refresh" content="3" /> <title>樹莓派實時監(jiān)控站</title> </head> <body> <center> <font size="20" face="微軟雅黑" color="#0074CD"> <b>樹莓派<br> 實時監(jiān)控站</b> </font> <hr /> frameLabelStart--frameLabelEnd <!--修改此處--> <br /> <p> <font size="5" color="#269C5D"> <b>Design by James</b> </font> </p> <p> <font size="5" color="#269C5D"> <i>a Web Monitoring Based on Raspberry Pi</i> </font> </p> </center> </body> </html>
將該文件替換在nginx配置的web路徑的index.html文件,例如/var/www/index.html
在瀏覽器輸入 http://raspberry.你的域名.com:8080
嘗試一下能否訪問,如果成功出現樹莓派實時監(jiān)控頁面,則web頁面部署成功
阿里云微消息隊列MQTT
微消息隊列 MQTT 是阿里云推出的一款面向移動互聯(lián)網以及物聯(lián)網領域的輕量級消息中間件,針對移動互聯(lián)網以及物聯(lián)網 IoT 場景的消息傳輸特點,支持了包括 MQTT、STOMP、GB-808、新能源國標等主流通信協(xié)議
海創(chuàng)物聯(lián)開發(fā)平臺部署
海創(chuàng)開發(fā)平臺是海創(chuàng)科技有限公司開發(fā)的一款快速編程平臺,該平臺開發(fā)的組件能快速與PLC、GPIO、各式設備進行通訊,有豐富的API支持,基本你們想到的事情它都能干,非常適合做物聯(lián)網的網關控制中心
復制以下代碼,打開開發(fā)平臺,點擊右上角菜單,選擇導入-剪切板,然后粘貼保存,即可看到工作區(qū)新增了一個新的流程,該流程用于接受MQTT命令控制小車
[{"id":"9e9c968e.24e348","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"29","set":true,"level":"0","freq":"","out":"out","x":720,"y":140,"wires":[]},{"id":"37f46ac8.666436","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"31","set":true,"level":"0","freq":"","out":"out","x":720,"y":180,"wires":[]},{"id":"5f130d8f.f55d84","type":"function","z":"d99269c6.a2d0b8","name":"控制","func":"switch(msg.payload)\n{\n case '0':return [{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0}];\n case '1':return [{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1}];\n case '2':return [{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0}];\n case '4':return [{payload:0},{payload:0},{payload:0},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0}];\n case '3':return [{payload:1},{payload:0},{payload:1},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0}];\n}\n","outputs":8,"noerr":0,"x":510,"y":320,"wires":[["9e9c968e.24e348","676a7be6.b97e14"],["37f46ac8.666436","676a7be6.b97e14"],["2e8cc1ec.6369ce","676a7be6.b97e14"],["c7700a0b.47b378","676a7be6.b97e14"],["676a7be6.b97e14","482e8885.76d548"],["676a7be6.b97e14","62b4d0fc.a93f3"],["676a7be6.b97e14","fd3c406.31fc4c"],["676a7be6.b97e14","6ac88490.ba21bc"]]},{"id":"2e8cc1ec.6369ce","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"32","set":true,"level":"0","freq":"","out":"out","x":720,"y":240,"wires":[]},{"id":"c7700a0b.47b378","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"33","set":true,"level":"0","freq":"","out":"out","x":720,"y":280,"wires":[]},{"id":"8e757771.a599e8","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"停止","payload":"0","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":260,"wires":[["5f130d8f.f55d84"]]},{"id":"89e33a84.467878","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"前進","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":320,"wires":[["5f130d8f.f55d84"]]},{"id":"e521ba16.452cc8","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"后退","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":380,"wires":[["5f130d8f.f55d84"]]},{"id":"676a7be6.b97e14","type":"debug","z":"d99269c6.a2d0b8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":580,"wires":[]},{"id":"482e8885.76d548","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"35","set":true,"level":"0","freq":"","out":"out","x":720,"y":340,"wires":[]},{"id":"62b4d0fc.a93f3","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"36","set":true,"level":"0","freq":"","out":"out","x":720,"y":380,"wires":[]},{"id":"fd3c406.31fc4c","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"37","set":true,"level":"0","freq":"","out":"out","x":720,"y":440,"wires":[]},{"id":"6ac88490.ba21bc","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"38","set":true,"level":"0","freq":"","out":"out","x":720,"y":480,"wires":[]},{"id":"6473261a.673168","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"左轉","payload":"3","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":440,"wires":[["5f130d8f.f55d84"]]},{"id":"73eb851c.b88ddc","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"右轉","payload":"4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":480,"wires":[["5f130d8f.f55d84"]]},{"id":"bf85c267.64f96","type":"mqtt in","z":"d99269c6.a2d0b8","name":"","topic":"","qos":"2","broker":"bf40108b.620c2","x":235,"y":160,"wires":[["5f130d8f.f55d84","8a1c007d.34912"]]},{"id":"8a1c007d.34912","type":"debug","z":"d99269c6.a2d0b8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":435,"y":180,"wires":[]},{"id":"c1f327d8.b01818","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":40,"wires":[["c4d9812a.7b54b"]]},{"id":"c4d9812a.7b54b","type":"mqtt out","z":"d99269c6.a2d0b8","name":"","topic":"","qos":"","retain":"","x":415,"y":40,"wires":[]},{"id":"bf40108b.620c2","type":"mqtt-broker","z":"","name":"","broker":"","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
導入后效果如下
雙擊mqtt out節(jié)點,在屬性窗點擊服務器右側的那個小標簽按鈕進入mqtt服務配置。填好服務器(阿里mqtt實例的外網http接入點)、端口號(默認1883)、客戶端id("Group ID@@@任意id" 客戶端ID在每個實例每個主題中只能唯一,重復情況下后面連接的自動被阿里斷開)、用戶名(這邊我們使用的是簽名鑒權模式,Token鑒權模式參考文檔"Signature|Access Key|實例 ID")、密碼(參考阿里的簽名機制,快捷生成簽名請點擊簽名校驗),點擊保存返回mqtt屬性配置頁,填寫主題(阿里的Topic ID),QOS選擇1(至少上傳一次)。mqtt in節(jié)點類似,由于接受消息是用于控制小車,所以QOS選擇2(僅分發(fā)一次),以下是配置詳情
PIN控制著電機驅動模塊從而控制小車的動作,前進(四個輪子前進)、后退(四個輪子后退)、左轉(右側輪子轉)、右轉(左側輪子轉)。假設相鄰的兩個OUT口連接一個電機,那么驅動模塊的控制邏輯為
IN1IN2~數字信號10電機前進數字信號01電機后退數字信號00電機停止數字信號11電機停止
根據該邏輯配置function節(jié)點(示例已包含,請根據自己的接法設置GPIO口的信號輸出)
單擊定時器后mqtt out節(jié)點會將測試使用的時間戳上傳到阿里的mqtt服務器,然后mqtt in會訂閱接受到該消息,并在右側調試窗口輸出。正式使用數據請輸入0、1、2、3
使用mqtt發(fā)送正式消息,操作結果
作者:fengsl
更換封面
00:15 視頻尚未發(fā)布,暫時無法播放
前言
智能小車,自娛自樂,希望通過該分享幫助更多愛好者們化繁為簡,待我完成到第三季,我將會把程序放出來拱大家使用,我準備分三季來實現,APP后臺部署在阿里小程序云,通過阿里云MQTT消息隊列服務,來完成指令控制,并實現事件日志機制。
第一季實現小車的控制目標
1、實現小車4驅控制
2、實現攝像頭實時查看,借助反向代理來完成內外網的通信
3、實現指令通過阿里云微消息隊列MQTT來交互
4、設計APP端的控制界面實現
第二季實現目標
1、實現攝頭云端控制
2、人臉檢測
3、打包容器
4、熱體紅外+超聲波測距+濕度溫度
第三季實現目標
思考中。。
第一季開發(fā)準備
硬件
軟件
硬件連接
整體效果
環(huán)境部署
阿里云應用
云應用是面向小程序應用場景,為開發(fā)者提供的一鍵構建后端應用運行環(huán)境、后端服務部署、運維監(jiān)控等能力的一站式小程序部署服務。
我們需要申請一個云應用充當小程序的服務器以及fpc服務器。現在阿里推出繁星計劃,可以免費申請2個月的測試環(huán)境以及一個月的生產環(huán)境,無需申請,直接在應用界面新建新運用,創(chuàng)建詳情請參考文檔
在控制臺獲取服務器ip、用戶名(默認root)、密碼(需要修改默認密碼,然后重啟服務器),通過SSH工具連接,用于部署下面步驟
MJPG-Streamer
MJPG-Streamer是一個命令行應用程序,它將JPEG幀從一個或多個輸入插件復制到多個輸出插件。它可用于通過基于IP的網絡將JPEG文件從網絡攝像頭流式傳輸到各種類型的查看器,如Chrome,Firefox,Cambozola,VLC,mplayer和其他能夠接收MJPG流的軟件。
sudo raspi-config
sudo apt-get update
sudo apt-get install subversion
sudo apt-get install libjpeg8-dev
sudo apt-get install imagemagick
sudo apt-get install libv4l-dev
sudo apt-get install cmake
sudo apt-get install git
sudo git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
make all
sudo make install
sudo wget http://www.linux-projects.org/listing/uv4l_repo/lrkey.asc && sudo apt-key add ./lrkey.asc
修改sources.list,在末尾添加源,并安裝uv4l uv4l-raspicam,然后重啟
sudo nano /etc/apt/sources.list
#末尾添加,保存
deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/ wheezy main
sudo apt-get update
sudo apt-get install uv4l uv4l-raspicam
sudo reboot
重啟之后:
sudo pkill uv4l sudo apt-get update sudo apt-get install uv4l-uvc sudo apt-get install uv4l-xscreen sudo apt-get install uv4l-mjpegstream sudo reboot
再一次重啟之后開啟視頻流服務
sudo modprobe bcm2835-v4l2 ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -n -y -f 25 -r 640x480" -o "./output_http.so -n -w /usr/local/www"
然后打開瀏覽器輸入:http://raspberry-ip-address:8080/?action=stream
應該就可以看到Raspberry Pi Camera采集的動態(tài)視頻了,延遲大概不超過0.8秒吧。
frp
frp是一個快速反向代理,可幫助您將NAT或防火墻后面的本地服務器暴露給Internet。截至目前,它支持tcp&udp以及http和https協(xié)議,其中請求可以通過域名轉發(fā)到內部服務。
wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-install-shell/master/frps/install-frps.sh -O ./install-frps.sh
chmod 700
./install-frps.sh
./install-frps.sh install
然后一直回車(默認配置),知道全部安裝完成。安裝成功截圖
frps start
查看frps版本號
frps -v
我這邊安裝的是version 0.20.0,客戶端也要安裝對應版本的
3. 樹莓派部署frpc
由于我們服務器部署frps的版本是version 0.20.0,所以我們本地也要部署相同的版本
wget https://github.com/fatedier/frp/releases/download/v0.20.0/frp_0.20.0_linux_arm.tar.gz tar zxvf frp_0.20.1_linux_arm.tar.gz cd frp_0.14.1_linux_arm vi frpc.ini
修改 frpc.ini 文件
# frpc.ini [common] #服務器IP server_addr = x.x.x.x #服務器fpcs服務對應端口Bind port server_port = 5443 #服務端token oken = 你的服務端token [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000 #[]內名稱不能重復,標簽作用 [web_raspberry_web] type = http #端口號 對應本機視頻web服務器的端口 local_port = 8080 #配置穿透外網訪問域名,可設置多個 custom_domains = raspberry.你的域名.com
修改好frpc.ini后,啟動frpc客戶端。如果想在后臺運行,可在命令后加 &
./frpc -c frpc.ini
申請域名解析
將你的的域名主機記錄 raspberry A 記錄解析到你的服務器IP x.x.x.x
服務器部署 Nginx
Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。
Ubuntu16.04安裝及配置nginx
apt-get install build-essential
apt-get install libtool
sudo apt-get update sudo apt-get install libpcre3 libpcre3-dev
apt-get install zlib1g-dev
4.安裝ssl依賴庫
apt-get install openssl
安裝nginx
#下載最新版本: wget http://nginx.org/download/nginx-1.16.0.tar.gz #解壓: tar -zxvf nginx-1.11.3.tar.gz #進入解壓目錄: cd nginx-1.11.3 #配置: ./configure --prefix=/usr/local/nginx #編輯nginx: make 注意:這里可能會報錯,提示“pcre.h No such file or directory”,具體詳見:http://stackoverflow.com/questions/22555561/error-building-fatal-error-pcre-h-no-such-file-or-directory 需要安裝 libpcre3-dev,命令為:sudo apt-get install libpcre3-dev #安裝nginx: sudo make install #啟動nginx: sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 注意:-c 指定配置文件的路徑,不加的話,nginx會自動加載默認路徑的配置文件,可以通過 -h查看幫助命令。 #查看nginx進程: ps -ef|grep nginx
在瀏覽器輸入 http://raspberry.你的域名.com:8080
出現頁面則nginx部署成功
配置測試頁面
新建一個index.html文件,用于測試頁面,內容如下
<html>
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<meta http-equiv="Content-Type" content="text/html;" charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<meta http-equiv="refresh" content="3" />
<title>樹莓派實時監(jiān)控站</title>
</head>
<body>
<center>
<font size="20" face="微軟雅黑" color="#0074CD">
<b>樹莓派<br>
實時監(jiān)控站</b>
</font>
<hr />
<iframe src="http://raspberry.gkiiot.com:8080/?action=stream" scrolling=no width="320" height="240"> </iframe> <!--修改此處-->
<br />
<p>
<font size="5" color="#269C5D">
<b>Design by James</b>
</font>
</p>
<p>
<font size="5" color="#269C5D">
<i>a Web Monitoring Based on Raspberry Pi</i>
</font>
</p>
</center>
</body>
</html>
將該文件替換在nginx配置的web路徑的index.html文件,例如/var/www/index.html
在瀏覽器輸入 http://raspberry.你的域名.com:8080
嘗試一下能否訪問,如果成功出現樹莓派實時監(jiān)控頁面,則web頁面部署成功
阿里云微消息隊列MQTT
微消息隊列 MQTT 是阿里云推出的一款面向移動互聯(lián)網以及物聯(lián)網領域的輕量級消息中間件,針對移動互聯(lián)網以及物聯(lián)網 IoT 場景的消息傳輸特點,支持了包括 MQTT、STOMP、GB-808、新能源國標等主流通信協(xié)議
海創(chuàng)物聯(lián)開發(fā)平臺部署
海創(chuàng)開發(fā)平臺是海創(chuàng)科技有限公司開發(fā)的一款快速編程平臺,該平臺開發(fā)的組件能快速與PLC、GPIO、各式設備進行通訊,有豐富的API支持,基本你們想到的事情它都能干,非常適合做物聯(lián)網的網關控制中心
[{"id":"9e9c968e.24e348","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"29","set":true,"level":"0","freq":"","out":"out","x":720,"y":140,"wires":[]},{"id":"37f46ac8.666436","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"31","set":true,"level":"0","freq":"","out":"out","x":720,"y":180,"wires":[]},{"id":"5f130d8f.f55d84","type":"function","z":"d99269c6.a2d0b8","name":"控制","func":"switch(msg.payload)\n{\n case '0':return [{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0}];\n case '1':return [{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1}];\n case '2':return [{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0}];\n case '4':return [{payload:0},{payload:0},{payload:0},{payload:0},{payload:1},{payload:0},{payload:1},{payload:0}];\n case '3':return [{payload:1},{payload:0},{payload:1},{payload:0},{payload:0},{payload:0},{payload:0},{payload:0}];\n}\n","outputs":8,"noerr":0,"x":510,"y":320,"wires":[["9e9c968e.24e348","676a7be6.b97e14"],["37f46ac8.666436","676a7be6.b97e14"],["2e8cc1ec.6369ce","676a7be6.b97e14"],["c7700a0b.47b378","676a7be6.b97e14"],["676a7be6.b97e14","482e8885.76d548"],["676a7be6.b97e14","62b4d0fc.a93f3"],["676a7be6.b97e14","fd3c406.31fc4c"],["676a7be6.b97e14","6ac88490.ba21bc"]]},{"id":"2e8cc1ec.6369ce","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"32","set":true,"level":"0","freq":"","out":"out","x":720,"y":240,"wires":[]},{"id":"c7700a0b.47b378","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"33","set":true,"level":"0","freq":"","out":"out","x":720,"y":280,"wires":[]},{"id":"8e757771.a599e8","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"停止","payload":"0","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":260,"wires":[["5f130d8f.f55d84"]]},{"id":"89e33a84.467878","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"前進","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":320,"wires":[["5f130d8f.f55d84"]]},{"id":"e521ba16.452cc8","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"后退","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":380,"wires":[["5f130d8f.f55d84"]]},{"id":"676a7be6.b97e14","type":"debug","z":"d99269c6.a2d0b8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":580,"wires":[]},{"id":"482e8885.76d548","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"35","set":true,"level":"0","freq":"","out":"out","x":720,"y":340,"wires":[]},{"id":"62b4d0fc.a93f3","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"36","set":true,"level":"0","freq":"","out":"out","x":720,"y":380,"wires":[]},{"id":"fd3c406.31fc4c","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"37","set":true,"level":"0","freq":"","out":"out","x":720,"y":440,"wires":[]},{"id":"6ac88490.ba21bc","type":"rpi-gpio out","z":"d99269c6.a2d0b8","name":"","pin":"38","set":true,"level":"0","freq":"","out":"out","x":720,"y":480,"wires":[]},{"id":"6473261a.673168","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"左轉","payload":"3","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":440,"wires":[["5f130d8f.f55d84"]]},{"id":"73eb851c.b88ddc","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"右轉","payload":"4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":480,"wires":[["5f130d8f.f55d84"]]},{"id":"bf85c267.64f96","type":"mqtt in","z":"d99269c6.a2d0b8","name":"","topic":"","qos":"2","broker":"bf40108b.620c2","x":235,"y":160,"wires":[["5f130d8f.f55d84","8a1c007d.34912"]]},{"id":"8a1c007d.34912","type":"debug","z":"d99269c6.a2d0b8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":435,"y":180,"wires":[]},{"id":"c1f327d8.b01818","type":"inject","z":"d99269c6.a2d0b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":40,"wires":[["c4d9812a.7b54b"]]},{"id":"c4d9812a.7b54b","type":"mqtt out","z":"d99269c6.a2d0b8","name":"","topic":"","qos":"","retain":"","x":415,"y":40,"wires":[]},{"id":"bf40108b.620c2","type":"mqtt-broker","z":"","name":"","broker":"","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
導入后效果如下
2. 修改節(jié)點屬性
導入的流程不能直接使用,需要修改一些節(jié)點屬性配置。
雙擊mqtt out節(jié)點,在屬性窗點擊服務器右側的那個小標簽按鈕進入mqtt服務配置。填好服務器(阿里mqtt實例的外網http接入點)、端口號(默認1883)、客戶端id("Group ID@@@任意id" 客戶端ID在每個實例每個主題中只能唯一,重復情況下后面連接的自動被阿里斷開)、用戶名(這邊我們使用的是簽名鑒權模式,Token鑒權模式參考文檔"Signature|Access Key|實例 ID")、密碼(參考阿里的簽名機制,快捷生成簽名請點擊簽名校驗),點擊保存返回mqtt屬性配置頁,填寫主題(阿里的Topic ID),QOS選擇1(至少上傳一次)。mqtt in節(jié)點類似,由于接受消息是用于控制小車,所以QOS選擇2(僅分發(fā)一次),以下是配置詳情
PIN控制著電機驅動模塊從而控制小車的動作,前進(四個輪子前進)、后退(四個輪子后退)、左轉(右側輪子轉)、右轉(左側輪子轉)。假設相鄰的兩個OUT口連接一個電機,那么驅動模塊的控制邏輯為
IN1IN2~數字信號10電機前進數字信號01電機后退數字信號00電機停止數字信號11電機停止
根據該邏輯配置function節(jié)點(示例已包含,請根據自己的接法設置GPIO口的信號輸出)
ublime Text 3是一個輕量級的跨平臺文字編輯器,一經面世便被認為是一個杰出的編輯器,而它真正的強大之處在于你可以使用 Package Control 來增加它的功能以及可以進行各種自定義設置。 本文譯自realpython.com的一篇教程,可以讓你快速地將ST3改造成Python開發(fā)環(huán)境。——EarlGrey@編程派
在本文章中,我們將會看到如何將 Sublime Text 打造成為 Python 的全棧開發(fā)環(huán)境(從前端到后端),如何通過自定義主題和插件來增強它的基本功能,并且還將會涉及到很多使 ST3 變得更加強大的常用的命令,特性以及快捷鍵。
本教程將假定你使用的是 Mac 電腦并且習慣于使用終端。如果你使用的是 Windows 或者 Linux 操作系統(tǒng),本文涉及到的一些命令將有可能會有所不同,但是你應該仍然可以很容易地通過 Google 來獲取到與本教程相關的解答。
讓我們從 ST3 的一些默認特性開始著手吧…
Split Layouts
允許你將你的許多文件放到很多分割開來的視窗中。如果你正在進行以測試為目的的開發(fā)(將 Python 代碼放在一個視窗中,而測試腳本放在另一個視窗中)或者正在進行前端開發(fā)(將 HTML 代碼放在一個視窗里,CSS/Javascript 代碼放在另一個視窗里)的時候將會非常有用。
Vintage Mode
讓你能夠在 ST3 中使用 vi 模式。
Chrome-like Tabs
讓你在多個文件中切換變得更加方便。
Automatic loading of the last session
幫你自動打開你上次關閉的時候編輯器中所有打開的文件。我總是一直開著 ST3,而且其中打開著一大堆項目——當我重啟電腦以后, 它能夠自動幫我打開所有的這些文件和文件夾。
Code Snippets
允許你通過一兩個簡單的關鍵字就能寫出一段常用的代碼片(Snippets),從而增加你的生產效率。比如,你只需要打開一個文件,輸入 “l(fā)orem” 然后敲擊 tab 鍵,就會自動生成一段亂數假文(譯者注: 一種用于測試文章或文字在不同字型、版型下看起來的效果等的文字)。又比如在 Python 代碼中,你可以輸入 “defs” 然后敲擊 tab 鍵,你就能得到一段通用的函數定義。
同時,你還可以點擊 Tools > New Snippet 來創(chuàng)建屬于你自己的代碼片。請參照這個 文檔來獲取幫助,也可以在 這里 查看我個人用到的一些 snippets。
在你下載完 ST3 以后…
在命令行中添加 subl 命令
就像 TextMate 的 mate 命令一樣,Sublime Text 擁有一個叫做 subl 的命令行工具,可以用來通過終端打開一個文件或者一整個文件夾。
你需要建立一個指向 subl 二進制文件的符號鏈接來使 subl 命令有效:
$ sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/bin/subl
嘗試使用以下命令來打開 Sublime 來確保鏈接生效了:
$ subl
如果以上命令沒有效果,你可能需要將 /bin 添加到你的環(huán)境變量中:
$ echo "export PATH=~/bin:$PATH" >> ~/.profile
然后重新嘗試第一步。
現在你就可以通過下述命令來打開文件或者文件夾了:
# open the current directory
$ subl .# open a directory called tests
$ subl ~/Documents/test# open a file called text.txt
$ subl test.txt
如果路徑中含有空格,你必須使用雙引號將路徑括起來:
$ subl "~/Documents/test/my test file.txt"
想要查詢所有可用的命令,請打開幫助文件:
$ subl --help
安裝 Package Control
為了使用眾多的插件來擴展 Sublime 的功能,你需要安裝一個叫做 Package Control 的插件管理器——這個東西你必須要手動安裝。但是一旦你安裝好了以后,你就可以使用 Package Control 來安裝,移除或者升級所有的 ST3 插件了。
從 Sublime Text 3 官方獲取用于安裝的代碼。依次點擊 View > Show Console 打開 ST3 的控制臺。在控制臺中粘貼剛才的代碼,然后點擊回車。最后重啟 ST3。
現在你可以通過快捷鍵 cmd+shift+P 打開 Package Control 來安裝其他的插件了。輸入 install 然后你就能看見屏幕上出現了 Package Control: Install Package,點擊回車然后搜索你想要的插件。
其他一些相關命令如下:
List Packages 顯示所有已安裝的插件
Remove Packages 移除一個指定的插件
Upgrade Package 更新一個指定的插件
Upgrade/Overwrite All Packages 更新所有已安裝的插件
創(chuàng)建自定義配置文件
你可以通過一個基于 JSON 的配置文件來充分的自定義 Sublime Text,這使得轉移或者同步你的自定義文件到另一個系統(tǒng)變得非常容易。首先,我們需要新建我們自己的配置文件。我們最好是為不同的系統(tǒng)環(huán)境和編程語言各自創(chuàng)建一個配置文件。
依次點擊 Sublime Text > Preferences > Settings – User 來創(chuàng)建一個配置文件。在該文件中添加一個空的 JSON 類然后就可以在其中寫入你的配置內容了。如下所示:
{ // base settings
"auto_complete": false,
"sublimelinter": false,
"tab_size": 2,
"word_wrap": true
}
如果想為特定的編程語言新建配置文件的話,請點擊 Sublime Text > Preferences > Settings – More > Syntax Specific – User。然后按照 LANGUAGE.sublime-settings 的格式保存該配置文件。例如想新建一個 Python 專用的配置文件,請將該文件保存為 Python.sublime-settings。
你完全可以按照你自己的喜好來進行各項配置;不過我強烈推薦以我的這份 配置文件 以及 Python 配置 作為基礎,然后修改成你所需要的內容。
一個可選項: 你可以使用 Dropbox 來同步你的所有配置。你只需要將你的配置文件上傳到 Dropbox 然后就可以將你的配置同步到你的任意一臺設備上了。
你可以在 Sublime Text Unofficial Documentation 找到一些非常好的參考配置。
ST3 為你提供了完全自定義化一個適合自己主題的能力。當然,你如果不是那么的挑剔的話,你可以通過 Package Control 從許許多多的由 Sublime 社區(qū)設計的 主題 中下載一個。 在下載之前你可以通過 ColorSublime 來預覽這些主題。
廣受歡迎的的 Soda Dark 和極簡風格的 Flatland 是我個人最喜歡的兩個主題。
在安裝完了主題以后, 請務必更新你的配置文件. Sublime Text > Preferences > Settings – User:
{
"theme": "Flatland Dark.sublime-theme",
"color_scheme": "Packages/Theme - Flatland/Flatland Dark.tmTheme"
}
除了那些主題以外,我還會使用以下這一些插件來提升我的工作效率。
SideBarEnhancements
SideBarEnhancements 擴展了側邊欄中菜單選項的數量,從而提升你的工作效率。諸如”New file” 和 “Duplicate” 這樣的選項對于 ST3 來說實在是太重要了, 我甚至覺得 ST3 本來就應該提供這些功能。而且僅憑 “Delete” 這一個功能就讓這個插件值得下載。這個功能將你會在你刪除文件的時候把它放入回收站。雖然這個功能乍一看沒什么用,但是當你沒有使用這樣的功能而徹底刪除了一個文件的時候,除非你用了版本管理軟件,否則你將很難恢復這個文件。
現在就下載吧!
Anaconda
Anaconda 是一個終極 Python 插件。它為 ST3 增添了多項 IDE 類似的功能,例如:
Autocompletion
自動完成,該選項默認開啟,同時提供多種配置選項。
Code linting
使用支持 pep8 標準的 PyLint 或者 PyFlakes。因為我個人使用的是另外的 linting 工具,所以我會在 Anaconda 的配置文件 Anaconda.sublime-settings中將 linting 完全禁用。操作如下: Sublime > Preferences > Package Settings > Anaconda > Settings – User: {"anaconda_linting": false}
McCabe code complexity checker
讓你可以在特定的文件中使用 McCabe complexity checker. 如果你對軟件復雜度檢查工具不太熟悉的話,請務必先瀏覽上邊的鏈接。
Goto Definitions
能夠在你的整個工程中查找并且顯示任意一個變量,函數,或者類的定義。
Find Usage
能夠快速的查找某個變量,函數或者類在某個特定文件中的什么地方被使用了。
Show Documentation
能夠顯示一個函數或者類的說明性字符串(當然,是在定義了字符串的情況下)
你可以通過 ST3 的 Package Settings: Sublime Text > Preferences > Package Settings > Anaconda > README 來查看所有這些特性。
SublimeCodeIntel 是另外一個非常流行的插件,它的許多特性與 Anaconda 類似。我建議同時也試試它。
Djaneiro
Djaneiro 支持 Django 模版和關鍵字高亮以及許多實用的代碼片(snippets)功能。其中的 snippets 絕對是省時神器。你可以通過很少幾個關鍵字就能創(chuàng)建許多常見的 Django 代碼塊比如 templates,models,forms,以及 views。請查看官方文檔獲取 snippets 列表。
我個人非常喜歡的以下兩個用于創(chuàng)建 template 的代碼片:輸入 var 就可以新建 {{ }},而輸入 tag 就能新建 {% %}。
requirementstxt
Requirementstxt 可以為你的 requirements.txt 文件提供自動補全,語法高亮以及版本管理功能。
SublimeLinter
SublimeLinter 是 ST3 的一個代碼靜態(tài)檢查工具框架(linter)。這個插件本身來說并不包含任何的一個 linter,但是你可以通過在 Package Control 中輸入 SublimeLinter-[linter_name] 的方式來安裝一個 linter。你可以點擊這里查看官方的 linter。同時你還可以在 Package Control 中查看到許多的第三方 linter。請點擊這里查看安裝說明。
對于 Python 的代碼靜態(tài)檢查器,我建議使用 SublimeLinter-pyflakes 和 SublimeLinter-pep8。
與此同時,我也會使用 SublimeLinter-jshint, SublimeLinter-pyyaml, SublimeLinter-csslint,SublimeLinter-html-tidy,以及 SublimeLinter-json。
以上大多數的 linter 都需要先安裝一些依賴庫才能使用,所以在安裝前請務必閱讀他們的安裝說明。
你可以通過修改用戶自定義的 SublimeLinter.sublime-settings 文件來對你的每個 linter 個性化:Sublime Text > Preferences > Package Settings > SublimeLinter > Settings – User。 例如我通過以下代碼來忽略 pep8 中的錯誤和警告:
"pep8":
{
"@disable": false,
"args": ,
"excludes": ,
"ignore": "E501,C0301,W0142,W0402,R0201,E1101,E1102,C0103,R0901,R0903,R0904,C1001,W0223,W0232,W0201,E1103,R0801,C0111",
"max-line-length": 100,
"select": ""
},
GitGutter
GitGutter 讓 ST3 能在左邊欄的位置顯示一個小圖標,用以表示在最后一次提交以后,代碼是否有追加,修改或者刪除。
FTPSync
FTPSync 能夠將你的項目和遠程文件進行同步。你只需要打開文件便可以下載更新(如果你的遠端文件比本地更加新的話),而且如果你對本地文件做出了修改可以立即同步到遠程服務器。這是非常棒的同步本地文件和遠程文件的方法。你可以通過以下的方法來添加你的遠程服務器:Sublime Text > Preferences > Package Settings > FTPSync > Setup FTPSync.
Sample settings:
{ 'primary': { host: 'ftp.mywebsite.com', username: 'johnsmith', password: 'secretpassword', path: '/www/', upload_on_save: true, tls: true }}
我個人喜歡把密碼設為 因為我不想讓我的密碼出現在配置文件中。這樣 FTPSync 會在我每次保存完文件后要求我輸入密碼。
AdvancedNewFile
AdvancedNewFile 可以讓你在 ST3 中使用簡單的幾個快捷鍵便創(chuàng)建一個新的文件夾或者一個新的文件:
你只需要通過幾個快捷鍵便可以打開 AdvancedNewFile 的輸入框。然后輸入路徑和文件名。當你按下回車鍵后,文件便被創(chuàng)建了。除此之外,如果目標文件夾并不存在的話,該文件夾將會被自動建立。在默認情況下,你創(chuàng)建的文件的路徑將會顯示在狀態(tài)欄中。
請查看 Github 上的這篇文檔來獲取更為詳細的使用說明。特別建議請詳細閱讀TAB自動補全(Tab Completion)以及預定義別名(Predefined Aliases)部分。
我把“cmd+n”設置為了通過 AdvancedNewFile 創(chuàng)建新文件的快捷方式。該快捷鍵可以通過修改 Key Bindings – User file 來實現 Sublime Text > Preferences > Package Settings > AdvancedNewFile > Key Bindings – User:
[
{ "keys": ["cmd+n"],
"command": "advanced_new_file_new"
} ]
你也可以更改默認打開的文件夾路徑:Sublime Text > Preferences > Package Settings > AdvancedNewFile > Settings – User
{"default_initial": "/Users/michaelherman/Documents/repos"}
這樣我創(chuàng)建新文件的時候,/Users/michaelherman/Documents/repos將會自動被添加到路徑最前方,因為99%的情況下我都會把我的腳本放在這個路徑下。
Emmet
Emmet,以前叫做 Zen Coding,讓你可以通過簡單的縮寫來創(chuàng)建 HTML 或者 CSS 的代碼塊。
例如,你只需要輸入感嘆號!,然后按下 tab 鍵,便可以在一個 HTML 文件中創(chuàng)建一段帶有幾個基本標簽的 HTML5 文檔類型的代碼:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
</html>
Markdown Preview
Markdown Preview 可以用來預覽和編譯 markdown 文件。
你可以打開 Package Manager 然后輸入 Markdown Preview 來查看可用的命令:
Markdown Preview: Python Mrakdown: 在瀏覽器中預覽
Markdown Preview: Python Mrakdown: 導出 HTML 文件
Markdown Preview: Python Mrakdown: 拷貝到剪貼板
Markdown Preview: Github風格Markdown: 在瀏覽器中預覽
Markdown Preview: Github風格Markdown: 導出 HTML 文件
Markdown Preview: Github風格Markdown: 拷貝到剪貼板
Markdown Preview: 打開Markdown速查手冊
一旦你完成轉換,你之后的所有保存都會立即反映到轉換的文件中。
快捷鍵
跳轉到任意內容 (“cmd+p”) 用來快速查找和打開文件。你僅僅只需要工程中文件的一部分路徑或者文件名你就可以很容易的打開這個文件。這在一個大型的 Django 工程中顯得非常方便。
跳轉到指定行 (“ctrl+g”) 讓你在當前文件中跳轉到指定行數。
跳轉到標志 (“cmd+r”) 可以列出當前文件中所有的函數或者類,讓你更方便查找。你可以通過輸入關鍵字來查找你所需要的函數或者類。
跳轉到行首 (cmd+left-arrow-key) 與 跳轉到行尾 (cmd+right-arrow-key)
刪除當前行(ctrl+shift+k)
多重編輯 是我迄今為止最喜歡的快捷鍵
6.1:選定一個單詞,點擊 “cmd+d”來選擇同樣的單詞,再次點擊 “cmd+d”*繼續(xù)選擇下一個單詞…
6.2:或者 “cmd+單擊”來指定多個你想要同時修改的地方。
塊編輯 (option+left-mouse-click) 用于選擇一整塊的內容。通常在整理 CSV 文件的時候用于刪除空白內容。
你可以很容易地使用 Python 來編輯你自己的自定義命令和快捷鍵組合。目前我個人使用的有以下這些:
拷貝當前文件路徑到剪貼板 – 鏈接
關閉除當前活動標簽頁以外的所有其他標簽頁 – 鏈接
通過文件選項打開你的 Package 文件夾(Sublime > Preferences > Browse Packages),然后打開 User 文件夾,接下來將上述的 Python 文件添加到 “/Sublime Text 3/Packages/User” 文件夾中。
最后請在 Key Bindings – User file (Sublime Text > Preferences > Package Settings > AdvancedNewFile > Key Bindings – User) 文件中完成快捷鍵綁定。
[ // Copy file name
{
"keys": ["cmd+shift+c"],
"command": "copy_path_to_clipboard"
}, // Close all other tabs
{
"keys": ["cmd+alt+w"],
"command": "close_tabs"
}
]
(有刪減)
譯文地址:http://python.jobbole.com/81312/
譯者:伯樂在線 - Lane
印度小伙寫了套深度學習教程,Github上星標已經5000+
上百個數據文件合并,只能手動復制粘貼?教你一招十秒搞定!
一個提升圖像識別準確率的精妙技巧
一文讀懂:從 Python 打包到 CLI 工具
如何使用 Python 進行時間序列預測?
美亞Kindle排名第一的Python 3入門書,火遍了整個編程圈
十分鐘搭建私有 Jupyter Notebook 服務器
使用 Python 制作屬于自己的 PDF 電子書
12步輕松搞定Python裝飾器
200 行代碼實現 2048 游戲
你喜歡用什么編輯器碼Python?
歡迎留言和我們分享
如果覺得文章對你有所幫助,歡迎點贊并且推薦給你的好友。
*請認真填寫需求信息,我們會在24小時內與您取得聯(lián)系。