【実測】Arduinoで歩行用スマートインソールを自作|左右の荷重差と踵接地は検出できる?

医療AI活用ラボ






【実測】Arduinoで歩行用スマートインソールを自作|左右の荷重差と踵接地は検出できる?










DIY Gait Sensor Insole — Field Test Log

Arduinoで歩行用スマートインソールを自作。
左右の荷重差と踵接地は、本当に検出できるのか?

Arduino Nano、FSR圧センサー4〜8個、SDカードだけで作る歩行解析インソールの製作記録です。通常歩行・片足をかばう歩行・杖歩行の3パターンを比較しながら、「本当に検出できるのか」をセンサーの生波形と失敗例つきで検証します。理学療法士の視点での見方と、実際に動くArduinoコードの両方を掲載しています。

使用部品: Arduino Nano/FSR圧センサー×4〜8/microSDカードモジュール 比較対象: 通常歩行・かばい歩行・杖歩行 公開範囲: センサー値・波形・失敗例・センサー配置
実測ベースの波形パターンコード全文コピペ可失敗例つき理学療法士の視点非医療機器の学習用工作
この記事の波形について

本記事の波形図は、実際に試作機を組んで歩いた際に観察された傾向(ピークの高さ・立脚時間の左右差など)をもとに、特徴が分かりやすいよう単純化して描いた模式図です。実際のanalogRead値そのものの波形ではありません。数値そのものより「歩行パターンごとにどんな違いが出やすいか」という傾向の把握を目的としています。

01

なぜインソールで歩行を測るのか

歩行の異常は、痛みをかばう歩き方(疼痛回避歩行)や、片麻痺・下垂足などによる左右の荷重バランスの崩れとして現れることがよくあります。臨床の現場では専用の床反力計や圧力分布計測システムが使われますが、高価で持ち運びも大変です。一方で、足底に圧力センサー(FSR:Force Sensitive Resistor)を数点だけ配置し、荷重の「相対的な変化」を時系列で記録するだけなら、Arduinoと数千円の部品で十分に試作できます。

実際、下垂足のある方向けに足関節装具へ加速度・角速度・足底圧センサーを組み込み、歩行の変化を測定する足底圧センサーを使った足関節装具の試作研究も報告されています。本記事はそうした研究のアプローチを参考にしつつ、まずは自宅の作業台で再現できる最小構成(FSR+Arduino Nano+SDカード)に絞って製作し、実際に「歩行パターンの違いが波形に出るのか」を検証したものです。より本格的なリハビリ用センサーの自作については、当ラボのArduino×Python×AIで作るリハビリセンサー自作ガイドでも扱っていますので、あわせて参考にしてください。

先に断っておきたいこと

本作例は医療機器ではありません。較正されていないFSRセンサーの電圧値は、体重や足の踏み方、靴の中敷きの硬さによって大きくブレます。ここで紹介するのはあくまで「傾向をつかむための学習・研究用工作」であり、診断や治療方針の判断材料にはできません。歩行に不安がある場合は、必ず医療機関や理学療法士に相談してください。

02

使用部品とシステム全体構成

部品 役割 目安価格帯
Arduino Nano センサー値の読み取り、しきい値判定、SD書き込みの制御 低価格帯
FSR圧センサー×4〜8 踵・母趾球など足裏各点の荷重を電圧変化として検出 センサー1個あたり数百円〜
抵抗(10kΩ程度)×センサー数 FSRと分圧回路を組んでanalogReadで読める電圧に変換 安価
microSDカードモジュール+SDカード 歩行中のセンサー値を時刻つきでCSV記録(歩きながらPCに繋げないため) 低価格帯
薄手のインソール/両面テープ FSRを靴の中敷きに固定する土台 安価
モバイルバッテリー 屋外・室内の歩行中もArduinoを動かすための電源 手持ちの物で可

Arduino Nanoのアナログ入力ピンはA0〜A7の8本あるため、片足あたり最大8点のFSRをそのまま読み取れます。まずは片足4点(踵内側・踵外側・母趾球・小趾球)から始め、精度に納得できたら両足8点へ拡張するのがおすすめです。Arduino Nano自体のピン配置や購入時の選び方はArduinoメインボード徹底解説にまとめています。またFSRセンサーそのものの特性や基本的な配線は圧センサーを用いた電子工作の基礎編で扱っており、今回はその応用編にあたります。センサー自体の公式スペックはInterlink Electronics社のFSR 402データシートで確認できます。

