工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

BLEモジュール BL652ブレイクアウトボードで遊ぶ(4) --- A/D変換 ---

概要

BL652ブレイクアウトボードで、アナログ出力のセンサの値をA/D変換して読み取ってみた。



背景と目的

前回のI2C通信に引き続き、BL652ブレイクアウトボードでの実用を想定して、アナログ接続のセンサからA/D変換で値を読み取ってみる。



詳細

0. 実施環境と参考情報


1. 回路

以下の回路を使用し、AIN4~AIN7のA/D変換値を読み取る。

f:id:dekuo-03:20211128201544p:plain

  • AIN4: 5V系の電源電圧検出用回路を接続
  • AIN5: 土壌水分センサを接続
  • AIN6: 光センサを接続
  • AIN7: 予備系統

なお、GPIO14,16,18,20は計測時以外の無駄な電流をなくすための制御ポートとして用意している。(今回はどうでもいいのでONしっぱなしで使う)


2. コーディング

参考資料2を参考に、コーディングした。動作は、3秒に1回、A/D変換入力4chを取得。AD変換の設定は、

  • 減衰比: 1/6
  • 分解能: 12bit
  • アクイジションタイム: 40usec

とした。BL652の仕様上、A/D変換の基準電圧が0.6Vで減衰比1/Nのとき、ディジタルフルスケールが0.6 * N [V]に対応する。

GPIO14,16,18,20は、今回は待機電流はどうでもいいのでHIGHにしたまま。

// 変数 -----------------------------------------------------------

DIM pinVBAT,pinMOIST,pinPHOTO,pinEX1 // ADC入力
pinVBAT = 28
pinMOIST = 29
pinPHOTO = 30
pinEX1 = 31

DIM pinVBATEN, pinMOISTEN, pinPHOTOEN, pinEX1EN // センサ電源
pinVBATEN = 20
pinMOISTEN = 18
pinPHOTOEN = 16
pinEX1EN = 14

DIM r // 作業用

DIM adcVBAT, adcMOIST, adcPHOTO, adcEX1 // ADC計測値
DIM VCE as float : VCE = 0.013 // VBAT計測回路オフセット, 13mV

// 関数 ----------------------------------------------------------------

// ADCピン設定
FUNCTION config_ADCPins()

    // GPIOSETFUNCEX (nSigNum, nFunction, subFunc$)
    // subFunc$ will be a string that has the following form:- "\Gain_hex\Resolution_hex\Acquisition_hex"
    // ADC基準電圧は0.6V、1/Nスケーリングの場合、0.6*N[V]がディジタルフルスケールになる
    DIM subFunc$ : subFunc$ = "\16\0C\14" // gain=1/6scaling, resolution=12bit, aquisition_time=40usec
    r = GPIOSETFUNCEX(pinVBAT, 3, subFunc$)
    r = GPIOSETFUNCEX(pinMOIST, 3, subFunc$)
    r = GPIOSETFUNCEX(pinPHOTO, 3, subFunc$)
    r = GPIOSETFUNCEX(pinEX1, 3, subFunc$)

ENDFUNC 1

// センサ回路電源設定
FUNCTION config_SensorPowerSupply()
    // GPIOSETFUNC (nSigNum, nFunction, nSubFunc)
    // nSubFunc
    r = GPIOSETFUNC(pinVBATEN, 2, 0) // VBAT
    r = GPIOSETFUNC(pinMOISTEN, 2, 0) // MOIST
    r = GPIOSETFUNC(pinPHOTOEN, 2, 0) // PHOTO
    r = GPIOSETFUNC(pinEX1EN, 2, 0) // EX1

ENDFUNC 1

// センサ回路ON
FUNCTION enable_Sensors()

    GpioWrite(pinVBATEN, 1) // VBAT
    GpioWrite(pinMOISTEN, 1) // MOIST
    GpioWrite(pinPHOTOEN, 1) // PHOTO
    GpioWrite(pinEX1EN, 1) // EX1

ENDFUNC 1

