見出し画像

月額料金不要!徘徊者本人に行くべき道をこっそり教えるミニモニター(試作機)

認知症などで現在地点が判らないため、自宅や駅に戻れず、徘徊してしまう人年間1万7千人以上いるそうです

NHKスペシャルで、徘徊者本人へのインタビューにおいて、徘徊時にどの方向へ行けばいいのか、判らないけど、来た方向に戻るのは、負けた気がするので突き進んでしまうとのことです

車や自転車を使っての徘徊では、更に行動範囲が広がってしまい、本人を探し出すのは、かなりの苦労となってしまいます

更に車や自転車を置いた事や場所を忘れてしまい、何か月も見つからず、放置されていたこともあります
トイレに行くために、置いた後には、もう綺麗さっぱり、失念しちゃうようです

放置された車や自転車であればiPhoneの普及率の高い日本ではair tagN tagなどを仕込んでおけば、後からでも探せるかと思います

しかし、徘徊者本人がスマートフォンを使って地図アプリでサクサク移動なんて期待するのは無謀かと思います

そこでスマホのように公衆回線を使用することなく、タブレットケースサイズで電源を入れれば、自動的に進むべき先を示す装置を試作してみました

腕時計を貸したら、外し方が判らず、ハサミで壊されたこともあるので、複雑な機能は、一切省きます

電源スイッチ以外は、付けません

目的地登録ボタンなんて、付けてしまったら、間違ってリセットされて、一巻の終わりです

あえて徘徊者のために、何回、再起動しても同じ機能を提供します

頭脳の処理装置としては格安でデバイス処理との相性の良い、Paspberry Pi Pico Wを使います

座標の取得にはGPSモジュールを使います

計算結果はOLED(Organic Light-Emitting Diode)ディスプレイを使います

完成サイズフリスクケースとか社員証くらいの大きさにできるかと思います

今回は試作機のため、ブレッドボード上に動作環境を構築しました

ブレッドボードは電子部品をはんだ付けせずに接続し、回路を作ることができます

無数の穴があり、それぞれが規則性を持ったパターンでつながっています

USB端子経由で電源を供給し、他のパーツはブレッドボード経由で電源を供給されるので配線が簡単になります

各パーツはジャンパーワイヤーをブレッドボード経由で接続するので試作機の作成には最適の手法かと思います


自宅からの距離を常時表示し、1秒毎に更新

↑ 早速ラズベリーパイもどきでも動作しました(ソースコピーと別GPSモジュールでの動作確認)

自宅の緯度経度を表示


ミニモニターの拡大図

GPSモジュール、OLEDディスプレイともに4本ケーブルのみ使用なので簡単に再現可能と思います

GPSモジュールは、電源、グランド、RX、TXの4本と別途専用のアンテナ線をつなぎます
OLEDディスプレイは、電源、グランド、VCC、SCLの4本をつなぎます

GPSモジュールとOLEDモジュールの36番3.3Vにつながるブレッドボード経由で電源を取得します

それぞれのグランドは38番GNDにブレッドボード経由で接続します

GPSモジュールのRX7番GPIO8UART0 TXに接続します
受信だから送信側に接続すると考えると判りやすいかと思います

GPSモジュールのTX6番GPIO9UART0 RXに接続します
逆に送信だから受信側に接続すると考えると判りやすいかと思います

GNSS(全地球測位システム)は、みちびきに対応したモジュール(順天頂衛星システム(QZSS))だと誤差は20cmと高精度が期待できるそうです

通信方式はUART方式で9600ボーで転送される文字情報から文字列分割して、緯度経度や時刻、スピードが取得できます

時刻は標準時刻で取得できるので、タイムゾーンに9時間を指定して日本時刻を取得します

最初は自宅位置をGPSで取得するため、受信情報をそのまま表示するプログラムを実行させます

そこで取得された情報を撮影しておき、目的地として記録しておきます
iPhoneで動画撮影しておくと、その後作るプログラムの目的地として、緯度経度を使えます

目的地とGPSモジュールが取得した現在地から2点間の距離をKm単位で表示させます
計算は、地球の表面を沿った距離を大円距離として計算します

1秒間隔のリアルタイムで自宅までの距離情報を表示させますので、自宅まで遠のいているのか、近づいているのか、徘徊者本人に判断可能な情報を提供する訳です

認知症の人は、言われたことなどは、すぐに忘れてしまいますが、手元にある情報からは判断できるようなので、歩く度に自宅までの表示距離が変わることから行くべき方向の手助けになるかと思います

歩く度に代わる、自宅まであと何Kmと表示される距離情報から進むか、戻るか判断可能かと思います

ソースの管理にはThonnyというツールが便利です
PCとPaspberry Pi Pico WをUSBケーブルで接続しプログラムソースを操作可能です
Paspberry Pi Pico Wをリブートしたり便利です

GPSモジュールから受信した情報から、緯度経度、スピード、時刻、日付を表示するmain.pyはこんな感じのソースになります
これで自宅の緯度経度が取得できます

from machine import Pin, UART, I2C
#Import utime library to implement delay
import utime, time

#________________________________________________________
from ssd1306 import SSD1306_I2C
#https://github.com/stlehmann/micropython-ssd1306
#________________________________________________________
from micropyGPS import MicropyGPS
#https://github.com/inmcm/micropyGPS
#________________________________________________________

