• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+

ToshiTechのブログ一覧

2021年12月30日 イイね!

Fusion360用3/3Dマウスの製作(2号機)

Fusion360用3/3Dマウスの製作(2号機)
さて3/3Dマウスの1号機はいい感じで使えてはいるのですが、常時キーボードの前に置いておくのは邪魔くさいし、使うたびに引っ張り出すというのも面倒です。そこでキーボードの脇に張り付けられる小型のタイプを作りました。
・ダイソーの歯ブラシカバーをケースとして利用しています。
・USBケーブルは手持ちの不要品をカットして直接ケースから生やしています。
alt

・ノブとボタンと取り付けプレートは3Dプリンターで作成しました。
・キーボードの端にゲルテープで貼り付けています。この位置とサイズなら使わないときも邪魔になりません。
alt

●使用した部品
・ジョイスティック P-04048 秋月で\150/個
・マイコン ATtiny85 秋月で\170/個
・ツェナーダイオード 3.6V 秋月で\10/本
その他もろもろは手持ち部品ですが、全部購入しても総額\400程度でしょうか。
alt

●回路説明
・今回は完成品のDigisparkではなく、AVRマイコンのATtiny85を単体で使います。生のATtiny85にDigispark用のブートローダーを焼いて、外付けの抵抗3本とツェナーダイオード2本を追加すればDigisparkコンパチ品の出来上がりです。その後はUSB経由でフラッシュを焼くことができるようになります。
・Digisparkには基板上に3端子レギュレータが載っていますが、USBの5Vで使うので不要です。電源ラインのLEDも不要です。PB1のLEDも機能上は不要なのですが動作確認用として一応付けました。今回使ったATtiny85はDIPパッケージですがDigisparkを使うより安くかつ小型化できたと思います。
・今回のジョイスティックにはスイッチはついていないので、別途タクトスイッチを使っています。
alt


●組み立て
・サイズ的に少し無理があったようでツェナーダイオードが空中配線です。LEDをあきらめれば基板上に配置できたと思います。配線はポリウレタンワイヤを使いました。高さを抑えるためIC用ピンソケットは基板に半分埋め込んでいます。ジョイスティックからの入力は反対側に回せなかったのでICに直接半田付けしています。
alt
・ジョイスティックのノブとスイッチボタンは触って分かりやすいようにノブ表面を凸、ボタンを凹にしています。ノブの底面がジョイスティックのツラ面に軽く触るくらいのクリアランスにして、操作時にシャフトが傾かないようにしています。

●ソフトウェア
・ソースは前回アップしたものを//#define _2Xのコメントを外してビルドします。

●使ってみて
・このジョイスティックはヒスが大きくて、例えばX軸なら右に倒してから戻した時と左に倒してから戻した時でA/Dの読み取り値が異なります。キャリブレーションデータとしては2つの値の平均値を中点の値として設定しました。
・また中点に戻した後もマウス出力が0にならないことがあるので不感帯を設定する必要がありました
・これは想像した通りではあるのですがポテンショタイプと比べると細かい調整がしづらいので、マウスの最大移動量を少なめに設定しています。

★以下はブートローダー書き込みに関しての参考情報&備忘録です
●ブートローダーを書き込むためのハード準備
・適当なArduino(私の場合はNANO)を使って書き込み装置(ArduinoISP)を作ります。ネットにあったこの図ではUNOになってますがNANOでOKです。
alt
・配線はブレッドボードでもいいのですが、今後のことも考えて私はこのような物を作ってみました。
alt
・IDEでボードにNANOを選んでスケッチ例のArduinoISPを焼けば書き込み装置の準備はOKです。

●ブートローダー書き込み
・こちらを参考にしました↓
http://nopnop2002.webcrow.jp/ArduinoISP/ATtiny85-micronucleus.html
私の場合はまずブートローダ焼きこみ作業専用に適当なフォルダを作成し、そこにIDEのportableフォルダの下の階層からavrdude.confとavrdude.exeを探してコピー。さらに
https://github.com/micronucleus/micronucleus
から落としたブートローダーt85_default.hexをコピーし、コマンドプロンプトでカレントディレクトリを変更してから、コマンドラインから
avrdude -Cavrdude.conf -v -pattiny85 -cstk500v1 -PCOM9 -b19200 -D -Uflash:w:t85_default.hex:i -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m
で焼きました。COM9の9はそれぞれ環境によって変更の必要があります。