// AD変換
FUNCTION get_ADC()

    DIM VBAT as float

    // ADC
    adcVBAT = GpioRead(pinVBAT)
    adcMOIST = GpioRead(pinMOIST)
    adcPHOTO = GpioRead(pinPHOTO)
    adcEX1 = GpioRead(pinEX1)

    VBAT = (adcVBAT * 0.6 * 6 / 4096.0 - VCE) * 2.0 + VCE

    // 表示
    PRINT "VBAT = "; VBAT; "V\n"
    PRINT "MOIST = "; adcMOIST; "\n"
    PRINT "PHOTO = "; adcPHOTO; "\n"
    PRINT "EX1 = "; adcEX1; "\n"
    PRINT "\n"

ENDFUNC 1

// メイン -------------------------------------------------------

// ADCピン設定
r = config_ADCPins()

// センサ回路電源設定
r = config_SensorPowerSupply()

// センサ回路ON
r = enable_Sensors()

ONEVENT EVTMR1 CALL get_ADC

TimerStart(1, 3000, 1)

WAITEVENT


3. 動作確認

以下の通り、チャンネルごとに多少ばらつきはあるが、ほぼ正しい値となっていることを確認した。

  • AIN4
    • 実測1: 4.55V、A/D変換値: 4.55V
    • 実測2: 3.38V、A/D変換値: 3.39V --- 電池が消耗した場合を想定して低めの電圧の時の精度を確認。
  • AIN5
    • 実測: 2.956V, ADC: 3370=2.956V
  • AIN6
    • 実測: 2.247V, ADC: 2576=2.261V

※AIN7は、予備なので精度確認なし。

※上記の数値は、下の画像とは別のタイミングで取得。

f:id:dekuo-03:20211128202153p:plain


まとめと今後の課題

本記事までで、I2C、BLEアドバタイズ、A/D変換のコーディング方法が確認できた。次回は、センサ計測値をBLEで飛ばせるようにしたい。


ベビーリーフを育てる(1) --- 種まき ---

概要

ビーリーフの種まきを行った。



背景と目的

9月にわけぎを育てはじめたのだが、発芽せず完全に失敗してしまった。このまま何も育てないのも勿体ないし、何より失敗して悔しいのでどうにかして食えるものを育てたい。 わけぎの代わりに、今の時期に育てて比較的早く収穫できそうなものを探したところ、ベビーリーフといわれるサラダなどに使えそうな葉物がよさそうだとわかった。そこで、失敗を取り返すべくベビーリーフの栽培を始める。



詳細

1. 種の調達

近所のホームセンターで、以下の「ガーデンレタスミックス」という種を見つけた。 5種類のレタスの種がミックスされているので、うまく育てればいろいろなレタスが採れるはず。

www.sakataseed.co.jp


2. 種まき

プランターの場合、ばらまきでよいということなので、プランター全体に適当にばらまいた。量は、入っていた量の1/3~半分程度。 その上から少しだけ土を振りかける感じでかけて、水をやった。発芽は、暖かい時期なら数日、寒い時期なら1週間くらいらしい。うまく発芽してほしい。

f:id:dekuo-03:20211107122535j:plain



まとめと今後の課題

ビーリーフの種まきを行った。発芽することを祈る。


Tablacus Explorer上にWinSCPからドラッグ&ドロップする方法

はじめに

Tablacus Explorer上にWinSCPからドラッグ&ドロップすると、

f:id:dekuo-03:20211022092735p:plain

WinSCPはドロップ先のフォルダを検出できませんでした。」と出てしまい、うまくいかなくて困っていたが、やっとやり方が分かった。


やり方

WinSCPの設定画面>転送>ドラッグ&ドロップで、「一時フォルダを使用してダウンロード」

を選択する。

f:id:dekuo-03:20211022092606p:plain

これだけでOK!!!

BLEモジュール BL652ブレイクアウトボードで遊ぶ(3) --- I2Cセンサとの通信 ---

概要

BL652ブレイクアウトボードで、I2C接続のセンサからデータを取得してみた。



背景と目的

前回、BL652ブレイクアウトボードを使うための開発環境を整え動作を確認した。今回は、実用を想定してI2C接続のセンサからデータを取得してみる。



