The idea is to record and classify the accelerations of an ankle during various gaits. The accelerometer is worn in a band just above the ankle, and the five connector wires extend upwards to the waist where they lead into an Arduino with an attached micro-SD card. Power is provided by a battery pack and travels to the Arduino through a USB cable.
Pro tip: Remember to put a micro SD card into the adapter before testing. It can save an hour or so of debugging time. 😐
As a reference the Z acceleration (dots) is about 1 G more than the X and Y accelerations. Not much analysis has gone into this, but you can clearly see the forward “snap” of the knee as the pace speeds up.

Packaging
The Arduino and the micro SD card.

The accelerometer. In the next incarnation I’ll use bent pins to allow the package to be thinner. Legos work pretty well!

Wiring

Arduino Code
/**************************************************************
* Accelerometer Thread Created By: Tauseef Ahmad
* Created On: 8th January, 2022
* Modified by: Michael Graham, 14 January, 2023
*
* How To Interface ADXL335 Analog Accelerometer Sensor With Arduino
* Tutorial: https://youtu.be/HrIBGJep-1o
* Tutorial pages: https://arduinogetstarted.com/tutorials/arduino-write-variable-to-sd-card
* https://create.arduino.cc/projecthub/electropeak/sd-card-module-with-arduino-how-to-read-write-data-37f390
**************************************************************/
// initializations for save to microSD
#include <SD.h>
#define PIN_SPI_CS 4
File myFile;
int Precision = 3;
// Initializations for accelerometer A
#define xPinA A0
#define yPinA A1
#define zPinA A2
//calibrated minimum and maximum Raw Ranges for each axis
int xMinA = 249;
int xMaxA = 394;
int yMinA = 255;
int yMaxA = 396;
int zMinA = 260;
int zMaxA = 401;
// Take multiple samples to reduce noise
const int samples = 10;
// Interval is how long we wait
// add const if this should never change
const int interval=100;
// Tracks the time since last event fired
unsigned long previousMillis = 0;
String data_string;
void setup()
{
Serial.begin(115200);
while (!Serial) {
;
}
pinMode(4,OUTPUT);
if (!SD.begin(PIN_SPI_CS)) {
Serial.println(F("SD CARD FAILED, OR NOT PRESENT."));
while (1); // don't do anything more:
}
SD.remove("gait_dat.txt");
}
void loop()
{
// Get snapshot of time
unsigned long currentMillis = millis();
// How much time has passed, accounting for rollover with subtraction!
if ((unsigned long)(currentMillis - previousMillis) >= interval) {
//Read raw values
int xRaw=0,yRaw=0,zRaw=0;
for(int i=0;i<samples;i++)
{
xRaw+=analogRead(xPinA);
yRaw+=analogRead(yPinA);
zRaw+=analogRead(zPinA);
}
xRaw/=samples;
yRaw/=samples;
zRaw/=samples;
//-------------------------------------------------------------
//Convert raw values to 'milli-Gs"
//Convert value of RawMin to -1000
//Convert value of RawMax to 1000
long xMilliG = map(xRaw, xMinA, xMaxA, -1000, 1000);
long yMilliG = map(yRaw, yMinA, yMaxA, -1000, 1000);
long zMilliG = map(zRaw, zMinA, zMaxA, -1000, 1000);
// unused--------------------------------------------------
// re-scale to fractional Gs
float x_g_value = xMilliG / 1000.0;
float y_g_value = yMilliG / 1000.0;
float z_g_value = zMilliG / 1000.0;
//-------------------------------------------------------------
Serial.print(xRaw);
Serial.print("\t");
Serial.print(yRaw);
Serial.print("\t");
Serial.print(zRaw);
Serial.println();
myFile = SD.open("gait_dat.txt", FILE_WRITE);
if (myFile) // it opened OK
{
data_string = String(x_g_value,Precision) + "," + String(y_g_value,Precision) + "," + String(z_g_value,Precision);
myFile.println(data_string);
myFile.close();
} else
Serial.println("Error opening gait_dat.txt");
// Use the snapshot to set track time until next event
previousMillis = currentMillis;
}
}