https://kojinteki.net/2023/11/18/arduino-uno-r4-wifi-https/を参考にmysiteをゲットした
2025年5月31日土曜日
UnoR4Tutorial-2:https page get
2025年5月29日木曜日
BLE5 on raspicow receiver using aioble(わかりやすい)
https://qiita.com/_53a/items/39d6bfd38c538d6a3c94 ble5でうごいた
このコードはaiobleをつかっているので直感的、普通につかうならこっちか。。。
import asyncio
import aioble
import bluetooth
# mimicking nRF41822 UART
SERVICE_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
service = aioble.Service(SERVICE_UUID)
send_ch = aioble.Characteristic( #このchに送ると通信元にreadされた!
service = service, # 下のuuidはSERVICE_UUIDではない!注意!
uuid = bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'),
read = True,
notify = True,
)
recv_ch = aioble.Characteristic( # 通信元が、このchに送るとwrittenになる!
service=service, # 下のuuidはSERVICE_UUIDではない!注意!
uuid=bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'),
write=True,
write_no_response=True,
capture=True
)
aioble.register_services(service)
async def advertise_task():
while True:
async with await aioble.advertise(
interval_us=500_000,
name="bt-test", # サービス名
services=[SERVICE_UUID]
) as connection: # type: ignore
print("connected: ", connection.device)
await connection.disconnected(timeout_ms=None) #時間切れなし?
async def receive_task(): # 通信元からのメッセージを読んで送り返す
while True:
await recv_ch.written() # type: ignore
data = recv_ch.read()
print(f"received: {data}")
# ここで一仕事できるはず
send_ch.write(b'you said: ' + data, True)
async def main():
tasks = [
asyncio.create_task(receive_task()),
asyncio.create_task(advertise_task())
]
await asyncio.gather(*tasks)
asyncio.run(main())
2025年5月28日水曜日
BLE5! raspicow 温度情報のsender!
https://tech-and-investment.com/raspberrypi-picow-10-bluetooth1/
writeで述べたようにraspicow はble4のはずだが、
本コードはble5対応のlight blueでないとよめない 。。。。理由不明
import bluetooth
import random
import struct
import time
import machine
import ubinascii
from ble_advertising import advertising_payload
from micropython import const
from machine import Pin
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_INDICATE_DONE = const(20)
_FLAG_READ = const(0x0002)
_FLAG_NOTIFY = const(0x0010)
_FLAG_INDICATE = const(0x0020)
# 温度情報サービスのUUIDの定義です
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
#
# 特徴(Characteristic)を設定するタプルです。
# TypeのUUIDと、Permissionのフラグを設定しています
#
_TEMP_CHAR = (
bluetooth.UUID(0x2A6E),
_FLAG_READ | _FLAG_NOTIFY | _FLAG_INDICATE,
)
#
# サービスを設定するタプルです
# サービスの定義(Declaration)のTypeに設定するUUIDと
# 上記で作成した特徴(Characteristic)をセットしています。
#
_ENV_SENSE_SERVICE = (
_ENV_SENSE_UUID,
(_TEMP_CHAR,),
)
#
# ペリフェラルの分類を示す定数です、温度センサの値である768を使用します。
#
_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)
#
# Picoの温度情報を配信するペリフェラルのクラスです
#
class BLETemperature:
def __init__(self, ble, name=""):
# 温度センサに使うピンを設定します。
self._sensor_temp = machine.ADC(4)
# 呼び出し元から渡された、BLE用のオブジェクトをクラス内部にセットし、
# BLEを有効化します。
self._ble = ble
self._ble.active(True)
# ライブラリから呼び出してもらう関数をセットします。
self._ble.irq(self._irq)
# ライブラリにサービスをセットします。
# 戻り値のうち、_TEMP_CHARへのハンドルのみをメンバ変数に取得しています。
((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,))
# 配列をset関数で初期化します
self._connections = set()
# サービスの名前が指定されていない場合は、MACアドレスの名前を使用します。
if len(name) == 0:
name = 'Pico %s' % ubinascii.hexlify( self._ble.config('mac')[1],':').decode().upper()
print('Sensor name %s' % name)
# サービスの名前とオブジェクトを指定して、
# アドバタイズするデータ(ペイロード)を作成します
self._payload = advertising_payload(
name=name, services=[_ENV_SENSE_UUID]
)
# アドバタイズを行います
self._advertise()
#
# ライブラリから呼び出してもらう関数の定義です
#
def _irq(self, event, data):
# セントラルからの接続時は、その接続ハンドルを自身のリストに追加します
if event == _IRQ_CENTRAL_CONNECT:
conn_handle, _, _ = data
self._connections.add(conn_handle)
# セントラルからの切断時は、自身のリストから接続ハンドルを削除し、
# 停止していたアドバタイズを再開します。
elif event == _IRQ_CENTRAL_DISCONNECT:
conn_handle, _, _ = data
self._connections.remove(conn_handle)
self._advertise()
# Indicateの完了を受け取った時は、接続状態、値のハンドル、ステータスのハンドルを取得します。
elif event == _IRQ_GATTS_INDICATE_DONE:
conn_handle, value_handle, status = data
#
# 温度センサの値を更新して、notify/indicateを行う関数です
#
def update_temperature(self, notify=False, indicate=False):
# 温度センサから温度を取得・表示します
temp_deg_c = self._get_temp()
print("write temp %.2f degc" % temp_deg_c);
# キャラクタリスティック内の温度情報を更新します。
self._ble.gatts_write(self._handle, struct.pack("<h", int(temp_deg_c * 100)))
print("temp "+ str(int(temp_deg_c * 100)))
# 自身で保持している全ての接続ハンドル(セントラル)に対して、notify/indicateを行います
if notify or indicate:
for conn_handle in self._connections:
if notify:
self._ble.gatts_notify(conn_handle, self._handle)
if indicate:
self._ble.gatts_indicate(conn_handle, self._handle)
# 自身で保持しているペイロードをセットしてアドバタイズする関数です
def _advertise(self, interval_us=500000):
self._ble.gap_advertise(interval_us, adv_data=self._payload)
# pico W本体の温度センサの値を取得して、電圧->温度に変換する関数です
def _get_temp(self):
conversion_factor = 3.3 / (65535)
reading = self._sensor_temp.read_u16() * conversion_factor
return 27 - (reading - 0.706) / 0.001721
# メインの処理です
def demo():
# bleライブラリのオブジェクト(変数)を作成します
ble = bluetooth.BLE()
# ペリフェラルのオブジェクト(変数)を作成します
temp = BLETemperature(ble)
# Pico本体のLEDのピンを取得します
counter = 0
led = Pin('LED', Pin.OUT)
# 10秒に1回、温度センサの値を取得して、notifyします
# LEDは1秒ごとにON/OFFを繰り返します.
while True:
if counter % 10 == 0:
temp.update_temperature(notify=True, indicate=False)
led.toggle()
time.sleep_ms(1000)
counter += 1
if __name__ == "__main__":
demo()
BLE5 on raspberry pi (sender) receiver not yet
https://greenlion994.sakura.ne.jp/embedded/2022/08/009-2/ echo ...
---------------------------------------------------
https://qiita.com/comachi/items/c494e0d6c6d1775a3748
python 3 code as data sending peripheral
from pybleno import *
bleno = Bleno()
APPROACH_SERVICE_UUID = '13A28130-8883-49A8-8BDB-42BC1A7107F4'
APPROACH_CHARACTERISTIC_UUID = 'A2935077-201F-44EB-82E8-10CC02AD8CE1'
class ApproachCharacteristic(Characteristic):
def __init__(self):
Characteristic.__init__(self, {
'uuid': APPROACH_CHARACTERISTIC_UUID,
'properties': ['read', 'notify'], #読まれるだけのキャラクタ
'value': None
})
self._value = str(0).encode()
self._updateValueCallback = None
def onReadRequest(self, offset, callback):
print('ApproachCharacteristic - onReadRequest')
callback(result=Characteristic.RESULT_SUCCESS, data=self._value)
def onSubscribe(self, maxValueSize, updateValueCallback):
print('ApproachCharacteristic - onSubscribe')
self._updateValueCallback = updateValueCallback
def onUnsubscribe(self):
print('ApproachCharacteristic - onUnsubscribe')
self._updateValueCallback = None
def onStateChange(state):
print('on -> stateChange: ' + state)
if (state == 'poweredOn'):
bleno.startAdvertising(name='Approach', service_uuids=[APPROACH_SERVICE_UUID])
else:
bleno.stopAdvertising()
bleno.on('stateChange', onStateChange)
approachCharacteristic = ApproachCharacteristic()
def onAdvertisingStart(error):
print('on -> advertisingStart: ' + ('error ' + error if error else 'success'))
if not error:
bleno.setServices([
BlenoPrimaryService({
'uuid': APPROACH_SERVICE_UUID,
'characteristics': [
approachCharacteristic
]
})
])
bleno.on('advertisingStart', onAdvertisingStart)
bleno.start()
import time
counter = 0
def task():
global counter
counter += 1
approachCharacteristic._value = str(counter).encode()
if approachCharacteristic._updateValueCallback:
print('Sending notification with value : ' + str(approachCharacteristic._value))
notificationBytes = str(approachCharacteristic._value).encode()
approachCharacteristic._updateValueCallback(data=notificationBytes)
while True:
task()
time.sleep(1)
2025年5月27日火曜日
Raspberry PiでWebSocket|Lチカ、WebSocketの理解
https://tomono.tokyo/2021/03/26/9556/はubuntuにws_serverをインストする覚書
https://araisun.com/raspberry-pi-websocket.html
led-switch-server.py::
import RPi.GPIO as GPIO
from time import sleep
from websocket_server import WebsocketServer
LED = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
def receivedMessage(client, server, message):
print(message)
if message == 'led_on':
GPIO.output(LED, True)
elif message == 'led_off':
GPIO.output(LED, False)
else:
print("Unknown Message: {}".format(message))
server = WebsocketServer(5555, host="192.168.42.123")
server.set_fn_message_received(receivedMessage)
# https://www.raspberrypirulo.net/entry/websocket-server に上記関数の説明あり
server.run_forever()
-------index.html----------------------------------------------
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<script>
$(function () { //https://qiita.com/bakatono_super/items/fcbc828b21599568a597
var ws = new WebSocket("ws://192.168.42.123:5555/");
$('#btn').on('click', function () {
if($('#btn').text() == "OFF") {
$('#btn').text("ON")
ws.send('led_on');
} else {
$('#btn').text("OFF")
s.send('led_off');
}
});
})
</script>
<style>
#btn{
width: 500px;
height:200px;
font-size:100px;
}
</style>
</head>
<body>
<button id="btn">OFF</button> // 最初はoffでスタート
</body>
</html>
BLE5 on raspicow (ble5 in raspico2w!) receiver!(no-aioble)
https://xtech.nikkei.com/atcl/nxt/column/18/02584/のなかの
https://xtech.nikkei.com/atcl/nxt/column/18/02584/091900003/
にある以下の題目について学習した
「超小型ラズパイ「Pico W」でBluetooth通信、PCで情報を受け取ってみよう」
ble_test_led.py :: changeをうけとるとbuiltin ledがトグル操作される
-------------- code is below (main.py とも言える) in picow -------------------
from machine import Pin
import bluetooth
from ble_simple_peripheral import BLESimplePeripheral
#ble_simple_peripheralがadverting.pyを起動する仕様
BLE_NAME = "picow"
ble = bluetooth.BLE()
sp = BLESimplePeripheral(ble, name=BLE_NAME )
led = Pin("LED", Pin.OUT)
state_led = 0
def on_rx( data ):
print( f"Received Data: {data}" )
global state_led
if( data == b'change' ):
# androi app :: serial bluetooth terminal use ble4! ただし\r\nもはいって
# 送られるので上記のchangeはchagen\r\nにする必要がある(settingめんど)
if( state_led == 0 ):
state_led = 1
led.value( state_led )
sp.send( "LED ON" )
else:
state_led = 0
led.value( state_led )
sp.send( "LED OFF" )
while True:
if( sp.is_connected() ):
sp.on_write( on_rx )
2025年5月26日月曜日
Ble5 using Arduino Uno R4 WiFI receiver(sender not yet)
SubscribeとReadは、データの受信方法に関する重要な違いです。Subscribeは、デバイスが特定の特性の値が変更されたときに自動的に通知を受け取る方法であり、Readは、必要に応じて手動でデバイスからデータを読み取る方法です。Subscribe(通知/Indication/Notification):- デバイスが特定の特性の値が変更されたときに、自動的に通知を受け取ります。
- セントラルデバイスがサブスクライブすると、ペリフェラルデバイスは、その特性の値が変更されるたびに通知を送ります。
- 通知の種類として、
NotificationとIndicationがあり、Indicationは受信確認(ACK)を要求するのに対し、Notificationは要求しません。 - 受信確認を要求する
Indicationは、データの送信完了を保証するために使用されます。
Read(読み取り):- セントラルデバイスが、必要に応じてデバイスからデータを読み取ります。
Readは、特定の特性の値を取得するために、デバイスに読み取り要求を送信します。Readは、データが変更されたかどうかに関わらず、必要な時にデータの状態を読み取ることができます。
- セントラルがペリフェラルに直接データを送る。
- データの読み込みや変更をセントラル側で行う際に利用される。
- ペリフェラル側で何か設定を変更したり、データを記録したりする場合に便利。
- ペリフェラルがセントラルにイベントやデータの変更を知らせる。
- 例えば、温度センサーが温度が変わった場合に、セントラルに通知を送るなど。
- セントラル側でリアルタイムなデータの監視や、イベントに応じた処理を行う場合に便利。
- Writeはセントラルからペリフェラルへの一方的なデータ送信。
- Notifyはペリフェラルからセントラルへのイベントや変更の通知。
- Notifyには、レスポンスが必要な「Indicate」とレスポンスが不要な「Notify」があります。
- BLEでは、これらの「Write」や「Notify」を組み合わせることで、様々なアプリケーションを実現できます。
- IndicateとNotifyの違い
- Indicate:
- データの送信後、セントラルデバイスが受信確認を返信し、受信確認が返信されるまで次のデータ送信に進まない。
- Notify:データの送信後、セントラルデバイスからの受信確認を待たずに次のデータ送信に進む。
Indicateは、データの正確な転送が重要となるアプリケーションにおいて、Notifyよりも適しています。例えば、スマートホームデバイスのステータス情報や、センサーデータの通知など、データの損失が許されない場合にIndicateが用いられます。Indicateは、CCCD (Client Characteristic Configuration Descriptor)という特別なDescriptorを使い、セントラルデバイスがIndicateを購読しているかどうかを管理します。- ^^^^^^^^^^^^^^^^^^^^^^
- esp32もそうだし、micropythn-picowもそうだとおもうがbluetoot serial terminal