文章

顯示從 2020 起發佈的文章

[模組] 無線資料傳輸:nRF905 和 nRF24L01 (以 Arduino 為控制器)

圖片
# [模組] LoRa 模組範例測試通訊距離 # [模組] LoRa - Arduino MKRWAN 1300 通訊模組 模組說明          過去挪威公司 Nordic 開發兩款無線通訊傳輸模組,一種用在中低頻段 (433/868/915 MHz),稱為 nRF905 ;另一種用在高頻段 (2.4 GHz),稱為  n RF24L01 。以 RF 特性來看這兩款模組,低頻傳輸距離較高頻遠,低頻訊號具有繞射特性,高頻訊號穿透性較差,不過高頻的資料傳輸率比較高,NRF24L01 傳輸率 > 250kbps,NRF905傳輸率 < 50kbps。因此,我們可以依據應用的需求,選擇適合的無線模組。        圖一所示為 Nordic 公司的 NRF 模組的內部方塊圖,圖右邊有 SPI 控制介面可以讀寫晶片內的暫存器,這些暫存器組算是晶片基頻的數位資料,已經被解調後的資料了。另外,控制接腳用來切換 TX/RX 模式,RF 模組的傳輸可視為 半雙工 方式,因為不可能同時發送又接收。圖左邊是天線,內有一機制是模式切換,就是技術文件裡說的 BurstTX 和 BurstRX。接收端,後面接一個 LNA 放大器,將接收下來的小訊號放大以便讓後端解調處理。發射端,接一個 PA 放大器,將調變訊號再增強以便發射出去,PA 增益越大,發射的距離越遠,但是以這模組上的 PA 放大功率有所限制,主因還是使用無線頻譜資源必須得遵守, 不可干擾其他設備 。 圖一:NRF 無線模組的內部方塊圖 資料傳輸測試         NRF 模組內部有兩大機制,一個是位址,一個是 CRC 檢測,必須位址正確了,加上 CRC 檢測無誤,這樣才算完整接收成功。為了驗證資料丟失率,我們用兩塊 Arduino 開發板和 NRF905 模組,當做資料乒乓傳輸測試,一邊當發射端,一邊當接收端。發射端送出資料後,接收端收到後必須再回傳,發射端確認回傳資料無誤後,紀錄一次正確傳輸,如果一段時間沒有收到,代表資料丟失,記錄一次失敗傳輸,發射端再重新傳輸一次。         底下影片紀錄雙邊通訊的情況,在短距離的範圍內 (< 1公尺),發送一筆 4 bytes 長度的資料,接收端再回傳資料,當做 ACK,過程中還是有丟失資料的現象。測試代碼可參考 [2][3]。 影片:兩個 NRF90

[模組] 4G 通訊模組的應用

圖片
實際應用         在一個監控系統之中,網路通訊往往是最基礎的建置,如果已經布建了有線網路,自然省了網路通訊的工事。不過,有些監控環境幅員廣大,並不適合布建有線網路,因為採用 4G 通訊模組較為方便,如下圖一所示。         在圖中的左邊是監控的場域,圖中的右邊是監控中心,配置有資料庫系統。在偏闢的場域,安裝各種感測器,並將收集到的資料回傳監控中心的資料庫,這時整合一個 4G 通訊模組彼拉有線網路更為有效率。因此,我們研究目前市面的 4G 模組,並進行測試。購買模組時,要留意 4G 支援的頻道,有些模組支援的頻道數不夠多,未來使用時可能會遇上通訊不通,而我們實驗的模組是 4G - EC20 (Quectel)。 圖一:4G 通訊模組應用在監測環境 模組類型         目前我們使用的 4G 模組有兩種,可以依據本身的需求選用適合的模組,一種是用來整合嵌入式系統的模組,一種是獨立運行的模組。說明如下:         1) UART 介面為控制的模組:這種 4G 模組可以用來與其他模組整合在一起,MCU 藉由 UART 介面與 4G 模組連接,指令與資料傳輸都透過這介面通訊,MCU 組成一個系統並負責整合每個模組的運作。如下圖二所示,這種模組比較容易吸引 maker 的使用。         2) 路由器的模組:這種 4G 模組已經可以直接單獨使用,本身有乙太網路端口,如下圖三所示。運行這模組之前,我們需要先配置這 4G 路由器,類似配置 IP 分享器一樣。 圖二:以 UART 介面控制的 4G 模組 圖三:4G 模組路由器 UART 介面控制         4G 模組的控制指令都是靠 UART 介面做通訊媒介,而網路封包的資料也是透過 UART 介面傳送的,UART 通訊配置為 115200 bps, 8-N-1 的格式,看的出來這只適用於 低流量 的通訊應用。接著來了解一下如何使用模組,控制模組的指令是以 AT 方式處理,簡單區分下列的 AT 指令:         1) 控制指令:這些指令包含一些設定配置,或者各種查詢的指令。比如: ATI 查詢模組型號, ATE0 關閉指令的 echo 回應, AT+CSQ 查詢訊號強度...等等。更多的指令可以參考模組的文件。         2) 電話簡訊指令:這模組也能傳送簡訊,適合應用在行動電話的告