●別のブートローダーにトライ
・Digisparkデフォルトのブートローダーは、通電後5秒間はフラッシュ焼きこみスタンバイ用のUSBデバイスとして組み込まれ、その後リムーブされ、その後ようやくHIDとして組み込まれます。この間WindowsがUSBのオン→オフ→オンの音を出して鬱陶しいので、通電直後のフラッシュ用USB組み込みをバイパスするブートローダーに差し替えました。
こちらを参考にしました↓
https://qiita.com/nak435/items/67aca33ca49b6f328faa
↓ここにあるmicronucleus-1.11-entry_jumper_pb0.hexを先ほどと同じフォルダに展開し、
https://github.com/overfl0/NocInformatykaBoard/tree/master/upgrade/releases
先ほどのコマンドラインのt85_default.hexの代わりに今回のhexを指定してISPで焼きこみます。
・ちなみにこのブートローダーを使ってプログラムをフラッシュする際は、ボタンを押してPB0をGNDに落とした状態のままUSBに通電します。
・ネット情報ではmicronucleus.exeを使うと通常のUSB接続のまま(ISPを使わずに)ブートローダーを焼けるという事なのですが、私の環境では途中でこのような↓エラーが出てしまい書き込めませんでした。
> Program file is 1856 bytes too big for the bootloader!

Posted at 2021/12/30 19:46:35 | コメント(0) | トラックバック(0) | Fusion360 | パソコン/インターネット
2021年12月28日 イイね!

Fusion360用3/3Dマウスの製作(1号機)

Fusion360用3/3Dマウスの製作(1号機)

・ネットでたまたま目にした"3Dマウス"という言葉が気になって調べてみたら、
https://www.3dconnexion-japan.com/%E8%A3%BD%E5%93%81%E7%B4%B9%E4%BB%8B/
世の中には3D-CAD等でモデルの回転やズームを行える左手用のデバイスがあるという事がわかりました。直感的な操作ができて良さげですが、お試しで使うにはちょっと手が出せない価格ではあります。
alt

・そこで"3Dマウス 自作"で検索するとこんな方もいらっしゃる。↓すごい!
https://shk-maker.hatenablog.jp/entry/2019/10/12/154328

・ここで改めて考えてみるとFusion360でのモデルの操作方法は、
 ズーム:マウスホイールを回転
 平行移動:マウスホイールを押したままマウスを移動
 回転:シフトキーとマウスホイールを押したままマウスを移動
なので、左手が本当に必要となるのは回転だけです。そこでジョイスティックを1つだけ使って回転に特化した(というか回転しかできない)左手用のデバイスが作れるのでは、と考えました。本物の1/3しか機能がないので名付けて"3/3Dマウス"です。
・入手したジョイスティックには押しボタンスイッチが付いているので、これを短く押すと回転の中心(ピボット)を設定、長押しするとモデルを画面全体にフィットする機能を割り当てました。
alt

●使用した部品
・ジョイスティック Amazonで\150/個
https://www.amazon.co.jp/gp/product/B082M4V5S9
・マイコンボード Digispark micro-Bコネクタ版 \435/個(以前は\250くらいでしたが)
https://www.amazon.co.jp/KKHMF-Digispark-Kickstarter-Attiny85-Arduino/dp/B082M58JR2
・アナログ入力2chとデジタル入力1ch、それとHIDに対応したUSBインターフェースがあるものということでDigisparkのmicro-Bタイプを選択しました。
alt

・ケースはダイソーのクリーム入れ \100
・15kΩの抵抗1本とUSBケーブルは手持ちの物
総額で\700未満ですね。