詳細

0. 実施環境と参考情報


1. smartBASICでFLOAT型を使おうとしたら使えないのでファームウェアをアップデート

FLOAT型を使おうとしたらいきなりつまずいたので、メモ。 BL652は、smartBASICという言語でプログラムを書く。参考資料1にはFLOAT型の説明が載っているので、FLOAT型を使おうとしたのだが、なぜかCompileするときにUNKNOWN TYPEになってしまう。 どうもおかしいと思って色々調べたところ、ファームウェアが古いせい?に見えたので、こちらを参考に、ファームウェアの更新を行った。以下のように、もともとv28.6.1.2だったのを、v28.11.8.0にバージョンアップできた。

f:id:dekuo-03:20211004005957p:plain

f:id:dekuo-03:20211004010010p:plain

アップデート後、FLOAT型を使ってみたところ、エラーが出なくなった。ということで、問題解決。


2. I2C接続

I2C接続のセンサとして、手持ち品のBME280を使ってみた。 しかし、これが悪手だった。 今まで、ESP32などではArduino向けライブラリを使っていたせいで大して苦労はなかったが、smartBASICでは用意されていないので、BME280の仕様書を見ながら自前でコーディングしなければならないということに、やり始めて気づいてしまった。途中までやってしまったのでどうにかやり切ったのだが、まあこの手の作業はあまりやりたいものではない。具体的には、参考資料1の6.14に従った。なお、サンプルに書いてあるI2C読み出し関数のリターンコードに応じたエラー処理はすべて省略している。

一応、温度、湿度が取れるようになった。気圧は、なぜかうまくいかない。苦戦中。。。ひとまずここまでの出来高を載せておく。動作としては、

  • 1秒周期で、温度、湿度、気圧(うまくいってないが)をシリアル出力

するだけ。

2.0 BME280関連の定数、グローバル変数

// BME280定義値 ----------------------------------------------
// デバイスアドレス
DIM nSlaveAddr: nSlaveAddr = 0x76

// キャリブレーション値
DIM dig_T[3] AS INTEGER // 温度
DIM dig_H[6] AS INTEGER // 湿度
DIM dig_P[9] AS INTEGER // 気圧
DIM t_fine AS FLOAT

2.1 雑多な計算用

// singed int32に変換
FUNCTION to_SInt32(A AS INTEGER, b AS INTEGER)
    //PRINT "A = "; A; ", b = "; b;
    IF A >= b THEN
        A = 0xFFFFFFFF - (b * 2 - A) + 0x01
        //PRINT " -> A = "; A; "\n"
    ELSE
        //PRINT "\n"
    ENDIF
ENDFUNC A

2.2 初期設定

// 初期設定
FUNCTION INIT_BME280()

    // configレジスタ(0xf5)
    // 0xa0 = スタンバイ時間1000ms, IIRフィルタなし, SPI4線(無関係)
    DIM nRegAddrConf: nRegAddrConf = 0xf5
    DIM nRegValConf: nRegValConf = 0xa0
    rc = I2cWriteReg8(nSlaveAddr, nRegAddrConf, nRegValConf)

    // ctrl_measレジスタ(0xf4)
    // 0x27 = 温度オーバーサンプリングx1, 気圧オーバーサンプリングx1, ノーマルモード
    DIM nRegAddrCtrl: nRegAddrCtrl = 0xf4
    DIM nRegValCtrl: nRegValCtrl = 0x27
    rc = I2cWriteReg8(nSlaveAddr, nRegAddrCtrl, nRegValCtrl)

    // ctrl_humレジスタ(0xf2)
    // 0x27 = 湿度オーバーサンプリングx1
    DIM nRegAddrCtrh: nRegAddrCtrh = 0xf2
    DIM nRegValCtrh: nRegValCtrh = 0x01
    rc = I2cWriteReg8(nSlaveAddr, nRegAddrCtrh, nRegValCtrh)

ENDFUNC 0

2.3 キャリブレーションデータの読み出し