03

センサー配置:どこにFSRを貼るか

足底の荷重は「踵接地→足底全体での支持→母趾球への荷重移動→蹴り出し」という順番で移動します。この動きを捉えられるように、配置は次の4点を基本としました。

CH1・踵後方中央

接地の瞬間に最初に反応する場所。踵接地タイミングの検出に使う中心的なセンサー。

CH2・踵外側

着地直後に体重がやや外側にかかる人が多いため、踵中央と合わせて2点で踵接地を判定すると誤検出が減る。

CH3・母趾球(第1中足骨頭)

立脚後期、蹴り出し直前にピークが出る場所。踵から母趾球への荷重移動の遅れ・早まりが見える。

CH4・小趾球(第5中足骨頭)

外側荷重の傾向を見る補助点。片足をかばう歩行では母趾球側の荷重が減り、相対的にここが目立つことがある。

貼り付けのコツ

FSRは「点」で反応するセンサーです。センサーの受感面全体に均等に力がかかるよう、厚みのあるフェルトや薄いゴムシートを上に一枚かませると出力が安定しやすくなります。両面テープで直接貼るだけだと、体重が乗った時にセンサーが浮いて反応が抜け落ちることがあります(後述の失敗例1)。

04

配線図

FSR分圧回路(1chあたり)

FSRの片足をArduinoの5V、もう片足をanalogピン(例:A0)とし、同じanalogピンから10kΩ抵抗を経由してGNDへ落とす。荷重が増えるほどFSRの抵抗値が下がり、analogRead値が大きくなる。

チャンネル割り当て(片足4ch構成)

CH1踵中央→A0/CH2踵外側→A1/CH3母趾球→A2/CH4小趾球→A3

SDカードモジュール(SPI接続)

MOSI→D11、MISO→D12、SCK→D13、CS→D10、VCC→5V、GND→GND(Arduino Nanoの標準SPIピン)

記録タイミング用LED(任意)

D8に接続し、記録開始・終了の合図として点灯。屋外でPCの表示が見えない場面での目印になる。

両足で計測する場合はA0〜A7の8chをすべて使い切る構成になります。分圧抵抗の値(本記事では10kΩ)は、体重や靴の硬さに応じて4.7kΩ〜47kΩ程度の範囲で調整すると、使用する体重域でanalogRead値の変化幅が広く取れます。SDカードモジュールの配線や初期化まわりの詳しい仕様は、Arduino公式のSDライブラリガイドにまとまっているので、うまく認識しない場合はあわせて確認してください。ブレッドボード上での配線に不安がある場合はブレッドボード完全攻略ガイドも参考になります。

05

計測プログラム全文

4chのFSR値を50Hz(20ミリ秒間隔)でサンプリングし、時刻・各チャンネルの値・踵接地判定フラグをSDカードへCSVとして記録するコードです。delay()を使わずmillis()で管理しているため、SDへの書き込み中も次のサンプリングタイミングを見失いません。

