wvogel日記

自分用の技術備忘録が多めです.

メダマトーン製作

はじめに

昨今の半導体不足で,秋月での買い物は遅れに遅れ泣く泣く街に繰り出したり(digikeyは3日後には家に届きました...!)していましたが,家にある部品だけを使って子供用(2-3歳)のおもちゃを作ることにしました.

対象年齢2-3歳ということで,小さい子でも持ちやすいサイズに納める必要があります. また,操作が複雑なのは好ましくありません.姪っ子は時々バイオリンを触りにきますが,弓の往復よりも簡単な操作方法であることが一つの条件と考えます.

そこで,超音波センサを使って,床(天井)からの距離で奏でる音階が変わる電子楽器を作ることにしました. 超音波センサは,発信用・受信用センサが二つあり人の眼のようにも見えますから,有名な電子楽器オタマトーンをもじって,メダマトーンと名付けましょう.オタマトーンは指板上で指をスライドしたり,お口をぱくぱくさせる運動が必要ですが,メダマトーンは箱を上下させるだけですから,2,3歳の子でも十分扱うことが可能です.

f:id:wvogel00:20210918171523j:plain
メダマトーン 完成図

部品選定

まず初めに筐体を決めます.幸い家にいくつかタカチのケースがあったので実物をもとに検証することができました.結果,手持ちのケースでは子供にはやや大きすぎるきらいがあると判明したため,小さくてcuteなSW-55Bに決定しました. 寸法上,超音波センサHC-SR04が枠内ぴったりに収まる形状ですが,その分回路部に許される包絡域は非常に限られます.5V動作の超音波センサに必要な昇圧回路の試作では1cm四方に収めることができましたがもう一度実装するのが面倒になったのでamazonで適当なモジュールを買って分解することにしました.測定では4.97V出ていたので問題ないでしょう.

www.monotaro.com

3942 Adafruit Industries LLC | センサ、トランスデューサ | DigiKey

https://www.amazon.co.jp/gp/product/B077XRWK3Q/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1

メダマトーンに過不足ないフラットパッケージのマイコンは手持ちになく,また手元にある基板は2.54mmピッチなので,8pin DIP 12F683を採用しました. これはGP2からPWM出力が可能なので,横着実装で音階を奏でるにはぴったりです.

製作

回路を引いて基板に実装しました.若干苦労したので記録

f:id:wvogel00:20210918231203p:plain
回路図
f:id:wvogel00:20210918170919j:plain
実装後

写真に見えている面の背面に超音波センサが取り付いていますので,超音波センサと基板の間はカプトンテープで絶縁しています.

ボタン電池の下側に見えているのが昇圧基板です.購入時にはUSB端子がついていますが,そんなものがあっては入りませんのでカットしました.また,高さを稼ぐために部品を載せている基板には厚さ0.4mmの片面基板を採用しています. ただ,このままでは蓋が閉まりませんのでさらに筐体内部の空間を稼ぐために,超音波センサについている推奨発振子の位置に穴を開けた他,半田面のリード線をことごとくカットしました.一部カット漏れがあり,蓋を閉めるとショートして常にスイッチが入りっぱなしになったのでこれも修正します.

しかしまだ問題があります. 箱側面に見えている緑色スイッチはタクトスイッチなのですが,これの固定に苦労しました.

  1. メタルロッックで固着 ... タクトスイッチのボタン面についている出っ張りにより箱と密着できず剥がれる
  2. エポキシパテ+メタルロックで固着 ... 圧力の加わる方向に支えがないので剥がれる

結局,エポキシパテでボタン—基板間を充填することで固着しました. ソースコードも掲載しておきます.もし制作する場合は,下記改造が考えられます

  • 測距の変化率が大きい時に音が大きく変化するのを改良
  • PWMの変化幅を増やし対応オクターブを増やす
/*
 * File:   main.c
 * Author: toriiwataru
 * Created on September 17, 2021, 23:47 JST
 */

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

#include <xc.h>
#define _XTAL_FREQ 4000000 //8MHz

#define HIGH        1
#define LOW         0
#define PWM         GPIObits.GP2
#define ECHO        GPIObits.GP5        //INPUT
#define TRIGGER     GPIObits.GP4
#define BUTTON      GPIObits.GP1        //INPUT
#define N           8

char freqList[N] = {239,213,190,179,159,142,126,119};   //C,D,..,C
char avgList[N] = {239,239,239,239,239,239,239,239};

void StopPWM()
{
    CCP1CON = 0x00;
}
void StartPWM()
{
    CCP1CON = 0x0c;
}

void SetPWM(char v)
{
    PR2 = v;
    CCPR1L = v/2;       //duty cycle 1:1
}

void Initialize()
{
    OSCCON = 0x60;      //4MHz    
    TRISIO = 0x22;      // gp5, gp1 is input
    CMCON0 = 0x07;      //CIN pins as I/O
    ANSEL  = 0x00;
    GPIO   = 0x00;
    
    //setting PWM
    PR2 = freqList[0];
    CCPR1L = freqList[0]/2;       //duty cycle
    StartPWM();
    T2CON = 0x03;       //prescaler=16
    T2CONbits.TMR2ON = 1;//T2 ON
    TMR2 = 0;
}