// キャリブレーションデータの読み出し
FUNCTION READ_TRIM()

    DIM i AS INTEGER
    DIM work[7] AS INTEGER

    // 温度 ----------------------------------------------------------
    DIM nRegAddrT: nRegAddrT = 0x88 // 先頭アドレス
    FOR i = 0 to 2 STEP 1
        rc = I2cReadReg16(nSlaveAddr, nRegAddrT + 2 * i, dig_T[i])
        IF i != 0 THEN
            dig_T[i] = to_SInt32(dig_T[i], 0x8000)
        ENDIF
        //PRINT "dig_T"; i + 1; "="; dig_T[i]; "\n"
    NEXT
    
    // 湿度 ----------------------------------------------------------
    DIM nRegAddrH1 : nRegAddrH1 = 0xa1
    DIM nRegAddrH2 : nRegAddrH2 = 0xe1
    
    rc = I2cReadReg8(nSlaveAddr, nRegAddrH1, dig_H[0]) // unsinged char
    //PRINT "dig_H1="; dig_H[0]; "\n"
    
    FOR i = 0 to 6 STEP 1
        rc = I2cReadReg8(nSlaveAddr, nRegAddrH2 + i, work[i])
        //PRINT "work["; i; "]="; work[i]; "\n"
    NEXT
    
    dig_H[1] = work[1] * 256 + work[0] // signed short
    //PRINT "dig_H2="; dig_H[1]; "\n"
    
    dig_H[2] = work[2] // unsigned char
    //PRINT "dig_H3="; dig_H[2]; "\n"
    
    dig_H[3] = to_SInt32(work[3] * 16 + (work[4] & 0x0F), 0x800) // ビット演算を()で囲む必要あり
    //PRINT "dig_H4="; dig_H[3]; "\n"
    
    dig_H[4] = to_SInt32((work[4] >> 4) + work[5] * 16, 0x800) // ビット演算を()で囲む必要あり
    //PRINT "dig_H5="; dig_H[4]; "\n"
    
    dig_H[5] = to_SInt32(work[6], 0x80)
    //PRINT "dig_H6="; dig_H[5]; "\n"
    
    // 気圧 ----------------------------------------------------------------
    DIM nRegAddrP : nRegAddrP = 0x8e // 先頭アドレス
    FOR i = 0 to 16 STEP 2
        rc = I2cReadReg8(nSlaveAddr, nRegAddrP + i, work[0])
        PRINT "work[0]="; work[0]; ", "
        rc = I2cReadReg8(nSlaveAddr, nRegAddrP + i + 1, work[1])
        PRINT "work[1]="; work[1]; "\n"
        
        dig_P[i / 2] = ((work[1] << 8) | work[0])
        
        IF i != 0 THEN
            dig_P[i / 2] = to_SInt32(dig_P[i / 2], 0x8000)
        ENDIF
        
        PRINT "dig_P"; i / 2 + 1; "="; dig_P[i / 2]; "\n"
    NEXT

ENDFUNC 0

2.4 温度を取得する関数

// 温度
FUNCTION get_temperature() AS FLOAT

    DIM nRegAddr: nRegAddr = 0xfa // 温度
    DIM adc1 AS INTEGER
    DIM adc2 AS INTEGER
    DIM adc3 AS INTEGER
    DIM var1 AS FLOAT
    DIM var2 AS FLOAT
    DIM var21 AS FLOAT
    DIM T AS FLOAT
    DIM adc_T AS FLOAT
    
    // 読み出し
    // 0xfa - 0xfcの3バイトに格納されている
    // ビッグエンディアンなので8ビットずつ読みだして結合
    rc = I2cReadReg8(nSlaveAddr, nRegAddr, adc1)
    //PRINT "adc1="; adc1; "\n"
    rc = I2cReadReg8(nSlaveAddr, nRegAddr + 1, adc2)
    //PRINT "adc2="; adc2; "\n"
    rc = I2cReadReg8(nSlaveAddr, nRegAddr + 2, adc3)
    //PRINT "adc3="; adc3; "\n"
    
    // FLOAT化
    adc_T = adc1 * 256 * 16.0 + adc2 * 16.0 + adc3 / 16.0 // 20ビット化
    //PRINT "adc_T="; adc_T; "\n"

    var1 = (adc_T / 16384.0 - dig_T[0] / 1024.0) * dig_T[1]
    //PRINT "var1="; var1; "\n"
    
    var21 = (adc_T / 131072.0 - dig_T[0] / 8192.0) * (adc_T / 131072.0 - dig_T[0] / 8192.0)
    //PRINT "var21="; var21; "\n"
    
    var2 = var21 * dig_T[2]
    //PRINT "var2="; var2; "\n"
    
    t_fine = var1 + var2
    PRINT "t_fine="; t_fine; "\n"
    
    T = t_fine / 5120.0
    //PRINT "T="; T; "\n"
    