insole_logger.ino
// スマートインソール:FSR4ch読み取り+SDカードへCSV記録
#include <SPI.h>
#include <SD.h>
// --- ピン設定 ---
const int FSR_PINS[] = {A0, A1, A2, A3};   // CH1踵中央, CH2踵外側, CH3母趾球, CH4小趾球
const int CH_COUNT = 4;
const int SD_CS_PIN = 10;
const int LED_PIN = 8;
// --- サンプリング設定 ---
const unsigned long SAMPLE_INTERVAL_MS = 20;  // 50Hz
unsigned long lastSampleTime = 0;
unsigned long sampleIndex = 0;
// --- 踵接地しきい値(要調整:まず生の値を見てから決める) ---
const int HEEL_STRIKE_THRESHOLD = 300;   // CH1(踵中央)がこの値を超えたら接地とみなす
bool wasHeelDown = false;
File logFile;
void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  pinMode(SD_CS_PIN, OUTPUT);
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("SD init failed");
    // SDが無くてもシリアルモニタで確認できるよう、処理は止めない
  } else {
    logFile = SD.open("gait_log.csv", FILE_WRITE);
    if (logFile) {
      logFile.println("time_ms,ch1_heel_c,ch2_heel_o,ch3_mtp1,ch4_mtp5,heel_strike");
      logFile.close();
    }
  }
  digitalWrite(LED_PIN, HIGH);  // 記録開始の合図
}
void loop() {
  unsigned long now = millis();
  if (now - lastSampleTime < SAMPLE_INTERVAL_MS) {
    return;  // まだサンプリングのタイミングではない
  }
  lastSampleTime = now;
  int values[CH_COUNT];
  for (int i = 0; i < CH_COUNT; i++) {
    values[i] = analogRead(FSR_PINS[i]);
  }
  // 踵接地判定:CH1がしきい値を上回った瞬間(立ち上がりエッジ)だけ検出する
  bool heelDownNow = values[0] > HEEL_STRIKE_THRESHOLD;
  bool heelStrikeEvent = heelDownNow && !wasHeelDown;
  wasHeelDown = heelDownNow;
  // シリアルモニタへ出力(配線確認・しきい値決めに使う)
  Serial.print(now);
  Serial.print(",");
  for (int i = 0; i < CH_COUNT; i++) {
    Serial.print(values[i]);
    Serial.print(",");
  }
  Serial.println(heelStrikeEvent ? "1" : "0");
  // SDカードへCSV追記
  logFile = SD.open("gait_log.csv", FILE_WRITE);
  if (logFile) {
    logFile.print(now);
    logFile.print(",");
    for (int i = 0; i < CH_COUNT; i++) {
      logFile.print(values[i]);
      logFile.print(",");
    }
    logFile.println(heelStrikeEvent ? "1" : "0");
    logFile.close();
  }
  if (heelStrikeEvent) {
    digitalWrite(LED_PIN, LOW);
    delay(15);  // 目視できる程度の短い点滅(サンプリングへの影響は軽微)
    digitalWrite(LED_PIN, HIGH);
  }
  sampleIndex++;
}
06

コード解説

if (now – lastSampleTime < SAMPLE_INTERVAL_MS) return;
delay()を使うとSDカードへの書き込み待ち時間だけサンプリング間隔がズレてしまいます。millis()で「前回からの経過時間」を毎回チェックする方式にすることで、書き込みが多少遅れても次のタイミングを見失いにくくなります。
bool heelStrikeEvent = heelDownNow && !wasHeelDown;
「今回は踏んでいて、前回は踏んでいなかった」という立ち上がりエッジだけを踏み込みの瞬間として扱います。単純に「今、踏んでいるか」だけを見ると、接地している間ずっとイベントが発生してしまい、1歩を何度も数えてしまいます。
logFile = SD.open(“gait_log.csv”, FILE_WRITE); … logFile.close();
サンプルごとにopen/closeを繰り返すのは、途中で電源が落ちてもそこまでのデータが確実に保存される安全策です。ただしSDカードやモジュールの相性によっては書き込みが数十〜百ミリ秒単位で遅れることがあり、その場合の改善策を失敗例4で紹介しています。
const int HEEL_STRIKE_THRESHOLD = 300;
この数値は体重や靴、貼り付け方で大きく変わります。まずシリアルモニタでCH1の生の値を見ながら、「立っている時」と「浮いている時」の中間くらいに設定するのがコツです。ただし日によって基準値がズレる問題もあり、その対策は失敗例3で紹介しています。
この章のコードについて

ここまでのコードは、仕組みを理解しやすくするための基本版です。しきい値を毎回自動で決め直す処理(失敗例3)や、SD書き込みをまとめて行う処理(失敗例4)は含んでいません。実際に使う際は、次章の実測を踏まえたうえで、失敗例のセクションで紹介する改良を組み合わせてください。

07

実測:通常歩行 vs かばい歩行 vs 杖歩行

同じセンサー配置・同じしきい値のまま3パターンを試作機で歩いてみたところ、歩き方ごとに共通して現れやすい特徴が見えてきました。以下はその特徴を分かりやすく示すために描いた模式図です(実データそのものではなく、観察された傾向の図解です)。縦軸はanalogReadの値(0〜1023)のイメージ、横軸は時間です。

通常歩行:左右がほぼ同じ高さ・同じリズムで交互に立つ

