發表文章

超簡單做出低功耗藍牙温度計(nRF52840 Dongle + TMP102 + MircoPython)

圖片
 MicroPython支援nRF52840 Dongle (pca10059), 這支在Mouser上只要台幣343左右就可以買到。買來後要燒錄MicroPython的firmware, 寫作時, MicroPython出到1.20.0版。燒錄方法, 可以參考 燒錄Micropython 1.12至nRF52840 Dongle 。這連結有更新, 文章下方有增加1.20.0版的燒錄方式, 不用擔心, 現在的燒錄方法是可以還原的, 以後仍可燒回其他firmware。 有了可跑MicroPython的nRF52840 Dongle後, 可以直接寫Python程式來實作低功耗藍牙温度計。其實不用傷腦筋如何寫, MicroPython官網就有一個範例程式, 直接拿來用就可以有這個功能了! 這麼好, 當然了, 這不就是MicroPython給我們的承諾嗎? 簡單好用! 連結在此:  ubluepy_temp.py 註: 這個程式和MicroPython 1.20.0在nRF52840上, 會有RTC被用掉的問題, 要改一下! 如下圖, 1改成2就可以了。 改好, 直接跑, 然後用手機上的nRF Connect App (或其他BLE App), 找micr_temp這個裝置, 連接上去, 注意連接上去後, Dongle的LED燈會亮起來。找Environmental Sensing服務下的Temperature特徵值, 按下通知啟用, 並修改Data parser為符號整數。查看log部份, 就可以看到每5秒左右會更新一次温度值。如下圖: 如上圖, 第2點所圈起處, 看到2800, 這表示為28度C。如果沒有修改Data parser, 預設會是看到16進位數值, 如上圖第3點所圈起處0xF00A, 這個格式我們人類看不懂! 大家都注意到了吧! 現在温度都出現2700, 2800, 2900之類的, 後面那2個0都不會出現其他數字, 這是因為現在這個範例程式是存取nRF52840內建的温度感測器, 而這個温度感測器基本是查看MCU的温度用的, 而且目前firmware的實作也沒有取得小數點部份, 可能覺得沒必要! 而且, MCU通常會發熱, 比實際上的環境温度要高一些。 因此, 以下使用TMP102這顆TI的温度感測器來取得較為接近實際環境的温度。修改部份...

再論TI TMP102

圖片
 雖然TMP102只是一個温度感測器, 但因為它使用I2C溝通界面, 讓我們可以學習I2C的用法, 而且架構簡單, 用起來不難, 但又有許多功能可以設定, 玩起來很有意思, 最主要的是其温度感測算是很準, 所以我一直很喜歡這顆。加上網路上也有很多人在用, 討論的文章和驅動程式都很容易找到, 所以這裡我想再談一下這顆的一些用法。 1. 驅動程式的寫法:  其實可以不用自己寫驅動程式, 如果你使用Arduino, 那Sparkfun已經幫大家寫好了:  SparkFun_TMP102_Arduino_Library  請直接拿去用就好了! 如果你使用MicroPython, 那khoulihan也寫好一個:   khoulihan/micropython-tmp102 ,  他其實已經寫得很好。 但是我還是自己用MicroPython再寫了一次, 原因是khoulihan的驅動太完整了, TMP102所有的功能都實作了! 可惜的是我想用的一個開發板的Flash空間太小, 放了這個驅動後, 剩下的空間就太小了, 要寫其他的程式就很受限! 另外, 在自己改寫的過程中, 我發現自己又學到一些東西。雖然多花了幾天時間在嘗試, 還是收穫不少! 其實2017年在玩PyMata的時候, 就已經寫過TMP102的驅動, 參見 python code for pymata tmp102 , 但這個是架在PyMata之上的, 基本上是在PC上面執行, 稱之為驅動, 似乎有些奇怪。但程式邏輯和想法基本上相同。 操作TMP102的方法, 很簡單, 就是設定其暫存器的值就可以了, 如下圖 (取自TMP102的datasheet), TMP102主要有4個暫存器, (還有一個指位暫存器Pointer Register), 要取得温度值, 就讀取Temperature Register的內容值, 再做一些格式轉換即可。要讓TMP102進入省電的Shutdown模式, 就只要將Configuration Register內的某一個位元設成1就可以了。問題是如何指定要存取那個暫存器呢? 那就要在指位暫存器先指定就可以了, 例如, 將指位暫存器設成0x01, 就可以存取Configuration Register。 不過, 在讀或寫暫存器值時, 指...

JLink SWD + VCOM (virtual UART)接線方法