●回路説明
・DigisparkのP0はデジタル入出力として使えます。今回はスイッチ入力に割り当てます。
・P1はボード上にLEDが付けられているので無改造ではデジタル出力としてしか使えません。これは動作確認用にそのまま使うことにします。
・P2はアナログ入力として使えます。X軸のアナログ入力に割り当てます。
・P3, P4はUSB用に割り当てられているので今回のようにユーザープログラムがUSBを利用するときには使えません。
・P5はリセット端子を兼ねているのですが、電圧をLに落とさなければアナログ入力として使えます。Y軸のアナログ入力に割り当てます。
・ただしそのままだとジョイスティックを倒したときにP5の電圧がL電位まで落ちてリセットがかかってしまうので、ジョイスティックを改造してポテンショメーターの1番端子とGND間に15kΩの抵抗を直列に挿入します。これでP5の電圧はジョイスティックを最大に動かしても3~5Vの範囲に収まります。(ATtiny85のスペックだとリセットピンのLレベル電圧Maxは0.2Vccなので5V使用時に1.0Vとなり、それに比べたら十分余裕があります。)
・Digisparkで使われているATtiny85のヒューズと呼ばれている内部のフラッシュ領域を焼き直すとリセット機能を簡単に無効にできるのですが、今回はDigispark側を無改造で使うことにしてハードウェア側で対応しています。
alt
●ジョイスティックの改造
・Y軸用のポテンショのGNDに落ちているピンの周囲のパターンをカットし、ピンとGNDとの間に15kΩの抵抗を入れます。パターンを観察するためレジストを剥いでしまったので最後にマニキュアを塗っておきました。
alt
●ケースに組み込み
・ケースに穴をあけて基板をグルーガンで固定しました。ジョイスティックには6mmの足を付けてDigisparkとは2階建て構造です。LEDが隠れてしまうので透明の樹脂棒で導光を試みましたがあまりうまくいきませんでした。
alt
●ソフトウェア説明
・Digisparkにはキーボードライブラリ<DigiKeyboard.h>とマウスライブラリ<DigiMouse.h>が用意されているのですが、両者を同時に組み込むことができませんでした。
・検索してマウスとキーを同時にエミュレートできるAdafruit-Trinket-USBライブラリを見つけました。↓
https://github.com/adafruit/Adafruit-Trinket-USB
これのTrinketHidComboフォルダをArduinoIDEを展開したフォルダの下のlibrariesフォルダにコピーしておきます。
・ジョイスティックの中点がきっちり抵抗値の50%になるとは限らないのと、Y軸側はそもそも中点が50%ではないので最初にキャリブレーションデータの取得を行います。//#define DEBUGのコメントを外してビルドするとマウスのあるウインドウにX,YのA/D値とそれらを疑似マウスの移動量に変換した値が次々に表示されるので、X,YそれぞれのA/D最小/中点/最大の値をメモします(エディタ等で空白のファイルを開いてその上にマウスカーソルを置いた後で書き込みを開始する必要があります)。メモした値でソースを修正し、再度ビルドして疑似マウス移動量が設定どおりに変化することを確認します。
・#define DEBUGを再度コメントアウトしてビルドして焼きこめば完成です。
・アップしたソースは1号機と2号機それぞれをビルドできるようになっています。1号機が今回の物で2号機はスライド式のジョイスティックを使った小型タイプなのですが、そちらはまた別途。
・マウスをエミュレートしているだけなので、従来のマウスとシフトキーによる回転操作をした時と同様にマウスカーソルも移動します。//#define CURSORRECOVERのコメントを外してビルドすると一定移動距離ごとにカーソルを戻す機能が組み込まれるのですが、どうも元の位置にきっちり戻らないのと、マウスカーソルがちらちらするのと、従来の操作方とのカーソル位置の違いに違和感があるのと、たまにピボット点が変わってしまうという問題があり今は使っていません。
・スイッチをクリックすると、シフトを押しながらホイールを押すコードだけを送っています。これでカーソル位置にピボットが設定されます。
・Fusion360側の機能としてホイールをダブルクリックするとモデルを画面全体にフィットする動きになります。これにより短時間に2回ジョイスティックを動かすとダブルクリックと判定されて予期せずフィットになってしまうことがありました。そこでジョイスティックやスイッチを戻した時に、カーソル位置を少しだけ"行って来い"させてダブルクリック判定に入らないようにしています。
・そのためスイッチのダブルクリックによる画面フィットは不可能になったので、長押ししたらF6キーを送ることで画面フィットを実現しています。