右CH1 左CH1

左右のピークの高さ・立脚時間がほぼ揃っている=対称性が高い

片足をかばう歩行:かばう側の立脚時間が短く、ピークも低い

健側CH1 患側CH1(低く短い)

患側(かばう側)はピークが浅く、立脚時間も短い=早く体重を健側へ逃がしている

杖歩行:3点(杖・健側・患側)のリズムに三拍子的な間が生まれる

健側CH1 患側CH1 杖側の間(無接地区間)

健側の立脚が長く続き、患側の後に一拍分の間(杖の接地区間)が挟まる三点支持のリズム

波形から読み取れたこと

3パターンとも、CH1(踵中央)のピーク高さと立脚時間の左右差という2つの指標だけで、見た目にもはっきり傾向が分かれました。特に「立脚時間の左右差」は、ピークの絶対値よりも個人差・センサー貼り付け誤差の影響を受けにくく、簡易的な自作センサーでも比較的安定して見える指標だと感じています。

08

左右の荷重差は検出できる?

結論から言うと、「絶対的な荷重の大きさ(kg単位)」の左右差は難しいが、「相対的な非対称性」は検出できるというのが実際に組んでみた実感です。理由は次の通りです。

  • FSRの出力は荷重に対して線形ではなく、しかも個体差がある。左右のセンサーを同じ製造ロットで揃え、同じ貼り方をしても、同じ体重で同じ電圧値が出るとは限らない。
  • そのため、左右のCH1の値をそのまま比較するのではなく、各センサーの「その人の最大荷重時の値」で正規化してから比較する必要がある。

本作例では、歩行分析の分野でよく使われる対称性指数(Symmetry Index、SI)の考え方を簡易的に応用し、次の式で左右差を数値化しました。

symmetry_index.txt
SI(%) = (右足ピーク値 − 左足ピーク値) / ((右足ピーク値 + 左足ピーク値) / 2) × 100
SI = 0%     → 左右対称
SI が正の値 → 右足への荷重が相対的に大きい
SI が負の値 → 左足への荷重が相対的に大きい
目安:|SI| が概ね10%を超えると、波形上でも視覚的に非対称が分かりやすくなる

この計算はArduino側で毎回行う必要はなく、SDカードのCSVをPCに取り込み、1歩ごとのピーク値を抽出してから計算する方が現実的です。Arduino側は生データの取りこぼしのない記録に専念させるのが、実装としてはシンプルでした。

POINT

左右差を「検出できるか」という問いに対しては、絶対値の精度ではなく相対的な指標(正規化・比率)で見る設計にすることが、自作センサーでも実用的な結果を得るコツでした。

09

踵接地は検出できる?

踵接地(ヒールストライク)のタイミング検出は、しきい値をきちんと調整すれば安定して検出できました。ポイントは次の3つです。

Q1

1点のセンサーだけで十分?

CH1(踵中央)1点だけでも立ち上がりエッジ検出は可能でしたが、靴下の中で足の角度が微妙にズレるとCH1が反応しない瞬間があり、まれに接地を1回分見逃すことがありました。CH1とCH2(踵外側)のOR条件(どちらかがしきい値を超えたら接地とみなす)にすることで見逃しが大きく減りました。

Q2

チャタリング(誤った複数回検出)は起きない?

起きます。しきい値付近で値が細かく上下すると、1回の接地を何度も検出してしまうことがありました。立ち上がりエッジ検出に加えて「前回のイベントから100ミリ秒以内は再検出しない」という不応期(デバウンス)を入れると解消しました。

Q3

杖歩行や、すり足のような接地でも検出できる?

すり足のようにゆっくり体重が乗る歩き方では、立ち上がりの傾きが緩やかになり、しきい値ちょうどのタイミングが数サンプルに渡ってブレることがありました。この場合はサンプリング周波数を上げる(20ミリ秒→10ミリ秒間隔)ことで検出の安定度が上がりました。

スマホと組み合わせる場合

センサーの数値だけでなく、実際の足の動きも見ながら検証したい場合は、スマホのカメラ1台だけで歩行を撮影・解析する方法も選択肢になります。手順はスマホ1台でリハビリの動作分析はどこまでできる?現状と始め方で紹介しているので、しきい値調整の答え合わせに併用するのもおすすめです。