[模組] 實現小尺寸 TFT LCD 的控制 (以 ST7735 模組為例)

圖片
       一個系統是由多數個大大小小模組所構成,學習各類模組的開發有助於設計一個系統,其中 TFT LCD 模組是常見的人機溝通介面,接下來針對小尺寸模組(1.8吋)的硬體接線方式與程式調用進行說明。 模組硬體        以 ST7735 晶片驅動的 TFT LCD 模組的控制介面是 SPI,再加上 DC 與 Reset 兩根控制接腳。模組與 Arduino UNO 相連的方式如下:                 CLK    -- pin 13 (SPI clock)                 MISO  -- pin 12 (因為 LCD 是輸出顯示,可以不接)                 MOSI  -- pin 11 (SPI MOSI)                 CS       -- pin 10 (SPI chip select)                 DC      -- pin 9   (Data/Command 這個接腳可換,與程式碼的調用有關)                 Reset   -- pin 8   (這個接腳可換,與程式碼的調用有關) 驅動程式封裝         在 Arduino IDE 環境下,Adafruit 已經將 TFT LCD 控制的函數封裝起來了,並提供繪圖的 API 讓使用者調用。首先,我們要先下載 Adafruit TFT library ,安裝成功後,可以在 \Arduino\libraries 路徑下找到 TFT 目錄夾,這底下就是 Adafruit 提供的函數庫。整個函數庫被封裝成圖一的架構,我們從最上層的 API 開始研究,先到 Arduino 網站上查詢 https://www.arduino.cc/en/Reference/TFTLibrary  有哪些函數,發現 API 就是畫點、畫線、畫矩形、 畫圓、設定長與寬...等。         Adafruit 將 Arduino 最上層的 API 實現在 GFX 這一層裡面,只要打開原始碼 Adafruit_GFX.cpp 可以查看所有繪圖功能的實現,無論是哪種尺寸的 LCD,GFX 這一層都能做到點線面的繪圖功能。承接 GFX 的底層就是 TFT LCD 的驅動程式,以 ST7735 面板為例,上面的