ENDFUNC T

2.5 湿度を取得する関数

FUNCTION get_humidity() AS FLOAT

    DIM nRegAddr: nRegAddr = 0xfd
    DIM H AS FLOAT
    DIM var_H AS FLOAT
    DIM var_H1 AS FLOAT
    DIM var_H2 AS FLOAT
    DIM var_H3 AS FLOAT
    DIM adc_H AS FLOAT
    DIM adc1 AS INTEGER
    DIM adc2 AS INTEGER
    
    // 読み出し
    // 0xfa - 0xfcの3バイトに格納されている
    // ビッグエンディアンなので8ビットずつ読みだして結合
    rc = I2cReadReg8(nSlaveAddr, nRegAddr, adc1)  
    //PRINT "adc1="; adc1; "\n"
    rc = I2cReadReg8(nSlaveAddr, nRegAddr + 1, adc2)
    //PRINT "adc2="; adc2; "\n"
    
    adc_H = adc1 * 256.0 + adc2 // ビッグエンディアン
    //PRINT "adc_H="; adc_H; "\n"
    
    var_H = t_fine - 76800.0
    var_H1 = dig_H[3] * 64.0 + dig_H[4] / 16384.0 * var_H
    var_H2 = 1.0 + dig_H[2] / 67108864.0 * var_H
    var_H3 = 1.0 + dig_H[5] / 67108864.0 * var_H * var_H2
    var_H = (adc_H - var_H1) * dig_H[1] / 65536.0 * var_H3
    H = var_H * (1.0 - dig_H[0] * var_H / 524288.0)
    
    IF H > 100.0 THEN
        H = 100.0
    ELSEIF H < 0.0 THEN
        H = 0.0
    ENDIF
    
    //PRINT "H="; H; "\n"

ENDFUNC H

2.6 気圧を取得する関数

苦戦中。。。以下、正しく算出できない。

// 気圧
FUNCTION get_pressure() AS FLOAT

    DIM nRegAddr : nRegAddr = 0xf7
    DIM var1 AS FLOAT
    DIM var2 AS FLOAT
    DIM P AS FLOAT
    DIM adc1 AS INTEGER
    DIM adc2 AS INTEGER
    DIM adc3 AS INTEGER
    DIM adc_P AS FLOAT
    //DIM adc_P AS INTEGER
    
    // 読み出し
    // 0xf7 - 0xf9の3バイトに格納されている
    // ビッグエンディアンなので8ビットずつ読みだして結合
    rc = I2cReadReg8(nSlaveAddr, nRegAddr, adc1)  
    PRINT "adc1="; adc1; "\n"
    
    rc = I2cReadReg8(nSlaveAddr, nRegAddr + 1, adc2)   
    PRINT "adc2="; adc2; "\n"
    
    rc = I2cReadReg8(nSlaveAddr, nRegAddr + 2, adc3)
    //PRINT "adc3="; adc3; "\n"
    
    adc_P = adc1 * 256 * 16.0 + adc2 * 16.0 + adc3 / 16.0 // 20ビット化
    PRINT "adc_P="; adc_P; "\n"
    
    var1 = t_fine / 2.0 - 64000.0
    
    var2 = var1 * var1 / 32768.0 * dig_P[5]
    
    var2 = var2 + var1 * dig_P[4] * 2.0
    
    var2 = var2 / 4.0 + dig_P[3] * 65536.0
    
    var1 = dig_P[2] / 524288.0 * var1 * var1 + dig_P[1] / 524288.0 * var1
    
    var1 = (1.0 + var1 / 32768.0) * dig_P[0]
    
    IF var1 == 0.0 THEN
        P = 0
    ELSE
        P = 1048576.0 - adc_P
        
        P = (P - var2 / 4096.0) * 6250 / var1
        
        var1 = dig_P[8] * P * P / 2147483648.0
        
        var2 = P * dig_P[7] / 32768.0
        
        P = P + (var1 + var2 + dig_P[6]) / 16.0
    ENDIF
    
    P = P / 100.0 // 単位は[Pa]なので[hPa]に直す
    