10

失敗例と対処法

FAILURE 01

体重を乗せているのに値がほぼ変化しない

両面テープでFSRを直接インソールに貼ったところ、センサーの受感面の一部だけに力が集中し、荷重が乗っても値がほとんど動かないチャンネルがありました。

対処:FSRの上に厚み2〜3mm程度のフェルトや薄いゴムシートを一枚挟み、荷重を面で受けてから伝えるようにしたところ、変化幅が大きくなりました。
FAILURE 02

歩いている途中で値が急に0に張り付く

配線の取り回しが甘く、歩行中の足の曲げ伸ばしでリード線の根元が繰り返し曲がり、断線しかけていました。

対処:センサーの根元をインソールの土踏まずあたりで一度固定し、配線に遊び(たるみ)を持たせて足首の動きで直接引っ張られないようにしました。
FAILURE 03

しきい値を一度決めても、別の日に履くと接地検出がズレる

靴下の厚みや靴の締め付け具合で、同じ体重でも立っている時の基準値が日によって変わり、固定したしきい値では検出が甘くなったり過敏になったりしました。

対処:計測開始時に数秒間「直立静止」する時間を設け、その間の値を基準値として自動取得し、しきい値をその基準値からの相対値(例:基準値+150)で毎回計算し直す方式に変更しました。
FAILURE 04

SDカードへの書き込みが数秒に一度、明らかに遅延する

安価なSDカードモジュールとカードの組み合わせで、書き込みのタイミングによっては数十〜百ミリ秒単位の遅延が発生し、サンプリング間隔が乱れることがありました。

対処:1サンプルごとのopen/closeをやめ、一定サンプル数(例えば25サンプル=0.5秒分)をメモリ上の配列にためてからまとめて書き込む方式に変更し、遅延の影響を軽減しました。
11

FAQ・まとめ

市販の歩行分析システムの代わりになりますか?

なりません。本作例は圧力の相対変化を捉える簡易的な自作デバイスであり、医療機器としての較正・精度保証はありません。傾向をつかむ学習・研究用の工作として位置づけてください。実際の歩行評価や治療方針の判断は、必ず医師・理学療法士などの専門家の診察を受けてください。

FSRセンサーは何個必要ですか?

最低限、踵と母趾球の2点×左右4個で荷重の左右差はおおまかに検出できます。踵接地のタイミングや足圧の移動(踵→外側→母趾球)まで見たい場合は片足4個、両足8個の構成を推奨します。

なぜ踵接地の検出がうまくいかないことがあるのですか?

FSRはセンサー面全体に均等に力がかからないと出力が安定しません。靴の中敷きの硬さや貼り付け位置のズレ、配線の接触不良、しきい値の設定ミスが主な原因です。本記事の失敗例1〜4で具体的な対処法を紹介しています。

SDカードへのログはどのくらいの頻度で記録すればよいですか?

歩行1周期はおよそ1秒前後のため、最低でも50Hz(20ミリ秒間隔)程度でのサンプリングを推奨します。すり足など緩やかな接地を細かく捉えたい場合は100Hz(10ミリ秒間隔)まで上げると安定しました。

まとめると、FSR+Arduino Nano+SDカードという最小構成でも、「立脚時間の左右差」と「踵接地のタイミング」はしきい値と正規化の工夫次第で実用的に検出できるという手応えがありました。一方で「荷重の絶対値(kg)」の精度には限界があるため、経過観察のように同じセンサー・同じ人で繰り返し測って変化を追う使い方が、この構成には向いていると感じています。

あわせて読みたい

圧センサーそのものの基礎から学び直したい方は圧センサーを用いた電子工作の基礎編、力の変化を別の切り口で楽しみたい方はリアルタイム握力計測ゲームのコード解説がおすすめです。筋の活動も合わせて見たい場合はArduino×筋電センサー完全ガイド、リハビリ現場でのAI活用を広く知りたい方はリハビリ職のAI活用17選もあわせてご覧ください。

DIY GAIT SENSOR INSOLE — 学習・研究目的の電子工作記録です。医療上の判断は専門家にご相談ください。



関連記事

特集記事

コメント

この記事へのコメントはありません。

TOP
CLOSE