##########################################################
#Oled I2C connection
i2c=I2C(0, sda=Pin(8), scl=Pin(9), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
##########################################################

##########################################################
#GPS Module UART Connection
gps_module = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
##########################################################


##########################################################
TIMEZONE = 5
my_gps = MicropyGPS(TIMEZONE)
##########################################################

##########################################################
def convert(parts):
    if (parts[0] == 0):
        return None
        
    data = parts[0]+(parts[1]/60.0)
    # parts[2] contain 'E' or 'W' or 'N' or 'S'
    if (parts[2] == 'S'):
        data = -data
    if (parts[2] == 'W'):
        data = -data

    data = '{0:.6f}'.format(data) # to 6 decimal places
    return str(data)
##########################################################

##########################################################
while True:
    #_________________________________________________
    #print(i2c.scan())
    length = gps_module.any()
    if length>0:
        b = gps_module.read(length)
        for x in b:
            msg = my_gps.update(chr(x))
    #_________________________________________________
    latitude = convert(my_gps.latitude)
    longitude = convert(my_gps.longitude)
    #_________________________________________________
    if (latitude == None and latitude == None):
        oled.fill(0)
        oled.text("No Data", 0, 0)
        oled.show()
        continue
    #_________________________________________________
    t = my_gps.timestamp
    #t[0] => hours : t[1] => minutes : t[2] => seconds
    gpsTime = '{:02d}:{:02d}:{:02}'.format(t[0], t[1], t[2])
    
    gpsdate = my_gps.date_string('long')
    speed = my_gps.speed_string('kph') #'kph' or 'mph' or 'knot'
    #_________________________________________________
    print('Lat:', latitude)
    print('Lng:', longitude)
    #print('time:', gpsTime)
    #print('Date:', gpsdate)
    #print('speed:', speed)  
    #_________________________________________________
    oled.fill(0)
    oled.text('Lat:'+ latitude, 0, 0)
    oled.text('Lng:'+ longitude, 0, 12)
    oled.text('Speed:'+ speed, 0, 24)
    oled.text('Time:'+ gpsTime, 0, 36)
    oled.text(gpsdate, 0, 48)
    oled.show()
    #_________________________________________________
    
##########################################################

取得した自宅の緯度経度を、次のソース内で書き換えれば、目標の自宅から現在地までの距離情報が表示できます
main.pyファイルとしてPaspberry Pi Pico Wに書き込みます
例として東京駅を目的地として記述しております

from machine import Pin, UART, I2C
import utime, time
from ssd1306 import SSD1306_I2C
from micropyGPS import MicropyGPS
import math  # 追加: 距離計算のためにmathモジュールをインポート

##########################################################
# Oled I2C接続
i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)

##########################################################
# GPSモジュールUART接続
gps_module = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))

##########################################################
TIMEZONE = 9
my_gps = MicropyGPS(TIMEZONE)

# 目的地の緯度・経度(例: 東京駅)
destination_lat = 35.681236  # 東京駅の緯度
destination_lng = 139.767125  # 東京駅の経度

##########################################################
# 緯度・経度を変換する関数
def convert(parts):
    if (parts[0] == 0):
        return None
        
    data = parts[0] + (parts[1] / 60.0)
    if (parts[2] == 'S'):
        data = -data
    if (parts[2] == 'W'):
        data = -data

    data = '{0:.6f}'.format(data)  # 小数点6桁まで表示
    return float(data)  # 文字列ではなくfloat型で返すように変更

##########################################################
# Haversine式による距離計算関数(単位: メートル)
def haversine(lat1, lon1, lat2, lon2):
    R = 6371000  # 地球の半径(メートル)
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    delta_phi = math.radians(lat2 - lat1)
    delta_lambda = math.radians(lon2 - lon1)

    a = math.sin(delta_phi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(delta_lambda / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    distance = R * c  # メートルでの距離
    return distance

##########################################################
while True:
    length = gps_module.any()
    if length > 0:
        b = gps_module.read(length)
        for x in b:
            msg = my_gps.update(chr(x))
    
    latitude = convert(my_gps.latitude)
    longitude = convert(my_gps.longitude)
    
    if (latitude is None or longitude is None):
        oled.fill(0)
        oled.text("No Data", 0, 0)
        oled.show()
        continue
    
    t = my_gps.timestamp
    gpsTime = '{:02d}:{:02d}:{:02d}'.format(int(t[0]), int(t[1]), int(t[2]))  # 時刻フォーマット
    speed = my_gps.speed_string('kph')  # km/hでスピードを取得
    
    # 現在位置と目的地との距離を計算し、キロメートルに変換
    distance_to_destination = haversine(latitude, longitude, destination_lat, destination_lng) / 1000  # メートルからキロメートルに変換
    
    # OLEDディスプレイに表示(緯度・経度を非表示にして時刻、スピード、距離のみ表示)
    oled.fill(0)
    oled.text('Time: ' + gpsTime, 0, 0)  # 時刻表示
    oled.text('Speed: ' + speed + ' km/h', 0, 12)  # スピード表示
    oled.text('Distance:', 0, 24)
    oled.text('{:.2f} km'.format(distance_to_destination), 0, 36)  # 距離をキロメートルで表示
    oled.show()
    
    # コンソールにも表示
    print('Distance to destination: {:.2f} km'.format(distance_to_destination))
    
    utime.sleep(1)

Paspberry Pi Pico Wの記憶領域に限りがあるので注意ください
調子に乗ってソースを入れすぎると突然書き込めなくなり、理由が判らず焦ります
こんなときは、一旦基本に戻って一番小さなプログラムのLED点灯などに差し替えて、動作確認すると安心できるかと思います
貼り付けたソースが途中までしか表示されないのは容量不足なので余分なライブラリなどを削除すれば、大抵解決します
ファイルが見えなくなったら一旦、削除して、再びメインソースを書き込めば動作することもあります
ご参考ください

試作機なのでディスプレイは小さいですね
また、暫定版なので英語表記としております
日本語表記も導入可能です

日本語化が面倒なときはディスプレイの外にテプラで「自宅までの距離」って貼っておけば意味は通じるかと思います




この記事が気に入ったらサポートをしてみませんか?