ENDFUNC P

2.7 タイマーイベントのハンドラ関数

// 一定周期で実行
FUNCTION HandlerTimer0()

    DIM T AS FLOAT
    DIM H AS FLOAT
    DIM P AS FLOAT
    
    // 温度, 湿度, 気圧を計測
    T = get_temperature()
    H = get_humidity()
    P = get_pressure()

    PRINT "Temperature="; T; "\n"
    PRINT "Humidity="; H; "\n"
    PRINT "Pressure="; P; "\n"

ENDFUNC 1 //remain blocked in WAITEVENT

2.8 メイン処理

DIM handle
DIM rc

// オープン
rc = I2cOpen(400 * 1000, 0, handle)

// 初期設定
DIM x: x = INIT_BME280()

// キャリブレーションデータの読み出し
x = READ_TRIM()

// 計測タイマー
ONEVENT EVTMR0 CALL HandlerTimer0
TimerStart(0, 1000, 1) //start a 500 millisecond recurring timer

// クローズ
//I2cClose(handle)

// 計測待ち
WAITEVENT


3. 動作確認

UwTerminalXにて、結果を表示し、ひとまず温度、湿度は正しく表示されることを確認できた。



まとめと今後の課題

BL652でBME280とI2Cで通信し、計測値を取得することができた。(ただし、気圧はうまくいっていない)次回は、BLEのアドバタイズに載せて飛ばしてみたいと思う。


BLEモジュール BL652ブレイクアウトボードで遊ぶ(2) --- アドバタイズ ---

概要

BL652ブレイクアウトボードで、アドバタイズを飛ばしてスマホで受信してみた。



背景と目的

前回、BL652ブレイクアウトボードを使うための開発環境を整え動作を確認した。今回は、実用を想定してアドバタイズでデータを飛ばしスマホで受信できるか試す。



詳細

0. 実施環境と参考情報


1. アドバタイズの仕様

Flags、デバイス名、任意データの3種類で構成し、トータルは31バイト。任意データの部分はBL652につないだセンサ値などを入れることでセンサ値を飛ばせる想定だが、今回は動作確認なので適当な値を入れる。

  • AD Structure1
    • Length: 2バイト(0x02)
    • AD Type: Flags(0x01)
    • Flags: LE Limited Discoverable Mode + BR/EDR Not Supported(0x04)
  • AD Structure2
    • Length: 9バイト(0x09)
    • AD Type: Complete Local Name(0x09)
    • Complete Local Name: 8バイト('My BL652')
  • AD Structure3
    • Length: 17バイト(0x11)
    • AD Type: Manufacture Specific(0xFF)
    • Manufacture Specific: 16バイト(0x00~0x0Fまで1ずつ増やす)

※LE Limited Discoverable Modeについての参考

  • LE Limited Discoverable Mode
  • LE General Discoverable Mode


2. コーディング

BL652は、smartBASICという言語でコーディングするのだが、何しろLaird Technology社デバイス用のものなので、Web上の情報は公式資料以外ほぼ皆無。とはいえ、基本はBASICなので、一応VBAを使ってきた経験が役立ちそうな感じ。

というわけで、一から調べると大変なのでサンプルを探したところ、Laird Technology社がgithub公開しているサンプルがあり、その中のBleAdvertStart.sbがちょうどよかったので参考にコーディングしてみた。