void DoReMi()
{
    for(int i = 0; i < N; i++)
    {
        SetPWM(freqList[i]);
        __delay_ms(200);
    }
}

int MeasureEcho()
{
    int counter = 0;
    
    TRIGGER = HIGH;
    __delay_us(10);
    TRIGGER = LOW;
    
    while(ECHO == LOW)  //wait for rising edge
        ;
    
    while(ECHO == HIGH) //wait for falling edge
    {
        counter++;
        __delay_us(10);
    }
    __delay_ms(20);
    return counter;
}

char IsPressed()
{
    char isPressed = !BUTTON;
    for(int i = 0; i < N; i++)
    {
        __delay_us(200);
        isPressed &= !BUTTON;
    }
    return isPressed;
}

void main(void) {
    char prevValue = 0;
    
    Initialize();
    DoReMi();
    
    while(1)
    {
        int avg = 0;
        const int threshold = 20;
        
        if(IsPressed())
            StartPWM();
        else
            StopPWM();
        
        for(int i = 1; i < N; i++)
            avgList[i-1] = avgList[i];
        avgList[N-1] = MeasureEcho();
        for(int i = 0; i < N; i++)
            avg += avgList[i];
        
        int value = freqList[0] - (2*avg)%freqList[0];
        
        if(   prevValue-value > prevValue/threshold
           || value-prevValue > prevValue/threshold)
            SetPWM(value);
        
        prevValue = value;
    }
}

史上最短,16時間緊急入院時の記録

背景

7/10 23:30 JST,激しい腹痛により救急外来へ自宅の車で搬送,その後2h弱で癒着性イレウスと診断され入院,翌7/11に退院した. その状況を記録する.