●使ってみて
・確かに直感的にモデルを回転することができる気がします。
・回転しながらのズームはできません。これはマウスによる従来の操作でもできないので当然ではありますが。
・ジョイスチックを倒した方向にマウスを動かすとモデルを急峻に回転させることができます。
・常時キーボードの前に置いておくのは邪魔くさいし、使うたびに引っ張り出すというのも面倒です→2号機に続く

★以下は備忘録です
●Digispark用開発環境の構築
・こちらを参考に↓
http://digistump.com/wiki/digispark/tutorials/connecting
IDE1.6.5がお勧めのようなので、こちらの↓Previous Releasesから1.6.5のZIP版を落としてフォルダごと解凍。
https://www.arduino.cc/en/software
・普段使っているArduinoIDEとは別環境にしたかったので、展開したarduino.exeと同じ階層にportableという名前のフォルダを追加。
・arduino.exeのショートカットをデスクトップに作成し、Digispark専用のIDEはそこから起動。
・IDEを起動したら環境設定でボードマネージャのURLとして以下を追加。
http://digistump.com/package_digistump_index.json
・ツールのボードマネージャでDigistump AVR Board by Digistumpをインストール。
(私の場合バージョン1.6.7じゃないとその後うまくビルドできませんでした)
・この際ドライバーのインストールで一番上の1つがエラーになったので、↓ここの
https://github.com/digistump/DigistumpArduino
toolsフォルダの下のwindows用ドライバを解凍してインストールしたら全部組み込めた。(このドライバが必須かどうかはわからないですが)
・IDEのツールからボードを"Digispark (Default - 16.5mhz)"を選択。
・ビルド&書き込みボタンを押してPlug in device now...(will timeout in 60 seconds)と表示されたらDigisparkを接続。(抜き差しが面倒なので私はUSB延長ケーブルの途中にスイッチを入れて+5Vラインをオンオフできるようにしています)

[↓ソースはここから]
/*****************************************************************************
*
*   JoystickMouse.ino -- Joystickでマウスをエミュレート[Digispark]
*
*   Adafruit-Trinket-USBのTrinketHidComboフォルダをlibrariesフォルダ下にコピー
*   https://github.com/adafruit/Adafruit-Trinket-USB
*
*   JoystickのSW→P0
*   JoystickのX軸→P2(AD1)
*   JoystickのY軸→P5(AD0)
*    PB5はリセット入力兼用なのでY軸のポテンショのGND側に15kΩを
*    直列に挿入して電圧がLレベルにならないようにしている。
*
*   rev1.0  2021/12/22  initial revision by Toshi
*
*****************************************************************************/
#include <TrinketHidCombo.h>    // マウス&キーボードライブラリ

//#define DEBUG         // A/D読み取り値出力時にはコメントを外してビルド
//#define CURSORRECOVER // カーソル位置を戻すならコメントを外す
//#define _2X           // 2号機ならコメントを外す

#define SW PB0  // スイッチポート
#define LED PB1 // LEDポート

#define LED_ON digitalWrite(LED, 1);
#define LED_OFF digitalWrite(LED, 0);

#ifndef _2X // 1号機(ポテンショメータータイプのJoystick))
 #define ADMAXX 1023    // X軸の最大A/D実測値
 #define ADCENTERX 516  // X軸のセンターA/D実測値
 #define ADMINX 0       // X軸の最小A/D実測値
 #define ADMAXY 1023    // Y軸の最大A/D実測値
 #define ADCENTERY 835  // Y軸のセンターA/D実測値
 #define ADMINY 667     // Y軸の最小A/D実測値+2
 #define MAXMOUSE 8     // マウス最大移動量
 #define DEADZONE 0     // ジョイスティックの不感帯(マウス移動量)
#else       // 2号機(スライドタイプのJoystick)
 #define ADMAXX 1023    // X軸の最大A/D実測値
 #define ADCENTERX 476  // X軸のセンターA/D実測値
 #define ADMINX 0       // X軸の最小A/D実測値
 #define ADMAXY 1023    // Y軸の最大A/D実測値
 #define ADCENTERY 828  // Y軸のセンターA/D実測値
 #define ADMINY 677     // Y軸の最小A/D実測値+2
 #define MAXMOUSE 6     // マウス最大移動量
 #define DEADZONE 1     // ジョイスティックの不感帯(マウス移動量)