[應用] 生產線設備的數據分析 (以 C# 程式開發)

圖片
系統架構         與金屬中心合作的智慧機上盒 ( SMB : Smart Machine Box) 補助計畫案,開發系統並應用在工廠實作上。以下內容是實際運用在工廠的案例。在提升工廠的設備產能效率上,需要將產線上的設備進行 e 化,並且收集各個設備的數據,在後端進行數據分析。首要,設備要具備連網的功能,如果無法連網,也要開發一個類似 gateway 的轉換器與設備相連,將該設備網路化。工廠網路化之後,工業連線有一套資料傳輸標準,稱為 MODBUS [1],每台設備皆可透過這套通訊協定傳送資料,如下圖所示。最後,收集來的資料必須找個地方存放以便分析,安裝一套資料庫或使用既有的資料庫是不錯的選擇,而後端的資料庫可以依照使用者的熟悉度安裝與配置,目前這工具分別與 Oracle、SQLite 、MS SQL 測試過連線和讀寫。         實際開發的過程中,遇到最大的挑戰是產線設備的聯網,有些產線的環境比我們想像的還惡劣 [2]。並非所有生產設備都具有網路接口,有的設備只有 RS-232/RS-485 接口,有的設備只有 USB 輸出,在不更換產線設備的前提下,我們需要在設備外面再連一個轉換器,將接口轉換成網路讓生產線具有聯網的功能,參考 [3][4] 文章的說明。 圖一:系統架構圖         接著,我們以 C# 語言開發一套資料擷取的工具,如下圖二所示,利用 MODBUS -TCP 連線與設備相連接,採用每秒輪詢的方式讀取單一設備的所有資料,再將這些資料寫入後端的資料庫系統內。在多個設備的環境下,程式對每個設備的連線會創建一條 thread,專門處理該設備的資料擷取,讀取後的資料再傳到資料庫並寫入表格裡。 圖二:資料擷取工具的畫面         擷取工具中,每個設備的參數以 XML 格式存放,如下圖三所示,配置非常方便閱讀。紀錄設備的 IP 位址,設備型態名稱,MODBUS 的設備 ID...等。每個設備裡,紀錄著欲讀取資料的型態與位址。 圖三:XML儲存每個設備的參數 調用資料庫       C# 程式開發各種資料庫的函數庫,要先從 NuGet 套件庫中下載函數庫,如下圖四所示,有調用 Oracle 和 SQLite 的 DLL。接著,依照各個資料庫的指令製作 CreateTable 、Reader 、Insert...等呼叫的接口。我們將程式連接

[應用] STM32 DFU (Device Firmware Upgrade)

圖片
DFU 說明         DFU (Device Firmware Upgrade) 顧名思義是升級晶片的韌體程式,這相當於嵌入式系統中的 bootloader 程式。一般來說,我們所開發設計的韌體程式會存放在晶片內建的 flash 或者外部的 flash、 NOR、NAND,而 DFU 程式就是為了更新放在那些 flash 裡的韌體。另外,更新的方式可以透過 RS-232、Ethernet、USB...等,從這些媒介收到更新的程式碼,再燒錄到所存放的對應位址。         對於 STM32 晶片來說,當電源啟動後,晶片第一執行的位址就是 0x8000000,所以我們把這一小段 DFU 程式安排在這個位址,此時 DFU 內部程式執行後,我們會設計成做個判斷「是否做韌體升級」,如果沒有的話,DFU 會將執行位址跳到 APP 定義的位址,如下圖所示。圖一中,APP 程式碼安排在 0x8003000 位址,這個位址可以自己定義,假如 DFU 程式碼比較大,勢必要將 APP 位址往後移,如果 DFU 程式碼較小,就可以將位址往前移。         如果判斷為更新韌體,這時 DFU 要啟動輸入媒介(RS-232、Ethernet、USB)的驅動,同時也要啟動寫入 flash 的驅動。將收到的韌體程式碼,逐步寫入 flash 裡面。接下來本文的例子是以 STM32 USB 的更新方式來說明,STM32 網站有提供 DFU USB 的範例程式。 圖一:STM 內部記憶體配置 位址安排         當我們用 KEIL IDE 開發環境編譯時,需要先配置程式碼儲存的地方,圖二和圖三分別是 DFU 和 APP 程式碼定義的位址,DFU 放置在 0x8000000,大小為 0x3000 ,然後 APP 程式碼則要放在 0x8003000 ,這就是程式碼配置的關鍵步驟。         此外,還要留意一點,由於 APP 程式碼起始位址已經偏移了,它的中斷向量表 Vector 位址也已經偏移了,所以我們必須要 APP 程式裡把新的中斷向量表做重新的 map,指向新位址。請參考底下這個函數                             NVIC_SetVectorTable ( NVIC_VectTab_FLASH, 0x3000 ); 圖二:設置 DFU 的

[模組] ADXL335 三軸加速計的 USB 體感搖桿

圖片
[1]  三軸陀螺儀與加速規 Gyro & Accelerometer [2]  三軸重力加速計 Accelerometer (GY-61 ADXL335 模組) STM32F1 系統         在之前的文章中[1][2]曾研究過三軸加速計的控制,當時使用的控制器是 NXP LPC11 系列,這回我使用 STM32F103 做為控制器,開發一個 USB 介面的操控搖桿,系統的架構則如圖一所示。         GY-61 模組上面是 ADXL335 晶片的三軸加速計,將它的 XYZ 軸的訊號線接到 STM32 開發板上的 ADC 接腳。另外,板子上的 DMA 功能要開啟,利用 DMA 搬運 ADC 的取樣資料。每次搬運完成後,產生中斷通知 CPU。根據 XY 軸的資料,計算出游標數值,透過 USB 介面再傳送給電腦。整個操作的過程,請參考底下的影片。 圖一:系統架構圖 STM32F103 + ADXL335 影片: [模組] GY-61 ADXL335 as USB joystick on STM32F103         此外,用 STM32F103C8 最小開發板設計開發一個搖桿的功能,同時具有方向鍵,如同電玩的搖桿一樣,請參考影片連結  https://youtu.be/pO3MB5SFBMg

[筆記] Jitsi Meet server 視訊會議系統

圖片
一,準備工作 準備作業系統 Ubuntu 18.04 以上的 Server (無UI),或 Desktop (有圖形UI,但容量大)。 安裝並開啟 ssh:Desktop 版本才需要安裝 SSH server,Server 版本已經有了。在命令列輸入 #sudo apt-get install ssh,這樣我們便可從遠端 SSH-client 連線進入作業系統操作了。 設定系統 DNS:/etc/resolv.conf裡面要新增 DNS 服務器,如 nameserver x.x.x.x,這樣之後我們在更新軟體套件時才不會出錯。或者,修改 /etc/netplan/xxxx-init.yaml 檔案的內容,重新設定網路參數,這樣也行。 二,安裝 Jitsi Meet 服務器 設定域名 :到 DNS 註冊一個機器的域名對應到公網 IP 位址,比如在公網輸入meeting.jitsi.tw 便會指向安裝的服務器。不過,在測試階段,我們可以考慮架設一台本地DNS server (用Windows 2008/2012/2016...的環境),配置一個內部的域名,這樣暫時不用註冊一個公共的域名。 設定服務器的主機名稱 :修改 Linux 系統的 /etc/hostname內容,或者命令列 #sudo hostnamectl set-hostname meeting,這樣機器在網上能被其他電腦用名稱來訪問了。 開啟防火牆 :利用 ufw 命令開啟下列的埠,TCP 80 (http) 、 443 (https) 、 4443 (video/audio) 、 22 (SSH),以及 UDP 10000 (video/audio)。例如命令列 #sudo ufw allow 80/tcp,再把 ufw 啟動。 安裝過程 :          a) 命令列 #sudo apt-add-repository universe:由社群維護的軟體庫新增到系統的更新列表上,基本上 OS 系統已經有預設了。           b) 安裝 apt-transport-https :這是 HTTP over TLS。           c) gnupg2 :這是 OpenPGP 工具 ,方便檔案加密,如果沒有安裝這工具,Jitsi Meet 將無法下載安裝。           d)

Visual Studio 2019 遠端連接到 Raspberry Pi 的執行與除錯

圖片
[準備工作] 在 Raspberry Pi 系統:         1. 安裝 openssh-server , g++ , gdb , gdbserver           2. 開啟 ssh 服務,sudo service ssh start 在 Visual Studio 系統:         1. Visual Studio Installer 先安裝 " Linux C++ 開發元件 "         2. 新建一個 Raspberry 專案         3. 設定遠端偵錯電腦,如下圖。 圖一:遠端偵錯配置 [編譯專案]        從 Visual Studio 2019 編譯樹莓派的 Linux 專案,程式碼只是點亮一顆 LED 燈,還有控制 I2C 介面的 LCD 模組。用 VS 2019 編譯後,結果如下圖所示,產生的 out 執行檔被傳送到樹莓派的工作目錄上。 圖二:編譯後的結果 [遠端執行]        此時準備從 Visual Studio 2019 執行樹莓派的 Linux 程式,如果要中斷程式的話,在執行前必須先設定好中斷點。好了,開始執行後,列印的結果如下圖,顯示在 "Linux 主控台視窗" 。 # 小尺寸 TFT LCD 顯示控制 (以 Arduino 和 Raspberry Pi 為例) # 中文語音合成+語音辨識 以百度的AI開放平台 in Python 開發 # Raspberry Pi 樹莓派的入門筆記 # Raspberry Pi 樹莓派的 I/O 介面開發 in C

[筆記] Android Studio 遇到 Gradle 的問題

圖片
        每次升級Android Studio後,總會遇到原本的項目無法成功編譯 (升級前是正常),發現在網路上也有其他人遇上同樣的問題,這次就將問題記下來以免未來又忘了。 1. Gradle 與 Gradle Plugin 是兩個不同東西,下圖一:         Gradle :是開發過程中的工具,對所有程式碼的編譯與封裝,可以看成是一個 MakeFile 或是 Visual Studio 當中的 project solution。         Gradle Plugin :是一個 Android Studio 裡面的插件,這插件是為了整合Gradle工具,然而插件的版本並不與 Gradle 版本相同,所以圖一可以選擇插件的版本,也可以選擇 Gradle 工具的版本。 圖一:Gradle 與 Gradle Plugin 2. 編譯出現 "Process unexpectedly exit"         這個問題主要是插件版本所造成的,其實與 Gradle 版本不相關 (我上下的版本號都改來改去,後來才發現插件問題)。解決的方式,我們要調整圖一中的 Gradle Plugin 版本, 往下降低 並找到適合的版本,直到能夠成功編譯的版本。 圖二:編譯時所發生的問題 3. Android Studio 編譯         調整過版本後,先 sync Gradle,這時會檢查編譯封裝的自動化內容,檢查過程很快,如果沒問題,就可以進行編譯。在編譯前,最好先clean project,然後再 make app 或者 make module,確保編譯的內容很乾淨。如果沒有先做 clean 的動作,有時編譯過程會出現異常。

[應用] 雲運算之語音辨識 (Speech To Text)

圖片
語音辨識架構         隨著雲端運算的技術越來越成熟,各家平台提供語音方面的服務,應用開發者只要連上雲端並將語音上傳,便能取得想要的服務。為了研究如何連上各家平台的服務,筆者設計一個 Proxy 服務,如圖一所示。目前,我們實際使用過的平台有:阿里雲 、 百度 、 科大訊飛 、 雲知聲,每個雲端平台提供服務的連線驗證方式都不一樣,而且雲運算的語音辨識參數也不盡相同,所以設計一個 Proxy Service 將連線驗證與各項參數做成一個統一開放的介面。Proxy 服務讓其他程式 、 工具 、 或人機介面透過網路方式連到這個服務上,並上傳語音,之後返回辨識結果。過程中,各平台的驗證以及 SDK 的整合均由這個 proxy 處理掉了。 圖一:語音辨識的 Proxy 服務 設計流程         圖二是Proxy Service 內部架構的方塊圖。服務裡有一個 TCP listening 一直等待著其他程式連線,一旦有 TCP 連線,便創建一個新 thread,專門處理這一路連線的通道。由此可知,Proxy 服務可以同時處理多個語音通道,互相獨立運算。另外,圖下方所示,這個服務的底層就是整合多家平台的 SDK,調用他們的 SDK 連上雲端獲得服務。這些 SDK 函數主要功能是封裝 WebSocket 通訊協定,方便開發者調用。當然,我們也可以根據平台的技術文件自行設計一套 WebSocket app 連線雲端,參考 [1][2] ,既然平台有提供 SDK,最好是使用 SDK 來開發,這可避免不相容的問題。         Proxy 服務的核心是提供一個統一開放介面 SRChannel,並可以設定相關參數,如:VAD 、s ilence偵測 、 silence 長度...等。設計一個存放語音的 queue,並穩定地上傳到雲端。從雲端返回的事件或結果,再傳給對應的程式。 圖二:Proxy 服務的內部方塊圖 實現展示         這裡,我們設計一個音檔轉換工具,透過 Proxy