動作としては、1分間所定のアドバタイジングパケットを吹くだけ。

DIM addr$ : addr$ =""
DIM scnRpt$ : scnRpt$ =""
DIM advRpt$ : advRpt$ =""
DIM rc

// アドバタイズタイムアウトのイベントハンドラ
FUNCTION HndlrBlrAdvTimOut() 
   PRINT "\nAdvert stopped via timeout"
   PRINT "\nExiting..."
ENDFUNC 0

// デバイス名の設定
// GAP serviceの初期化関数で設定する
DIM deviceName$, nameWritable, nAppearance, nMinConnInterval, nMaxConnInterval, nSupervisionTimeout, nSlaveLatency
deviceName$ = "My BL652" // デバイス名
nameWritable = 0 // nameWritable
nAppearance = 768 // デバイスの種類(768: 温度計)
nMinConnInterval = 500000 // min_conn_interval
nMaxConnInterval = 1000000 // max_conn_interval
nSupervisionTimeout = 4000000 // supervision timeout
nSlaveLatency = 0 // slave latency
rc = BleGapSvcInit(deviceName$, nameWritable, nAppearance, nMinConnInterval, nMaxConnInterval, nSupervisionTimeout, nSlaveLatency)
PRINT "--- New DevName : "; BleGetDeviceName$(); "\n"

// 初期化
DIM discovMode : discovMode = 0 // 
DIM nFlagsAD: nFlagsAD = 0 // 0はFlags=0x04(LE Limited Discoverable Mode + BR/EDR Not Supported)に相当
DIM nAdvAppearance : nAdvAppearance = 0 // Appearance: 0=省略, 1=表示
DIM nMaxDevName : nMaxDevName = 8 // デバイス名(ShortLocalName or CompleteLocalName)の表示バイト数
IF BleAdvRptInit(advRpt$, nFlagsAD, nAdvAppearance, nMaxDevName) == 0 THEN
    PRINT "Advert report initialised\n"
ENDIF

// 追加データ
DIM nTag : nTag = 0xFF
DIM stData$ : stData$="\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F"
IF BleAdvRptAppendAD(advRpt$, nTag, stData$) == 0 THEN
    PRINT "AD with data '";stData$;"' was appended to the advert report\n"
ENDIF

// 確定させる
PRINT BleAdvRptsCommit(advRpt$, scnRpt$)

PRINT "advRpt="; advRpt$; "\n"

// アドバタイズ開始
DIM nAdvType: nAdvType = 3 // 3=ADV_NONCONN_IND=アクティブスキャン拒否, 接続拒否
DIM nAdvInterval: nAdvInterval = 1000 // アドバタイズ周期: 1000msec
DIM nAdvTimeout: nAdvTimeout = 60000 // アドバタイズタイムアウト: 60sec
DIM nFilterPolicy: nFilterPolicy = 0 // 0=ホワイトリスト無効
IF BleAdvertStart(nAdvType, addr$, nAdvInterval, nAdvTimeout, nFilterPolicy) == 0 THEN    
    PRINT "Adverts Started\n"                  
    PRINT "If you search for bluetooth devices on your device, you should see '"; deviceName$; "'\n"
ELSE                                          
    PRINT "\nAdvertisement not successful\n"
ENDIF

// イベント設定
// アドバタイズタイムアウトを設定
ONEVENT  EVBLE_ADV_TIMEOUT  CALL HndlrBlrAdvTimOut

// イベント待ち
WAITEVENT


3. 動作確認

スマホのLightBlueを立ち上げ、スキャンしてみるとデバイスが見つかった。Complete Local Nameが正しく表示されている。詳細なパケットも、以下のように正しく吹かれている。

f:id:dekuo-03:20211007012946p:plain



まとめと今後の課題

BL652ブレイクアウトボードで、アドバタイズを飛ばすことができた。次回は、 、BL652にセンサをつないでセンサ値を飛ばしたい。


わけぎを育てる(2) --- 植え付け ---

概要

わけぎの球根の植え付けを行った。



背景と目的

前回準備したプランターに、球根の植え付けを行う。