#endif  // _2X

#define LOOPTIME 20     // ループごとの待ち時間
#define MINMOVE 15      // ホイールダブルクリック判定回避の移動量
#define RESETMOVE 50    // マウスの位置を戻すカウント
#define RECOVERGAIN 54  // 行きに対する戻り側カウント量[%]

int AdData0, AdData1;   // A/D読み取り値
char MoveX, MoveY;      // マウス移動量
int TotalX, TotalY;     // マウス総移動量
bool fPush;             // シフトキー押されているかどうか

void setup()
{
    pinMode(SW, INPUT_PULLUP);
    pinMode(LED, OUTPUT);
    TrinketHidCombo.begin();    // USBデバイスエンジン起動
}
void loop()
{
    static bool fonshort, fonlong;
    static int buf0, buf1;

    // A/D読み取り(0~1023)
    AdData0 = AdRead(0, &buf0); // PB5はAD0(Y軸)
    AdData1 = AdRead(1, &buf1); // PB2はAD1(X軸)

    // A/D読み取り値からマウス移動量への変換
    MoveY = Ad2Mouse(AdData0, ADMINY, ADCENTERY, ADMAXY);
    MoveX = Ad2Mouse(AdData1, ADMINX, ADCENTERX, ADMAXX);

    // SWの短押し/長押しを判定
    JudgeButton(digitalRead(SW) == 0, &fonshort, &fonlong);

#ifdef DEBUG
    DebugPrint();   // A/D読み取り値とマウス移動量をカーソル位置に出力
    delay(500);
#else

    /** 画面Fit **/
    if (fonlong)    // 長押し?
    {
        // F6キーを押す
        TrinketHidCombo.pressKey(0, KEYCODE_F6);
        TrinketHidCombo.pressKey(0, 0);
    }

    /** カーソル位置にピボットを設定 **/
    else if (fonshort)  // 短押し?
    {
        // シフトキーを押す
        TrinketHidCombo.pressKey(KEYCODE_MOD_LEFT_SHIFT,
                                    KEYCODE_LEFT_SHIFT);
        fPush = true;   // シフトキー状態オンを記憶
        // ホイールボタンをオン
        TrinketHidCombo.mouseMove(0, 0, MOUSEBTN_MIDDLE_MASK);
        // ホイールボタンをオフ
        TrinketHidCombo.mouseMove(0, 0, 0);
    }

    /** オービット **/
    else if (MoveX != 0 || MoveY != 0)  // スティックが倒されている?
    {
        if (!fPush) // まだ押されていないなら
        {
LED_ON
            // シフトキーを押す
            TrinketHidCombo.pressKey(KEYCODE_MOD_LEFT_SHIFT,
                                            KEYCODE_LEFT_SHIFT);
            fPush = true;   // シフトキー状態オンを記憶
        }
        if (fPush)  // シフトキーが押されているなら
        {
            // ホイールを押しながらマウスを移動させる
            TrinketHidCombo.mouseMove(MoveX, MoveY, MOUSEBTN_MIDDLE_MASK);
            TotalX += MoveX;    // 移動量の累積
            TotalY += MoveY;
            // トータル移動量が規定に達した?
            if (abs(TotalX) >= RESETMOVE || abs(TotalY) >= RESETMOVE)
            {
                // カーソル位置を戻す
                RecoverMouse(&TotalX, &TotalY);
            }
        }
    }

    /** スティック&ボタン操作なし **/
    else
    {
        if (fPush)  // シフトキーが押されていたら
        {
LED_OFF
            TrinketHidCombo.mouseMove(0, 0, 0); // ホイールボタンをオフ
            // 短時間で2回来た時ダブルクリックと判定されるのを回避する
            TrinketHidCombo.mouseMove(MINMOVE, 0, 0);   // 少し動かして
            TrinketHidCombo.poll();
            TrinketHidCombo.mouseMove(-MINMOVE, 0, 0);  // 元に戻す
            TrinketHidCombo.pressKey(0, 0);     // シフトキーをオフ
            fPush = false;                      // シフトキー状態オフを記憶
            // カーソル位置を戻す
            RecoverMouse(&TotalX, &TotalY);
        }
    }
    delay(LOOPTIME);        // 少し待つ
    TrinketHidCombo.poll(); // USBに何かする必要があるかどうかを確認
#endif  // DEBUG
}
// デバッグビルド時にA/D読み取り値とマウス移動値を出力
void DebugPrint()
{
    TrinketHidCombo.print(AdData1); // X軸A/D値
    TrinketHidCombo.print(",");
    TrinketHidCombo.print(AdData0); // Y軸A/D値
    TrinketHidCombo.print("  ");
    TrinketHidCombo.print((int)MoveX);  // X軸移動量
    TrinketHidCombo.print(",");
    TrinketHidCombo.println((int)MoveY);// Y軸移動量
}
/*----------------------------------------------------------------------------
    カーソル位置を戻す
    書式 void RecoverMouse(int* totalx, int* totaly)

    int* totalx;    移動した量x
    int* totaly;    移動した量y
----------------------------------------------------------------------------*/
void RecoverMouse(int* totalx, int* totaly)
{
#ifdef CURSORRECOVER    // カーソル位置を戻すモードなら
    int x, y;

    TrinketHidCombo.mouseMove(0, 0, 0); // ホイールボタンをオフ

    // mouseMoveの引数はsigned char型なので範囲内で繰り返す
    while (!(*totalx == 0 && *totaly == 0))
    {
        x = min(*totalx, 127);
        x = max(x, -127);       // ライブラリ側で-127までのようなので
        y = min(*totaly, 127);
        y = max(y, -127);
        TrinketHidCombo.poll();
        // マウスカーソルを移動
        // (移動したカウントと戻り量が異なるのでRECOVERGAINは要調整)
        TrinketHidCombo.mouseMove(-x * RECOVERGAIN / 100,
                                  -y * RECOVERGAIN / 100, 0);
        *totalx -= x;
        *totaly -= y;
    }
#else
    *totalx = *totaly = 0;  // 移動量の累積をクリア
#endif // CURSORRECOVER
}
/*----------------------------------------------------------------------------
    A/D読み取りと平均
    書式 ret = AdRead(int ch, int* buf)

    int ret;        A/D値(0~1023)
    int ch;         A/Dチャンネル
    int* buf;       sumバッファ
----------------------------------------------------------------------------*/
#define AVENUM 10   // 平均数。最大で31
int AdRead(int ch, int* buf)
{
    *buf = 0;       // 合計をクリア
    for (int i = 0; i < AVENUM; i++)
    {
        *buf += analogRead(ch); // A/Dデータを累積
    }
    return (*buf + AVENUM / 2) / AVENUM;    // 四捨五入
}
/*----------------------------------------------------------------------------
    A/D読み取り値からマウス移動量への変換
    書式 ret = Ad2Mouse(int data, int dmin, int dcenter, int dmax)

    char ret;       マウス移動量
    int data;       A/Dデータ
    int dmin;       A/D最小値
    int dcenter;    A/Dセンター値
    int dmax;       A/D最大値
----------------------------------------------------------------------------*/
char Ad2Mouse(int data, int dmin, int dcenter, int dmax)
{
    char x, ret = 0;

    if (data >= dcenter)    // センターよりプラス側
    {
        x = (char)map(data, dcenter, dmax, 0, MAXMOUSE + DEADZONE);
    }
    else    // センターよりマイナス側
    {
        x = (char)map(data, dcenter, dmin, 0, -MAXMOUSE - DEADZONE);
    }
    // 不感帯処理
    if (abs(x) > DEADZONE)  // 不感帯より値が大きいなら
    {
        ret = (char)(sign(x) * (abs(x) - DEADZONE));    // 不感帯分を引く
    }
    return ret;
}
/*----------------------------------------------------------------------------
    ボタンの短押し/長押し判定
    書式 void JudgeButton(bool flag, bool* fonshort, bool* fonlong)

    bool flag;      スイッチのon/off状態
    bool* fonshort; 短押し判定
    bool* fonlong;  長押し判定
----------------------------------------------------------------------------*/
#define ONTIMELONG 20   // 長押し判定時間
#define ONTIMESHORT 2   // 短押し判定時間
void JudgeButton(bool flag, bool* fonshort, bool* fonlong)
{
    static int ontime, offtime = 30000;
    static bool flong;

    *fonshort = *fonlong = false;       // いったんクリア

    AddOnOffTime(flag, &ontime, &offtime);  // オンオフ時間の累積

    // オン時間が長押し時間に達した
    if (ontime == ONTIMELONG)
    {
        *fonlong = true;    // 長押しと判定
        flong = true;
    }
    // オフ時間が短押し時間に達して長押しではない
    if (offtime == ONTIMESHORT && !flong)
    {
        *fonshort = true;   // 短押しと判定
    }
    // 長押し後にオフ時間が短押し時間+1に達した
    if (flong && offtime > ONTIMESHORT)
    {
        flong = false;      // 長押し状態解除
    }
}
/*----------------------------------------------------------------------------
    符号を返す
    書式 ret = sign(int x)

    int ret;    負なら-1, さもなければ1
    int x;      データ
----------------------------------------------------------------------------*/
int sign(int x)
{
    if (x < 0) return -1;
    return 1;
}
/*----------------------------------------------------------------------------
    フラグのオン/オフ時間の累積 
    書式 void AddOnOffTime(bool flag, int* ontime, int* offtime)

    bool flag;      フラグ
    int* ontime;    オン時間
    int* offtime;   オフ時間
----------------------------------------------------------------------------*/
#define TIMEMAX 30000
void AddOnOffTime(bool flag, int* ontime, int* offtime)
{
    if (flag)                           /* オンしてるなら */
    {
        *offtime = 0;                   /* オフ時間を0に */
        if (*ontime < TIMEMAX)          /* 規定に達するまでタイマ++ */
        {
            (*ontime)++;
        }
    }
    else                                /* オフなら */
    {
        *ontime = 0;                    /* オン時間を0に */
        if (*offtime < TIMEMAX)         /* 規定に達するまでタイマ++ */
        {
            (*offtime)++;
        }
    }
}
/*** end of JoystickMouse.ino ***/
[↑ここまで]