圖片
 這算是個差不多先生的故事, 因工作的關係, 由網路管理和系統管理以及企業流程程式設計的領域, 進入了微控制器(MCU, 單晶片)firmware開發的世界。我們內部有從電路設計, 到PCB Layout, Assembly的能力, 所以除了MCU原廠出的Evaluation Board, Development Board外, 我們內部會在取得MCU IC後, 製作自己的工程板(Engineering Board)。驗證沒問題後, 就會將工程板改成真正產品的量產板。 幾乎每個人都以自己的角度來看世界, 硬體部門在做工程板的時候, 就我們firmware的角度來看, 他們應該沒想過我們要怎麼過日子吧! 要怎麼把firmware燒錄到工程板, 這件事就可以看得出來, 工程板上就是把比較會用到的(硬體的角度)Pin拉出來, 例如SWCLK, SWDIO, VCC, GND。然後, 給你一支JLink除錯器, 接下來怎麼接上去, 就是你家的事了! 當然, 這也是給我們自我訓練的機會。 原廠的開發板, 有部份會有onboard debugger, 像下面這張Nordic PCA10040, 我圈起來的部份就是, 通常都會是一顆JLink的晶片。 有些原廠的板子也會沒有onboard debugger, 這時候他們通常會設計一些Connector, 20pin, 9pin之類的, 現在debugger的廠商種類很多, 連接線也一樣有很多種。如以下開發板, 就有一個JLink的標準20Pin的連結器。 這樣使用原廠開發板寫firmware時, 只要用標準的20pin連接線, 來連接JLink除錯器和開發板就可以了。而這連接線和接頭都有防呆的缺口設計, 所以不會弄錯。 而我們一開始想的是, 如何把MCU上的firmware寫好, 除錯器只知道可以用來燒錄firmware到晶片上, 也可以用來做程式的除錯。這樣就好了, 其他的也沒時間多想了。差不多先生就這樣上身了。因此, 我知道, 原廠的JLink除錯器, 在我們使用SWD除錯時, 只要找到20pin裡的4個: VTref, SWCLK, SWDIO, GND。把這4個Pin接到工程板上的VCC, SWCLK, SWDIO, GND, 然後想辦法給工程板供電, 就可以開始工作了, 此時正常的話, IDE上都會看到有抓到除錯...

Infineon PSoC 6 BLE PROTOTYPING KIT 除錯器韌體更新

圖片
  最近在玩這張評估板, Cypress CY8CPROTO-063-BLE PSoC 6 BLE PROTOTYPING KIT, 原廠設計自帶除錯器, 如上圖左邊部份, 標註為KitProg2。 Cypress似乎出三種除錯器: KitProg2, KitProg3, MiniProg4; 自帶的用最低階的我能理解, 但看看不同除錯器支援的功能: 特別是IDE的支援, 明顯KitProg3是比較好的多! 而且似乎KitProg2支援的PSoC Creator只能在Windows上跑! 剛好看到Cypress文件說,  You can update your KitProg device to latest version of KitProg3 firmware with DAPLink using the crossplatform, command line Firmware Loader (fw-loader) tool. 就來試試: 首先要去download fw-loader這個工具,  https://github.com/Infineon/Firmware-loader 然後unzip, 在命令列裡進入這個目錄裡的 fw-loader\bin目錄,  先將評估板接用USB線連到電腦 下指令: (.\fw-loader.exe --device-list) PS C:\fw-loader\bin> .\fw-loader.exe --device-list Cypress Firmware Updater, Version: 3.4.0.1772 (C) Copyright 2018-2022 by Cypress Semiconductor Corporation (an Infineon company) All Rights Reserved Info: Start the API initialization Info: Connected - KitProg2-151A056E021F1400 Info: The hardware initialization has completed in 531 ms The connected supported devices: ...

利用解數獨的方法來解小四數學題

圖片
 小孩小四時的數學題目,  想不開的老爸:到底是誰在念小學?  當時, 忍不住寫了程式來解問題, 想法是列出所有排列可能再一一比對符合條件者, 這個方法會因為列出所有可能排列的清單太多, 而造成CPU使用率相當的高! 也必須等待較長的時間才能得到解答。 研究了數獨的程式寫法後,  數獨(Su Doku)用電腦來解 , 發現用recursion的技法效率相當的不錯, 即使使用Python來寫也可以很快。 之前方法(test3.c)需要36秒才解出答案, 即使改為多緒寫法也要10秒。改用recursion方法來寫後, CPU使用量少到看不到, 答案也是立即閃現。即使用Python來寫, 也是馬上得到答案。這個Python程式放在github: math_junior.py (對應的C語言版本程式:  math_junior.c  , 其實C的執行速度還是快的多) 程式修改的想法如下: 因為和數獨的玩法很像, 都是方格裡填數字, 只是數獨的要求是橫列和直欄及3x3小方格裡的數字都不能重複; 而小四數學題目是橫列格子裡數字加總要等於指定的某個數值, 以及直欄格子裡的數字加總要等於指字的某個數值, 還有格子裡的數字要是1-16都不能重複。這不是很像嗎? 差別只是方格大小不同, 填入格子的數字要滿足的條件不同而已。 因此, solve()裡針對差異改了2個地方, 如下圖: 然後, 資料存放的陣列, 配合要求, 改了一下: 因應題目4x4的方格每橫列加總要等於該橫列指定的加總值, 所以直接把方格加大一些, 多出來的位置拿來放置指定的加總值 (如圖, 橫列的加總值以及直欄的加總值)。 最後, possible(y, x, n)裡要檢查同樣有3個條件, 1. 填入1-16不能重複, 這可以由#can't repeat之下的nested loops 來完成檢查工作。 然後橫列加總的條件有點挑戰! 一開始, 我用傳入的行列值(y, x)來判斷當到達行=3時, 再來檢查橫列加總是否符合條件, 卻總算出錯誤的答案, 而且跑很久! 後來才想到, 這支程式的solve()只找空格來嘗試可能答案, 而題目本身原本在四個角落就已經填了數值! 所以solve()會跳過這4固已填的格子; 這樣一來, 就不會檢查到加總條件是否符合。所以修改成先檢查...