7/10 自宅(20:40 JST

お手洗い中,段々と腹痛が強くなる. これまで数ヶ月に渡り,治癒しかけの十二指腸潰瘍痕により同様の激しい腹痛を経験していたため真っ先にこれを疑い,ロキソニンを服用(20:50JST).これは現在タケキャブを服用することで快方へ向かっているはずだが,痛むときは痛む.ただ気になるのが,十二指腸潰瘍よりも下部が痛む感覚があり,潰瘍と違って,指で少し触れるだけで激痛が走った.

これまでの経験上,潰瘍に対してはロキソニン服用後およそ40min-1h程度で効果が出始める.しかし,1h20m経過した時点でも治る気配がない(22:10 JST). そもそも,潰瘍から激しく出血している場合にはロキソニンは効かないはずなので,潰瘍痕が出血性潰瘍へ悪化したことを疑う. このとき,ときたま吐き気も催していたため吐血を恐れた.吐血後,出血量によっては失神するのだが,まだ本日分の薬液(フローラン)調合を終えていなかったのである.急ぎ,意識のあるうちにと親に指示を出して薬液調合を完遂する.調合人員の冗長系が欲しい.

7/10 救急病棟(23:20 JST)

親に病院への連絡をお願いするもなぜか少し渋られた後,行きつけの病院到着(かかりつけよりも,行きつけが正しい).

事前に,これまた行きつけの病棟に連絡していたため,会うのは初めてだが担当科の夜勤医師が対応.後に知るのだが,私が運び込まれる前に既に病棟に病床確保指示,CT検査準備を進めてくれていた.

血圧・SpO2・触診.触診時に,上述したように十二指腸潰瘍よりも痛む場所がずれていることを医師も指摘,超音波エコーを実施. 痛む場所に,常に同じ腸管が留まっているように見える.

ついで,CT検査も視野に入れて肘の内側の太い橈骨皮静脈にVラインを取り,ここから採血ののち痛み止めのソセゴンを点滴. この採血の結果,白血球数が12000,CRPが0.5程度まで上昇しており何らかの炎症が起きていることが確定.おそらくイレウス(腸閉塞)と診断が固まるが,決定打がない.イレウスにも様々な種類があるためである.なお,私は過去に嵌頓によるイレウスも経験しているがこちらは手術で解決している.

相談の上,造影CT撮影.あらかじめVラインをCT用に耐圧のものを使用していたため,すぐに検査できた. 結果,一部腸管が浮腫んでおり,採血・エコーの結果と合わせて癒着性イレウスと診断された(7/11 1:10 JST).(癒着性イレウスでは,CRP,白血球の増加が認められる) 昨年8月に人生3度目の開腹により脾臓摘出手術をしたため,癒着性イレウスは十分起こりうる状況ではあった.

7/11 一般病棟 1:30

ソセゴンのおかげもあり7/11 1:00頃には違和感はあるものの著しい痛みがほぼおさまった. イレウスに対しては,絶飲食での腸の浮腫解消,抗生剤点滴,腸の状態によっては切除を行うが今回の場合は軽症なので半日絶飲食することに.

昼食から半分量で再開し,再発しないことを確認,17:00 JSTに退院した.

まとめ

  • 私のカルテ情報が豊富にある病院とは言え,到着前に諸々準備してくれた医師のおかげで迅速に診断・入院することができた.救急病棟の看護師?には迷惑がられていたように見えたが,迅速な対応に感謝.
  • 癒着性イレウスは開腹手術をした人間の宿命とも言え,特にコロナで運動量が激減したことにより癒着が進んだとも考えられる.該当箇所を切除しない限り付き合い続けるしかなく,また発症は運任せなところもあるのが難点であるが,付き合い方はこれまでの消化管出血と何ら変わらないことを考えると気が楽である.
  • 癒着性イレウスとの付き合い方として,1日1万歩,スクワットなど体育会系解決法を提示されたが,それでは肺高血圧症が悪化してしまうw.従来通り,腹八分目,消化の悪いものを避けるといった方法を今後も継続していく
  • 4,5h痛みで悶絶したおかげで今もまだ眠い.

在宅医療ポンプのレザーバッグを作った

目的

CADDシリーズの汎用輸液ポンプMODEL 6500用レザーバッグを製作する

背景

私はかれこれ20年近く24時間静脈注射を使っています. すると,このポンプを入れるバッグが必要になります. 最初の三年くらいは,青色のとてもダサいバッグを支給されたので使っていました. 当時の静注薬は24時間保冷が必要だったため,カセット(輸液を入れているタンク)の両側に保冷剤を入れられる形をしている必要がありました.

しかしダサかった.

あまりにもダサすぎたためか,3年程度でデザインが変わり,色も紺色と黒色の2色から選べるようになりました.初回だったので無料でプレゼントしてもらえましたが,買い替えの場合には当時の価格で7000円あるいは9000円が必要です.

f:id:wvogel00:20210627150929p:plain
10数年使用してきたポンプ

このバッグを10数年使用してきた過程で降り積もった不満点があるので列挙していきます

既存バッグのデメリット

  1. すでに不要になった保冷用のアルミがださい
  2. 長年使ったおかげでアルミ表面がつるつるになり,ポンプが滑り落ちる
  3. でかい.ダサい
  4. ファスナーの終端金具がバッグの側面についているので,閉まりが甘いとバッグからポンプが滑り落ちる
  5. せめて予備電池用ポケットは欲しい
  6. バッグ裏側にベルト通しがあるが,バッグ+ポンプが重すぎてベルトにはつけられない
  7. ベルト通し表面には細かい凸凹があるため,擦れて服やスーツが必ず摩耗する

3つ目はバッグとして致命的です.ポンプが滑落するポンプ用バッグがこの世に存在して良いのでしょうか.実際,数日前もバッグから滑落してコンクリートに落下・衝突しました.写真のポンプの液晶にある傷はその時ついたものです.

最後2つは日常生活を送る上でとてもストレスフルです.お気に入りの服がどんどんけずれて磨耗していきます.

つい最近レザークラフトを始めた者として,上記問題点を全て解決するバッグを製作しました. レザークラフト初心者なので,レザーのルールは全て無視します.

成果物

下が成果物です.茶色革は姫路レザーを使いました.当初キャメルカラーの革を買ったんですが,色が明るすぎたことによる変更点です. 赤い革の部分は,2mのレザーテープで全てを賄っています.それでも少し余ったのでちょうど良い分量です.

f:id:wvogel00:20210627154046p:plain
輸液ポンプMODEL6500用レザーバッグ

f:id:wvogel00:20210627154646p:plain
厚さはおよそ半分に
f:id:wvogel00:20210627154802p:plain
側面のストライプがクッションにもなる

デメリットの改善点を見てみます

  1. 保冷用のアルミはなくなりました.
  2. 上から出し入れする方式なので滑落はしません
  3. 厚さはおよそ半分になり,少しお洒落になりました
  4. 上から出し入れする方式なので滑落はしません
  5. カセットの下側に見えているのが予備電池用ポケットです.
  6. ベルト通しはありません
  7. ベルト通がないので服も傷みません

また,ポンプと体が接する面には,発泡スチロール剤を芯材にしたクッションを入れています.

型紙製作はしていませんが,コバ処理は少しだけ頑張りました. 正規ポンプバッグは7000 or 9000ですが,今回の材料費はおよそ4500円なので,費用を半分に抑えた上で全ての問題点を解決するソリューションを提案することができました.

以上,参考になれば幸いです.

私とどらえもんとひみつ道具

我が家にはドラえもんのぬいぐるみが大小問わずそれなりの数ある.今はもういない友達にもらったものもあれば,ストレス下の私が鉛筆で目に斜め線を描き込んだせいでずっと怒った表情のドラえもんもいる.

それはさておき,私には姪がいる.2歳9ヶ月になろうかという聡明な若人である. 彼女のヒーローはジャムおじさんプリキュアで,まだ一度もドラえもん作品を観たことはないが,我が家に遊びにくる度に沢山のドラえもんと遊んでいるため,漫画やアニメを見たことはなくとも既に知っている.無自覚のうちに旧知の仲となった彼女とドラえもんを見て,さて自分の場合はどうだったか.これを機に記しておくことにする.

f:id:wvogel00:20210609203215p:plain
姪っ子とよく遊んでいるドラえもん
f:id:wvogel00:20210609203136p:plain
最近組み立てたドラえもんプラモデル

どらえもん

私はドラえもんフリークではないし,特別にこれが好きというわけでもない.それでもドラえもんは私の日常の1部である. 特に大長編との付き合いは長い. 鉄人兵団の無人店で楽しそうに買い物をする彼らも,怪盗ドラパン謎の挑戦状の「ちょべりば~!」や「通り抜けフープ!...LLサイズ」も,雲の王国の「パルパル皆を頼んだ」の一連のシーンも,眼に耳に残ってふとした時に思い出す.

そもそも私は幼少期,人と触れ合うことがなかった.こども病院にいたためである.親も面会時間は限られ,エレベーターホールと病棟を阻む扉に貼られた笑顔のききとららのイラストがとても無機質に見えた.片道1時間強の道,月に何度かは姉や妹も来てくれたが扉を超えることは出来ず,ききとららの隙間を縫ったガラス越しに手を重ねたりして遊んでいた(時に扉を強く叩きすぎて怒られた). 体調の良い時はエレベータホールに出られることもあったが,姉とゴーリキーやゴーストを通信ケーブル越しに交換する程度の時間しか与えられなかったし,基本的に絶飲絶食状態だったためか,頭にはいくつもの円形脱毛が起きていたと聞いている.

頻繁に入っていたICUは尚更であろう.親の面会時間は更に限られ,私は起き上がることも出来ない.そんな状況下で,世界と私を繋いでいたのはドラえもんだった. 親はよく,今は亡きVHSに録画したり,どこかのビデオ屋(多分TSUTAYA)でレンタルしたドラえもん映画を持ってきてくれた.起き上がれないので,ビデオのセットは親が来る時だけである(自分の娯楽のために看護師さんを煩わせるのは幼心に申し訳なくて出来なかった). ICUで見た日本創世記はなぜか記憶に焼き付いているし,VHSの日本誕生は,放送中に流れた速報情報が画面上部に出る場所も覚えている(リニアモーターカーごっこのび太が振り落とされた後辺り).海底鬼岩城は,テープが擦り切れてほぼ砂嵐になっても記憶を頼りに”観ていた”.今思うとVHSには過酷なことをした.

インプットがドラえもんしかないので,当然アウトプットもドラえもんしかない.大長編ドラえもんの漫画を真似て,適当にコマを割って漫画を描いたり,アイロンビーズひみつ道具を作ったりした(写真).およそ20年ぶりに引っ張り出した今でも全てのひみつ道具の名前を覚えていた.皆さんはいくつわかるだろうか. 部品一つ一つをアイロンビーズで作り,細い針金でインテグレーションしたタイムマシンはかなりの力作だったが,おそらくタイムトンネルに入りどこかに流れていってしまった.

f:id:wvogel00:20210609200435p:plain
アイロンビーズひみつ道具

ひみつ道具

ジャイアン達がドラえもんの出す道具は役に立たないと呆れるシーンをよく見るが,ひみつ道具はだからこそ美しく,広く愛されるのだと思う.そうでなければ,22世紀の未来で普及している筈がない.夢たしかめ機のような,何の役にも立たないのにそれなりに値が張りそうなメカに始まり,10円を要求してくる転ばし屋,的中率70%のたずねびとステッキ,塗りすぎると暑く(寒く)なりすぎるあべこべクリーム.22世紀でも最新の技術テキオー灯も24時間で効き目が切れるが,24時間というのがまた良い.有限の時間がわくわくを高める要素となる.この点,あらためてF先生の偉大さを感じる. そして数ある道具の中で当時欲しかったものの一つが重力ペンキだ.これがあればいつでも病院を抜け出すことができるし,地球の重力に従って歩いている人々を驚かせることもできる.

21世紀のひみつ道具

昔入院中に流れていたテレビで,実現されたひみつ道具を紹介するような趣旨の番組を観た記憶がある.山びこ山や空気クレヨン,タケコプター(これは1人乗りヘリコプターだったので無理があった)などが紹介されていた記憶があるが,会社が全くわからない.情報があれば教えていただきたい.

これを観た時,初めてドラえもんは現実になるのかもしれないと思った. F先生も言っている,”SFとはすこしふしぎ”であると.すこしふしぎなだけなら,そんな未来はすぐ来るんじゃないのか,作れるのではないか.私の中の科学の原点はドラえもんであり,数々のひみつ道具達である.

さいごに

私が幼少期を過ごした20世紀末に比べテクノロジーはめざましい進歩を遂げた. FAXや固定電話は鳴りを潜め,その数十倍以上ものデータを個人間でやり取りする時代である.身に着ける電子機器は多くのセンサを搭載し,宇宙ではドラえもんのスパイ衛星さながら,国家以外の企業・団体が独自の衛星を運用する. ”普通”に生活する分には,もうこの世界には真新しいことはなくて,重箱の隅を突く様な研究ばかりしているかのように見えるかもしれない.

確か大魔境でドラえもんが「海でも山でも,およそ全て探し尽くされている.この世に秘境はもう残っていない」というようなことをのび太に告げるシーンがあった.

ところが新種生物の報告は尽きないし,人類が月面に降りたのだってまだ一度きり.人間は地球の核にたどり着いたことは一度もない.一方,絶滅生物は増え続け,数多くの民族言語も知られぬままに葬られようとしている.あらゆる分野に未開拓技術・領域が残されている.

自分のなかに培うひみつ道具とともに,まだ見ぬ知識の扉を叩く. ドラえもんと戯れる姪っ子を見ながら,子供たちがそんな楽しい日々を過ごせることを祈って筆をおく.

肺高血圧症雑記

備忘録兼,参考資料として記録しておきます.

肺高血圧症って何

詳しくは各自,文献なりwebなりをあたってください.簡単に述べると,人間の体には大きく分けて4つの動脈・静脈があるうち,心臓から肺に血液を送るための血管「肺動脈」の血圧が高いものを指します[1]. おそらく読者のほとんどの方が目にしたことのある血圧は,心臓と全身をつなぐ血管の圧を指しますので実際に自身の肺動脈圧をご存知の方はあまりいないかもしれません. 肺動脈圧を測定するには,足の付け根あるいは首にある動脈に穿刺してカテーテルを心臓まで通して直接測定する必要があります(記事執筆時点). 本来,運動や日常活動によって若干の変動はするものの安静時には肺動脈圧は10mmHg以下が正常値です.一方,肺高血圧症と診断される人の多くは安静時でも25mmHg以上になっており,進行度によってはさらに高くなります.この値が35mmHgを超えてくると,35mmHg未満の患者に対し有意に死亡率が高いといった報告がなされています[2].

国内人口はおよそ3000人(平成26年時点)で,私が発症(発見)した平成11年度と比べるとおよそ9倍と単調増加をしています.単純に症例が増え診断材料が増加したことで発見数が増えただけかもしれませんが. 男女比は1:2以上と女性患者が圧倒的に多く,また40,50代と比較的歳を重ねてからの発症が多くなっています.(平均年齢53歳). 症状が進むと,内部では心臓の右室肥大や,肺動脈の脆化(硬化)が起き,外部から観測可能な症状としては息切れや喀血,浮腫・失神などが挙げられ進行度によって死亡もあります. 後述するように最近は新薬も多々開発されてきていますが,昔は有効薬自体存在せず,IPAH/HPAHの場合,[3]には”1年生存率、3年生存率、5年生存率が各々67.9%、40.2%、38.1%”とありますので,発症者は戦々恐々と日々を過ごしていたことでしょう.知らんけど. そのため,薬のない時代に発症し20年以上経過した今もなお社会活動を営む男子(私)は割合貴重な研究材料となります.

上述の通り予後不良(進行性・死亡)な疾患として知られています.そのため日本では指定難病(86)に指定されており,比較的小さい負担で治療を受けることが可能です.とはいえ心身への負担は相当なものでしょう.知らんけど

一方,今年3/9に国立循環器病研究センターは,肺動脈性肺高血圧症(PAH)の重症化メカニズムをラットを用いた実験で解明したとプレスリリースがありました[4,5]. 今後画期的な薬が出ると良いですね.

歴史と治療法

肺高血圧症の発見は1891年,ドイツが最初と伝えられています[6].当時はカテーテル検査などありませんが,検体の心臓の右室肥大及び肺動脈の拡張・硬化が発見の手がかりとなりました. なお,カテーテルの心臓までの挿入には1926年に初めて成功しています.この時は専用器具等ありませんので,腕を切開してそこから尿道カテーテルを挿入しています.その後,1940年代に今の右心カテーテルを使った血圧・心拍量の検査手法が確立されました.これはノーベル賞を受賞しています.私に一番身近な賞かもしれません.

そして現在,様々な薬が開発・認可され,治療法にも選択の幅が出てきています.現に,私の周りの患者は皆成人後それも最近発症していますが,誰もフローランなぞ注射していませんし内服薬も相性によって変更するといった運用をしています.

平成24年の資料でやや古いのですが,[7]から画像を下に掲載します.

f:id:wvogel00:20210606163923p:plain
肺高血圧症治療手順([7]より)

これまで(いつの話やねん),肺血管に選択的に作用するプロスタサイクリン経路の治療薬が使われていましたが,今は

  1. プロスタサイクリン経路
  2. エンドセリン経路(国内で発見された)
  3. NO(一酸化窒素)経路

の3種類から作用する薬がそれぞれ開発されており,この3種のいずれかあるいは組み合わせて投与することで効果を高める内科治療が一般的となっています.

NO経路のもの(ダダラフィル,シルデナフィル)は,血液拡張物質サイクリックGMPを分解する酵素PDE5の働きを阻害することで,肺動脈圧を下げる効果があります.

エンドセリン経路のものは,物質エンドセリンがもつ血管収縮作用及び細胞分裂促進作用を妨げることで排血管を拡張する作用を持ちます.

プロスタサイクリン経路のものは,エポプロステノールは血管拡張及び血液凝固を妨げることで肺動脈圧を低下させます.24時間持続静法や吸入法が取られています.

私の場合

私は8歳で発症した後,13歳から当時の新薬(今は古株)フローランの24時間静注を開始しました.上に挙げた図では最も重症患者にとられる方法ですが,当時はこの薬しかありませんでした.その後,右心カテーテル検査を間欠的に実施,検査結果に合わせて増量を繰り返しますが,いろいろあって2019/10に心不全と診断されました. それを受けオプスミット,これにダダラフィルを処方されました.しかしダダラフィルが覿面に効き,副作用も激しかったため通常の半分量で止まっています.

そしていろいろあって(論文書けるレベルなので端折ります)現在は,10年以上付き合ってきたフローランを逓減するとともにウプトラビを逓増し完全内服への切り替え治療を進めています. ウプトラビもフローラン同様プロスタサイクリン経路です. これは,1日2回,1.6mg/回が服用上限ですので,2週間に0.2mgずつ増量する計画でいます.尤も,0.4mgまで増量した現在ですでに頭痛が出てきていますのでペースダウンあるいは中止する可能性もあります.

以上,備忘録兼記録でした.おしまい

参考資料

半自動スライドホイッスル演奏機

スライドホイッスルという楽器の存在を最近しりました. 筒の中に入る棒の長さで音高を調整する楽器です. 目的の音を出す位置まで自動で棒を動かすことができれば 奏者はただ息を吹くだけで演奏できるようになるのです. ギアを使った工作は未経験だったので勉強ついでに作りました.

f:id:wvogel00:20210508125031p:plain
半自動スライドホイッスル 演奏機
以下,製作記録です.

基本設計

棒を出し入れする機構が必要になります. 静音性重視でVCMを使う方法や,棒を固定し筒側を動かす方法も検討しましたが, 今回はシンプルにラックギアを棒に取り付け,ステッピングモータで位置制御する方針を採用. というのも,digitの移転セールでステッピングモータ(TS3166N913)を80円で入手していたためです.

f:id:wvogel00:20210508125242p:plain
TS3166N913
ラックギアには,タミヤの工作キットを活用させていただきました.

タミヤ 楽しい工作シリーズ ラック&ピニオン ギヤセット | タミヤ

タミヤのこのシリーズはミニ四駆同様,歯車のモジュールが0.5です. 規格が統一されているのは非常にありがたい. 購入したステッピングモータ の軸はφ5のDカットです. これにとりつけられるギアはさすがにタミヤにはなく,そしてこのサイズでは通常,ねじ止め歯車を使います. さっそく,KHK歯数56の格好良いギアを買いました.

f:id:wvogel00:20210508125514p:plain
KHK SS0.5-56A

しかしこの歯車,写真のように50g弱の重量(いもねじ含む)があり, これをステッピングモータ に取り付けたところ, 歯車重量によってモータの姿勢によっては回転運動が妨げられることが発覚しました. 試験時にはモータを横置きにしていたため発見が遅れました. 格好良い歯車なのに...残念. そこで,歯数30のギアを改めて購入.大幅に軽量化されました(写真).

f:id:wvogel00:20210508125750p:plain
協育歯車S50S30B*0805
30歯数の歯車を,タミヤのラックギアセットに入っていた42歯数歯車で受け,1.4倍の減速をかけます. 笛の可動部自体を軽く作っているので,問題なく動くはずです.

モータドライバには,PololuのDRV8835を使用.

デュアルモータードライバDRV8835 - スイッチサイエンス

ステッピングモータもDCモータも動かせる偉いやつです. MCUには私の愛用,PIC16F1705を使います. モータ自体はDC12Vまで使用できます.本作では5V-12Vの間で振ってみたところ, 5Vでも問題なく動作したので5V給電することにします.

3Dモデル用意

ギアボックス及び笛を設計します(写真).

f:id:wvogel00:20210508130300p:plain
設計 with fusion360
ギア間距離は,m=歯車のモジュール,Z1,2=歯車1,2の歯数とすると, (Z1+Z2)m/2 [mm] で計算されます.3Dプリンタの印刷誤差を考慮し,0.2mmほどマージンを設けました.

インテグレーション

写真が印刷結果です.その他,ねじやシャフトなど,構成部品を全て写してあります.

f:id:wvogel00:20210508130428p:plain
演奏機 構成部品
この頃,自分の3Dプリンタは私の元を離れていたため,友人のAdventure3で印刷してもらいました. 素晴らしい仕上がりです.惚れます. 3mmシャフトは,モノタロウで18mmのものを長さ指定購入しました. なお,ギアボックス本体と天蓋でシャフトを挟んで固定するために, 天蓋をネジで止める部分にはインサートナットを埋め込んでもらいました.かっけー

ギアボックスの白い部分は,上述したように歯車の変更があったので, ギア間距離調整のために埋めた跡です.

そして肝心の笛は位相を90度ずらした二箇所をネジ締結する方式です. うち一箇所はモータと干渉しないようにざぐりをいれています.

f:id:wvogel00:20210508130539p:plain
笛固定ねじのざぐり

ソフトウェア

ステッピングモータの資料が読める猿なら誰でも書けますのでバナナを食べながら書きました. MCUへの書き込み機も3Dプリンタ同様私の元を離れていたため,amazonで500円くらいのものを買いました. ソースコードは下記URLから参照できます.

https://github.com/wvogel00/SlideWhistle

完成

完成です.

f:id:wvogel00:20210508133119p:plain
完成(上から)
f:id:wvogel00:20210508095055j:plain
完成(横から)
演奏動画を下に貼っておきます. 手が赤いのは持病のせいですw

www.youtube.com

高音部分が音が出にくいので改良の余地がありますがとりあえず,めでたしめでたし

SDL2で簡単作曲ツールを作る

Haskell Advent Calendar 2020,13日目の記事です.

はじめに

夏から楽器の練習を始めましたが,如何せん音痴なので,楽譜を読んでも正しい音程やリズムがわかりません.これでは学習が進みませんね.

そんな障害をツールで解決するのがエンジニアです. 皆大好きHaskellには,これまた皆大好きなSDL2ライブラリが存在します. 音楽がさっぱりわからない私でも使えるGUIツールを作成していきましょう. まだまだ開発中ですが,記事最後にデモ動画を置いてあります.

なお,リポジトリは以下にあります.

github.com

では簡単に仕様を決めていきましょう.しかしあまりにも適当に仕様を決めると後々苦しいです. 現実世界の先取り約束機は,等価交換ではないのです.

2108.先取り約束機 - ドラえもん ひみつ道具完全大図鑑

仕様

  • PCキーボードで音階入力(C,D..B)
  • 音長,音程操作
  • 楽譜再生機能
  • 作成した楽譜の保存・読み出し機能(JSON形式)

スラー演奏なども欲しい機能ですが,とりあえず上記があればツールとしては使えるでしょう. また,アプリケーション名は”うずら”にしました.体の割に大きい声で鳴き,鳴き声を競う”鵜合わせ”にも用いられた鳥としても有名です.軽量なアプリで実用に耐えるものを,そんな思いを込めてみましょう.

stackの設定

使用するライブラリをstackで管理します.執筆時点では以下を使用しています.

[package.yaml]
dependencies:
- base >= 4.7 && < 5
- sdl2 >= 2.5.0.0
- sdl2-ttf
- sdl2-image
- aeson
- bytestring
- extra
- linear >= 1.21
- process
- text
- vector
- lens
- directory
- filepath

今回はlensを多用しています.もっと格好良く使えるようになりたい...

イベント型を考える

うずら”には,

  • 作曲画面
  • 保存画面
  • ロード画面

の3つが必要です.

一方,SDL2はIOやIORef使いまくりなので,少しでも安全に開発するために このそれぞれのイベントに対して独立した型を作ります. イベントに対する処理が未実装のものもまだ多数ありますが,次のようにしています.

data QuailEvent =
    Quit
    | NotImplemented
    | AddKeySignature KeySignature
    | AddClef Clef
    | AddNote Scale
    | AddSharp
    | AddFlat
    | Shorten
    | Lengthen
    | DeleteNote
    | AddSign Note
    | AddSlur [Note]
    | AddTie [Note]
    | PlaySound
    | StopSound
    | ResumeSound
    | MousePos Int Int
    | SaveEvent
    | LoadEvent
    deriving (Eq, Show)

data SaveEvent =
    QuitSave
    | Save
    | SaveChoice_Up
    | SaveChoice_Down
    | SaveName_Input Char
    | ContinueSave
    deriving Eq

data LoadEvent =
    QuitLoad
    | Load
    | LoadChoice_Up
    | LoadChoice_Down
    | ContinueLoad
    deriving Eq

楽譜型を考える

楽譜の構造を初めてまともに知りました. 結果,以下の型を採用しました.なお,フィールドは抜粋です. 割と妥当な設計ではないかと思っています.知らんけど.

lensで使うためにはフィールド名の先頭に'_'をつけましょう.

data MusicalScore = MusicalScore
    { _metro :: Metronome
    , _beatRate :: (Int,Int) -- e.g. 4/4拍子
    , _bars :: [Bar]
    }
    deriving (Eq, Show, Generic)

-- JSONのインスタンス化は,以下で登場する型についても同様.
instance FromJSON MusicalScore where
    parseJSON = genericParseJSON jsonOpts
instance ToJSON MusicalScore where
    toEncoding = genericToEncoding jsonOpts

-- テンポ
data Metronome = Metronome Int
    deriving (Eq, Show, Generic)

-- 音部記号
data Clef = GClef | FClef
    deriving (Eq, Show, Generic)

-- 小節
data Bar = Bar
    { _clef :: Clef
    , _keys :: [KeySignature] -- 調号
    , _notes :: [Note]
    }
    deriving (Eq, Show, Generic)

-- 音符 (フィールドは一部抜粋)
data Note = Note
    { _no :: Int
    , _scale :: Scale
    , _sign :: Sign
    , _oct :: Octave
    , _len :: (Length, [Dot])
    , ...
    }
    deriving (Eq, Show, Generic)

-- 音階
data  Scale = Rest | C | CS | D | DS | E | F | FS | G | GS | A | AS | B
    deriving (Eq, Show, Enum, Ord, Generic)

SDL2をゴリゴリ書く

SDL2の使い方についてはC++での解説が充実しているので,公式サイトとその他作例を参考にしつつ実装していきます.描画にはSurface型とRenderer型がありますが,今回は後者を採用しています. GUIの立ち上げ部のコードを掲載します.

startGUI :: IO ()
startGUI = do
    SDL.initializeAll
    withSDL $ withWindow "うずら" (width,height) $
        \w -> do
            sound <- newIORef []
            audioDev <- openAudio sound
            r <- SDL.createRenderer w (-1) rendererConfig
            ts <- loadNoteTextures r
            void $ renderLoop (audioDev,sound) r ts initMusicalScore
            SDL.destroyRenderer r

うずら”では音再生が必要で,SDL2にはそのための関数が用意されています.そしてHaskellでは,音データを格納する値はIORef型となっていますので,ツール起動中の間持ち回せるようにnewIORef関数で領域を確保します. openAudio関数は,音再生に使うデータをコールバック方式で指定する関数です. loadNoteTexturesでは,使用する音符・休符の画像データを読み込んでいます. renderLoop関数で描画ループに突入するので,イベントに応じて処理を書いていきます.

キーイベントに応じたイベント型を得る関数getEventTypeを一部抜粋します.

getEventType :: SDL.KeyboardEventData -> QuailEvent
getEventType event
    | catchOn event (Just SDL.keyModifierLeftShift, SDL.KeycodeA,   SDL.Pressed) = AddNote AS
    | catchOn event (Nothing,                       SDL.KeycodeA,   SDL.Pressed) = AddNote A
    | ...
    | catchOn event (Nothing,                       SDL.KeycodeP,   SDL.Pressed) = PlaySound
    | catchOn event (Nothing,                       SDL.KeycodeLeft,  SDL.Pressed) = Shorten
    | ...

最初の二行は音階を追加する場合のものですが,ここでAddNote ASAddNote Aよりも下に置くと,shiftキーを押してもAddNote Aを返してしまいますので注意してください.

ここで得たイベント型に応じて捌くのがdealEventです.全てのケースを掲載する必要もないのでこれも抜粋を掲載します.

dealEvent :: QuailEvent -> (SDL.AudioDevice, IORef [Int16]) -> SDL.Renderer -> MusicalScore -> IO MusicalScore
dealEvent ev (audio,sound) r ms = case ev of
    PlaySound   -> do
        buildMusic ms sound
        playAudio audio sound >> return ms
    StopSound   -> lockAudio audio >> return ms
    ResumeSound -> resumeAudio audio >> return ms
    ...
    AddSharp -> return $ addSharp (noteCount ms) ms
    AddFlat  -> return $ addFlat  (noteCount ms) ms
    Shorten  -> return $ shorten  (noteCount ms) ms
    Lengthen -> return $ lengthen (noteCount ms) ms
    LoadEvent -> do
        loadResult <- loadLoop r
        case loadResult of
            Just loadedScore -> return loadedScore
            Nothing -> return ms
    SaveEvent -> saveLoop r ms >> return ms
    _ -> return ms

なお,現時点ではAddSharp等の音符操作は,すべて楽譜の一番最後の音符についてのみの操作になっています.addSharp関数に渡す第一引数が,操作する音符の場所を示す値なので,将来的にマウスイベントなどを実装する場合には,ここを変更することで操作対象を変更します. また,音符や小節はリストに包まれているので何も考えずにlastやinitを使うと,楽譜に音符が存在しない時にエラーで落ちてしまいます.そこで少々面倒ですがsafelast,safeinit関数で安全に捌いています.

文字描画

適当にフォントデータ(ttf形式は動作確認済)をダウンロードし,適当なフォルダに格納します.格好良いフォントを探しましょう. フォントサイズが決まれば,SDL.Font.size関数で文字描画に最適な描画エリアが求まります.今回は再利用しやすいように文字描画用の関数を用意しました.SDL.V2はCInt型を引数に取るので,煩わしいですがfromIntegral関数で型を合わせてあげます.

drawText r color fontsize (x,y) text = unless (T.null text) $ do
    font <- Font.load fontpath fontsize
    textSurface <- Font.solid font color text
    (w,h) <- Font.size font text
    textTexture <- SDL.createTextureFromSurface r textSurface
    Font.free font
    SDL.copyEx r textTexture
        (Just $ SDL.Rectangle (SDL.P $ SDL.V2 0 0) (SDL.V2 (fromIntegral w) (fromIntegral h)))
        (Just $ SDL.Rectangle (SDL.P $ SDL.V2 x y) (SDL.V2 (fromIntegral w) (fromIntegral h)))
        0
        Nothing
        (pure False)

ちなみにこの関数,中で毎回フォントデータを読んでいるのであまりよろしくないです. いずれ直します,いずれ...

ただ,キーボードからの入力に応じた文字を描画するのは少々面倒です.楽譜を保存する時に必要になるのですが,sdlライブラリから得られるのは入力されたキーに対応するキーコードですので,以下URLを参考にテーブルを作成してフォントデータと紐付けました.

SDLキーコード一覧表

デモ動画

ほとんどの関数をGUI.hsに突っ込んでいたり,無駄に処理を繰り返していたり,リファクタリングしないといけない箇所が多々あるんですが,動くものは出来つつあります. 最後にカエルの歌でつくったデモ動画を貼っておきます. 今後,ちまちまと小節毎に区切り線入れるなどの改修も進める予定です.

そういえば五線紙も自分オリジナルで作り直したい...

youtu.be

ついでにロゴも作ってみました,が.雑ですね... 息抜きに絵が描きたかっただけなので,とりあえずは良しとしましょう. f:id:wvogel00:20201211233121p:plain

さいごに

音の改良にも手をつけたいところです.各楽器の代表的FFTデータとかどこかに落ちているんだろうか... 音痴はツールが解決しました.やったね!