Posted at 2021/12/28 15:31:52 | コメント(0) | トラックバック(0) | Fusion360 | パソコン/インターネット
2021年12月26日 イイね!

USBを給電用に分岐

USBを給電用に分岐
中華ナビでUSB接続のワンセグチューナーとブースターのために、以前2ポートハブを使いましたが、ブースター側へは+5Vを給電するだけなのでハブの必要はありません。セリアでPCのUSBポートからチャージするためのタコ足ソケットが売っていたのでこれを改造することにしました。
alt

蓋を開けるとこんな感じでコネクタとチップ抵抗が載っていて、入力のD+/D-端子は結線されていません。
alt


alt

今回はR1~R4のチップ抵抗を外して入出力のD+/D-を直結しました。もう片方の給電側はどうせその先が結線されていないので抵抗はそのままにしてありますが、もちろん外しても構いません。
alt

alt

ケースに戻して完成です。
alt

このセリアの商品、よく見るとUSBのマークの枝が逆になってます。チャージ専用なのでデーター転送には使えませんよ、と言いたいのかな?
Posted at 2021/12/26 11:23:31 | コメント(0) | トラックバック(0) | 中華ナビ | パソコン/インターネット

プロフィール

ToshiTechです。よろしくお願いします。 なにかを作るのが好きです。優先順位としては  ①世の中にないから作る  ②世の中にはあるけど値段が高いので...
みんカラ新規会員登録

ユーザー内検索

<< 2021/12 >>

   1234
567891011
12131415161718
19202122232425
2627 2829 3031 

愛車一覧

ホンダ フィット(RS) ホンダ フィット(RS)
ホンダ フィット3(RS)に乗っています。

過去のブログ

2025年
01月02月03月04月05月06月
07月08月09月10月11月12月
2024年
01月02月03月04月05月06月
07月08月09月10月11月12月
2023年
01月02月03月04月05月06月
07月08月09月10月11月12月
2022年
01月02月03月04月05月06月
07月08月09月10月11月12月
2021年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ
© LY Corporation