詳細

1. 球根

見た目は以下。大きさはニンニクの1片で、外皮は玉ねぎのような感じ。

f:id:dekuo-03:20210926172505j:plain


2. 植え付け

5cm間隔で、1か所当たり3個を4か所植えた。球根の先端が少しだけ出る程度の深さ。

f:id:dekuo-03:20210926172446j:plain


3. 水やり

とりあえず、水をやっておく。芽が出てくるまでおよそ3週間程度らしいので、自動水やり器で潅水しながら気長に待つ。


4. その後(追記)

1か月近く経っても発芽せず、気になって球根を掘り出してみたところ腐ってしまっていた。原因として考えられるのは、

  • 日当たりが悪かった
    • 夏場に設置した日除けシートを設置したままにしていてプランターが陰に隠れる時間が長かった → シーズンが終わったらちゃんと外すべき
    • 9月末~10月は例年よりも寒い日も多かった → 日当たりの悪さが尚更堪えた?
  • 植え付けの時期が少し遅い
    • 9月末は植え付けシーズンの最終盤だが、例年より寒かったせいで実質的に時期を外した気がする

と思われた。というわけで、今シーズンのわけぎの栽培は失敗に終わったので、来年は反省を生かしたい。



まとめと今後の課題

わけぎの球根の植え付けを行った。ちゃんと芽が出ることを願う。


BLEモジュール BL652ブレイクアウトボードで遊ぶ(1) --- 開発環境整備と動作確認 ---

概要

BLEモジュール BL652のブレイクアウトボードで開発環境整備とサンプルプログラム動作確認を行った。



背景と目的

最近、センサデータをBLEで飛ばすため(ビーコンのように定期的にアドバタイズできれば十分)手持ちのESP32を使うことを検討したのだが、色々調べるうちにスリープ復帰時の電力ロス的に電池の持ちがよくなさそうなので専用デバイスを使ったほうがよさそうだと思った。そこで、安価に手に入り開発環境をそろえるのも容易なものがないか探したところ、

akizukidenshi.com

が見つかった。特徴としては、

  • 約1200円で開発ボードが手に入る
  • 入出力も豊富
    • GPIOたくさん
    • SPI/I2C各1系統
    • ADC8ch
    • 他、NFCなど?
  • プログラミングは独自言語だがそんなに複雑でなさそう

という感じ。 そこで、BL652を使って簡単なセンサデータをBLEで飛ばせるように環境整備とサンプルプログラムの動作確認を行う。

※4,5年前にも同じような感じで遊ぼうと思っていろいろ探したが、もっと高くて、入出力も限られたものしか見つからなかった気がする。なので、最近は充実してきたんだなあと、感じている。



詳細

0. 実施環境


1. プログラム書き込みツール UwTerminalXを準備

下記から、UwTerminalX_v1.12a_Windows.zipをダウンロードして任意の場所に解凍するだけでOK。

github.com


2. サンプルプログラムの書き込み

  • ボードとUSBシリアル変換を接続する。

    • TX
    • RX
    • GND
  • 次に、ボードに電源をつなぐ。

    • 5V
    • GND
  • UwTerminalX.exeを起動し、Configタブでシリアルが認識されていることを確認。TX、RX、GNDしかつながないので、HandshakingはXon/Xoffを選択。ボーレートは115200bps。

f:id:dekuo-03:20210925151643p:plain

  • ここで、ブレイクアウトボードボードのRESETボタンを押す。

  • 次に、Terminalタブに移動し、右上のOpen Portボタンを押す。

f:id:dekuo-03:20210925144334p:plain

  • 黒い部分で右クリックし、XCompile + Load + Run を選択すると、ファイル選択画面が出るので、led_btn_sample.sbを選択。以下のような表示が出ればOK。

f:id:dekuo-03:20210925151913p:plain


3. 動作確認

ボタン1,2を押すとそれぞれLED1,2が点灯するだけ。正常に動作した。



まとめと今後の課題

BL652のブレイクアウトボードの環境整備とプログラム動作確認ができた。次は、自分でプログラムを書いてみたい。