數獨(Su Doku)用電腦來解

圖片
 之前兒子在書局買了一小本的數獨, 無事時拿來玩玩。規則很簡單, 如下圖, 共有9x9的格子, 這個grid又均分成9個sub-grid, 每個sub-grid大小為3x3。每格只能填入1-9的數字, 而且每横列的數字不能重複, 同樣每直欄的數字也不能重複, 還有每個sub-grid內的數字也不能重複。如圖, 一開始都會先有填好的數字, 稱為clue, clue愈多愈好解! 我們玩了一下, 容易的可以在20分鐘左右解完。難的可能要40分鐘以上, 真是kill time的好方法!  但有一天, 小兒突發奇想, 出了一個題目給我解, 哇! 居然解不出來! 這下子是不是顯得我能力不足? (其實是題目出的不好!) 為了證明是題目出的有問題, 我必須找出所有可能的解, 以說明給的clue不足以解出唯一解! 當然聰明的方法是用電腦來解, 用手算是很花時間的。 其實可以google到很多人寫的程式, 第一個找到的程式是: a really simple sudoku solver in pure c 這個程式可以找出解, 但也只會找到一個解! 因為正常來說, 數獨出題的人會只出有唯一解的題目, 所以只找一個解的想法是合理的。但是碰到小朋友這種出題者, 就不會只有唯一解了! 因此, 我就想要自己改一下這支程式來找出所有解!  當然, 還是先google一下, 是不是已經有人已經先寫好了。結果先看到以下的問答: Sudoku multiple solutions C 就是有人寫了一個類似的程式, 然後問怎麼改成可以解多個解, PioneerAxon則回答, 1. solveSudoku()在return 1之前要把value重置回0, 2. 所有格子都填完就印出結果。雖然沒有直接幫忙把程式改完, 但這些提示對我很有助益! 然後, 他還給了一個連結, 指到一個sudoku-solver的程式專案。我也去看了這個專案, 試了一下程式, 它確實可以非常快地找到所有的解。不過, 這支程式的寫法稍為複雜了一些些。我還是以前面的那支程式來改寫, 首先要先看懂程式的邏輯是什麼, 簡單說是利用recursion來幫我們產生一個tree search, 將所有可能都走遍, 再排除所有不對的情況後, 自然會找到所有可能的解。以下影片, 應有助更深入的理解。 所以依Pionee...

Raspberry Pico RP2040 + MicroPython + TMP102

圖片
 TI TMP102溫度感測器雖然有點年紀了, 但是幾年前我買了一個由sparkfun製作的模組, 這期間也使用過其他廠商的產品, 例如ASAIR AM2320, DHT11, TMP36, Bosch BME280。用起來, TMP102算是很好用的, 雖然只有單一的溫度感測功能, 但他很穩定, 使用的人也多, 很容易找到資源。 今天只想簡單的把微控制器接上TMP102, 讀一下溫度, 特別是冬天想做個麵包, 溫度是很重要的控制因素, 太冷的話, 發酵不起來的。 接線方法如下圖, 就2個模塊: Pico 和 TMP102。他們之間使用I2C溝通, 也就是實體線路SDA, SCL二條線, SDA我使用藍色的線, SCL我用紅色的線。不要忘記, 電路元件是要供電才會動的, 所以還要再接上GND, VCC。 用照片看不清楚的話, 我把Pico的Pinout圖放在下面, 我把使用到腳位打勾, 共4個Pin: 38 GND, 36 3V3(OUT), 22 GP17 (I2C0 SCL), 21 GP16 (I2C0 SDA)。各位可以用來和照片相互對照。其中39 VSYS (當接USB供電時, 此腳位是5V), 其實是用來輸入電源供電給Pico的, 這裡要改用36 3V3(OUT)比較適合。 好了, 硬體接線接好後, 要來驅動他們工作了。最最簡單的方法, 目前來說, 就是使用MicroPython了, 因為最煩人的部份, 他們都幫大家做完了! 剩下的部份, 留給大家來完成的就是最好玩的部份了。Pico的資源真的很多, Raspberry Pi原廠的文件和網站就已經做得很不錯, 其他相關廠商也有不錯的文件, 例如賣電子零組件的Digikey也寫了一份文件來教大家怎麼使用Pico的I2C:  https://www.digikey.tw/en/maker/projects/raspberry-pi-pico-rp2040-i2c-example-with-micropython-and-cc/47d0c922b79342779cdbd4b37b7eb7e2 目前和MicroPython最匹配的軟體開發環境應該是Thonny,  https://thonny.org/  下載安裝後, 開啟Thonny, 在他的功能表Tools -- Opt...