alli-GAIT-or analysis

Cost effective insole sensor for diagnosing foot problems

Similar projects worth following
This shoe insole logs & tracks a persons walking/running gait, it is aimed for use in the medical field, exploring a cost effective solution that provides doctors with additional data needed for the diagnosis/treatment of ambulatory disorders. Its aim is to help people recover from injury promoting a faster rehabilitation leading to lower hospital/treatment costs.
The data collected from the sole additionally provides the necessary information to create a 3D printed corrective insole which will be permanently placed in the persons shoe.
On another level athletes can use it log performance and track any right/left side imbalances.

The Project Synopsis (in a nutshell):-

  1. A great deal of information can be gathered about the way we walk, walking incorrectly can bring pain and discomfort, walking correctly will bring vitality and flexibility. This insole provides a tool for diagnosing the directions of any imbalances.
  2. The working mechanism leans on the premise that when you flex a piezo element it generates a voltage, multiple sensors have been placed around a shoe sole, by walking/running the foot flexes this sensor sole and the multiple transducers react to any load placed on them.
  3. This data is collected and displayed as a heat map on a remote screen Graphic user interface (screen) for analysis either in "Real Time" or in recorded playback.
  4. The software will diagnose whether the person is leaning their weight to much on the Medial or Lateral side or also Posterior or Anterior side or any combination of the previous.
  5. Data can be used to create a corrective 3D insole which is permanently placed in person shoe to correct the load distribution.
  6. The project uses easily obtainable low cost components which can be sourced world wide, enabling 1st,2nd,3rd,extraterrestrial world countries to profit.

Update 20160924 :- Live remote data flow

At last this is the first "Round Robin" test of the live remote data collection to display GUI.

Update 20160511 :- Here is a quick video overhead of how the system works, showing details of the mechanical & electronic set up.

Update 20160425 :-

The components arrive pretty quickly .... the fittest ones won.

Two different sized transducers and BlueTooth modules.... (to date I use only the 20mm type)

Project Materials and Aims :-

Each persons foot pressure/walking gait is different, with also right/left foot idiosyncrasies .

The aim is find the optimal walking gait for the person being monitored and to find out differing patterns between right and left feet, then display this in a meaningful easy to understand way.

To do this we have a multitude of pressure sensitive sensors placed throughout the insole, this means that some cross/relationship calculations can be made between adjacent sensors.

With the data it will be possible to create a real-time coloured stress map which is displayed to a smart phone for immediate diagnosis by doctor or/and recorded for later playback.

Basic outline and materials (BOM is in one of the Logs):-

  • Consists of one Right and one Left foot sensor
  • 2 Comfy flexible insoles circa 3-5mm thick each which will sandwich the sensor array
  • 16 Piezo transducers per shoe
  • Atmel Mcu to process the transducers and packet the data for transmission.
  • Either MCP3008 (10bit fast adc chips) or ADS1115 (16 bit not so fast adc chips)
  • BlueTooth adaptor/module to transmit sensor data to smart phone.
  • Batteries.
  • Smart phone or remote PC for displaying data.
  • SD card to enable logging of data (maybe it gets used on extended walk).

Envisaged challenges :-

  • Piezo's are fragile and prone to snap on excessive force. (too date none have broken)
  • Reading 32 Analogues from the sensors and extrapolation of data.
  • Heat generated by feet. (proved not to be an issue since I sandwiched the sensor array between two thermal soles).
  • Creating an APP based Gui for a meaningful quickly readable display.
  • How many different insoles would be necessary from small to large (or will one size fit them all)

Possible sensor alternatives :-

  • Strain Gauges
  • Conductive Foam (I already have experience here and jar of conductive graphite fluid)
  • Compressive laser light tubes
  • Capacitive plates
  • Air pressure

Possible additional "Spin Off's" :-

  • Athlete sports analysis (real time - during event and training)
  • Cycling foot load analysis to pedal
  • Walking sensors for immersive Virtual Reality.

Update 05/08/2016 :-

No Place for Stilettos

Blender jumps into action to design the Piezo sensor holder sole.

Click my log here for more details

Update 05/11/2016 :-

Squeezing the Crystals and 3D printing the sole.

Click my log here for more details on the 3D printing process

The 3D printed sole uses ABS plastic, split in two...

Read more »

Portable Network Graphics (PNG) - 13.06 kB - 09/21/2016 at 16:01


Portable Network Graphics (PNG) - 2.31 kB - 09/21/2016 at 16:01


Portable Network Graphics (PNG) - 2.14 kB - 09/21/2016 at 16:01


Portable Network Graphics (PNG) - 2.14 kB - 09/21/2016 at 16:01


Portable Network Graphics (PNG) - 2.31 kB - 09/21/2016 at 16:01


View all 18 files

  • 16 × Piezo Transducers per shoe 16 PCS 27mm Piezo Elements Sounder Sensor Trigger Drum Disc + wire copper
  • 1 × Atmel processor Pro Mini atmega328 5V 16M Replace ATmega128 Arduino Compatible Nano
  • 4 × 16 bit Analog to Digital converters 16 Bit I2c 4 Channel Ads1115 Module Adc With Pro Gain Amplifier
  • 2 × Blue Tooth Modules Bluetooth RF Transceiver Module HC-05 RS232 Master Slave
  • 2 × 3mm Insoles for shoes Insulated soft foam insoles

View all 7 components

  • Processing Android Phone App begins to work

    chiprobot10/02/2016 at 15:50 2 comments

    There is an App called APDE which enables Processing sketches to be run on your Android phone...

    Thought it would be a neat idea to give it a try..... surprisingly the Gui is 95% working, just need to sort out the serial data transfer.

    ok its a tad small.... and wrong rotation.... its a start.

  • Some "Live" data to peruse

    chiprobot10/02/2016 at 09:35 0 comments

    Here is a cross section sample of a 64 slice scan of foot data.

  • BOM aka Bill Of Materials

    chiprobot09/21/2016 at 16:50 0 comments

    BOM :- Bill of Materials for one sole

    Piezo Transducers 27mm £ 1.85
    Atmel processor Pro Mini atmega32£ 2.70
    416 Bit I2c 4 Channel ADS1115 Module Adc converter
    £ 8.40
    2Bluetooth RF Transceiver Module HC-05 £ 7.60
    3mm Insoles for shoes, Insulated soft foam insoles£ 2.00
    2Lipo Batteries 3.7V 500mA Output 1S £ 2.00
    1100PCS 1/4W Carbon Film Resistors,£ 1.50

    perf board / solder / pla / wire /etc/etc£ 3.94
    £ 29.99

  • Doing up the Buttons - Processing

    chiprobot09/21/2016 at 14:30 0 comments

    For control purposes the project requires some Buttons.

    These will provide feeback and instigate data recall modes from the sensor array using the Processing controlled Touch screen.

    Here is how to do this in Processing , it includes the sensor scan code too which retreives the live sensor data :-

    import controlP5.*;
    ControlP5 cp5;
    Slider s1; 
    //Textarea myTextarea1;
    //Textarea myTextarea2;
    int myColor = color(0,0,0);
    int sliderTicks2 = 100;
    Slider abc;
    import processing.serial.*;
    Serial myPort;  // The serial port
    float x,y,w,q;
    Blob[] blobs = new Blob[16];
    PShape bot;        // 000,001,002,003,004,005,006, 007, 008,009,010,011,012,013,014,015
    int[][] timeLine = { {000,000,000,000,000,000,000, 000, 000,000,000,000,000,000,000,000},
                         {000,000,000,000,000,000,000, 000, 000,000,000,000,000,000,000,000},
               set truncated here 
    void setup() {
       size(640, 360);
         cp5 = new ControlP5(this);
      s1 = cp5.addSlider("Milliseconds")
         .setRange(0,14) // values can range from big to small as well
         .setImages(loadImage("button_scan_green.png"), loadImage("button_scan_blue.png"),loadImage("button_scan_orange.png"))
         .setImages(loadImage("button_live_green.png"), loadImage("button_live_red.png"),loadImage("button_scan_green.png"))
         .setImages(loadImage("button_reset_green.png"), loadImage("button_reset_blue.png"),loadImage("button_reset_orange.png"))
      printArray(Serial.list());      // print list of active serial ports
      myPort = new Serial(this, Serial.list()[1], 38400);  // adjust serial port number to suit
        blobs[0] = new Blob(555,133);
        blobs[1] = new Blob(490,127);
        blobs[2] = new Blob(430,115);
        blobs[3] = new Blob(357,140);
        blobs[4] = new Blob(255,160);
        blobs[5] = new Blob(154,145);
        blobs[6] = new Blob(85,138);
        blobs[7] = new Blob(425,175);
        blobs[8] = new Blob(552,193);
        blobs[9] = new Blob(488,213);
        blobs[10] = new Blob(424,238);
        blobs[11] = new Blob(364,226);
        blobs[12] = new Blob(294,222);
        blobs[13] = new Blob(214,214);
        blobs[14] = new Blob(141,209);
        blobs[15] = new Blob(72,203);
        bot = loadShape("soles.svg");
    void draw() {
    for (int w = 0; w <= 15; w++) {
     for (int x = 0; x <= 15; x++) {
      if (myPort.available() > 0) 
        int lowByte =;
        int highByte =;
        int value = highByte * 256 + lowByte;
      x = mouseX;
      y = mouseY;
      for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          int index = x + y * width;
          float sum = 0;
          for (Blob b : blobs) {
            float d = dist(x, y, b.pos.x, b.pos.y);
            w=timeLine[int(   s1.getValue())][int(q)];
            sum += 10 *  w / d;
           // println(b.r);
           // delay(1);
          pixels[index] = color(sum, 255, 255);
     shape(bot, -90, -50, 800, 450);
      for (Blob b : blobs) {
       //float r= s1.getValue();
    public void controlEvent(ControlEvent theEvent) {
    // function buttonReset will receive changes from 
    // controller with name buttonReset
    public void buttonReset(int theValue) {
      println("a button event from buttonReset: "+theValue);
      myColor = color(128);
    // function buttonLive...
    Read more »

  • Scubbing through the data

    chiprobot09/19/2016 at 13:52 0 comments

    Test to bring Touch control the the Display Gui... Using Processingand a 10.5" HDMI touch screen monitor.

    The 16 analogues and Data set Time-Line can now be accessed and displayed using a Touch screen, by sweeping your finger on the scroll bar you can navigate through the recorded data sets.

  • Why create work when the Data is already there !!!

    chiprobot09/05/2016 at 09:23 0 comments

    I needed to create a Gui with the shape of a sole so that I could plot the live data to it.....

    In my mind I was not looking forward to the thought of drawing point by point in the Processing panel the outline and positioning of the sensors... it was going to be a time consuming task .... or so I thought..

    Enter "Blender" to the rescue.

    I already have the data sitting inside my Blender environment (the one I used to 3D print the sole).

    There is a Freescale SVG graphic export option that once selected in the user preferences allows for a great deal of control over saving your Blender shape data.

    Using the Blender export, both my sole and sensor array were saved as a SVG graphic, this meant that it could be easily scaled and worked with afterwards.

    I imported the SVG directly into Processing :-

    PShape bot;
    void setup() {
      size(640, 360);
      // The file "soles.svg" must be in the data folder
      // of the current sketch to load successfully
      bot = loadShape("soles.svg");
    void draw(){
      shape(bot, -90, -50, 800, 450);  // Draw at coordinate (110, 90) at size 100 x 100

    This gave me the pleasing overlay graphics.

    Now the second time consuming part was going to be the positioning of the sensor cells onto this graphic.... luckily Processing has a neat trick with the Mouse positioning.

     x = mouseX;
     y = mouseY;
    This made live very easy as I just had to hover the mouse over the sensor cell graphicand note the X,Y coordinate.

    Once all 16 Sensors had been located they were hard coded into the Blob Array.

  • Heat Mapping in "Processing"

    chiprobot09/04/2016 at 18:01 0 comments

    It looks like the best option to display the Foot sensor data is by using the Processing language.

    From the start of the Project I have experimented with a "Heat Mapping" type of display to show a

    coloured banding between the interacting sensor cells.

    Below is some test data to show the "Heat Map" process , here are just 6 of my 16 sensors.

    Each blob is a sensor and the thin black circle around each blob represents the signal strength.

    The Higher the signal strength the stronger the red colour, as you can see the colours blend together which gives a visual indication of the relationships between sensors.

    The Code (modified from Daniel Shiffman's github code :-

    // Daniel Shiffman  (modified slightly for chiprobots alligator test)
    // Code for: 
    Blob[] blobs = new Blob[6];
    void setup() {
      size(640, 360);
      //for (int i = 0; i < blobs.length; i++) {
        blobs[0] = new Blob(250,150);
        blobs[1] = new Blob(250,220);
        blobs[2] = new Blob(320,150);
        blobs[3] = new Blob(320,220);
        blobs[4] = new Blob(390,150);
        blobs[5] = new Blob(390,220);
     // }
    void draw() {
      for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          int index = x + y * width;
          float sum = 0;
          for (Blob b : blobs) {
            float d = dist(x, y, b.pos.x, b.pos.y);
            sum += 30 * b.r / d;
          pixels[index] = color(sum, 255, 255);
      for (Blob b : blobs) {
    and is Blob dependency required in a separate tab named "Blob"
    // Daniel Shiffman  (modified slightly for chiprobots alligator test)



    class Blob {

    PVector pos;

    float r;

    PVector vel;

    Blob(float x, float y) {

    pos = new PVector(x, y);

    vel = PVector.random2D();

    vel.mult(random(0, 0));

    r = random(10, 80);


    void update() {


    if (pos.x > width || pos.x < 0) {

    vel.x *= -1;


    if (pos.y > height || pos.y < 0) {

    vel.y *= -1;



    void show() {




    ellipse(pos.x, pos.y, r*2, r*2);



    Next stage is to map all 16 sensors in correct orientation.

  • "Processing" some optional Gui's

    chiprobot09/01/2016 at 08:06 0 comments

    I have a PiZero and HDMI touch screen waiting in the side lines.

    I know its possible to hook up the "Processing" language on the PiZero so below is the start of some documentation on the gottchas and ins and outs of display possibilities.

    This way I will have a good sized Touchscreen control Remote Display unit.

    Update :- The PiZero "Processing" environment is way to slow so PiZero will not be used.

    First Etape

    Finding out how to receive serial data into processing.

    >>> PiZero integration follows after these tests on my PC version of "Processing"

    (otherwise its a waste of time when the feel of "Processing" does not warrant further exploration)

    Establishing the SERIAL link

    Fire up "Processing" and insert this code:-

    import processing.serial.*;
    Serial myPort;  // The serial port
    void setup() {
       printArray(Serial.list());      // print list of active serial ports
       myPort = new Serial(this, Serial.list()[0], 38400);  // adjust serial port number to suit
    void draw() {
      while (myPort.available() > 0) {
        int inByte =;

    Running the module gives this output :-

    [0] "COM1"
    [1] "COM2"
    [2] "COM12"
    Now I know which active serial ports I have on my machine.

    So the code has to be revised to replace the port number from Serial.list() [0] to Serial.list() [2] this is the one my Arduino sensor is attached to (i.e. "COM12").

    import processing.serial.*;
    Serial myPort;  // The serial port
    void setup() {
       printArray(Serial.list());      // print list of active serial ports
       myPort = new Serial(this, Serial.list()[2], 38400);  // adjust serial port number to suit
    void draw() {
      while (myPort.available() > 0) {
        int inByte =;
        print(inByte); print (" ");

    Bingo.... now the output streams My serial data

    [0] "COM1"
    [1] "COM2"
    [2] "COM12"

  • Untethering The Sole Checklist

    chiprobot08/31/2016 at 20:58 0 comments

    1. >Remote Teva Sole subject
    2. >16 Piezo pressure sensors mounted
    3. >16 ADC channels using 4 ADS1115's operational
    4. >Arduino Mini to collect the data via i2c , overkill just two IO's used
    5. >BlueTooth Module transmits to remote workstation, currently running @38400Baud
    6. >2X500mAhr Lipo batteries
    7. > Live Data appears to be working

  • Severing the umbilical - Bluetooth

    chiprobot08/29/2016 at 18:22 0 comments

    Now was is a pressing need to couple the data streaming out of the Atmel to some form of display unit.

    To get the ball rolling Bluetooth links were used, namely HC-05 modules

    (HC-05 is best one to get as it can operate as a Master or Slave).

    I have a bucket load of bluetooth modules and believe me its a lottery as to what firmware is installed, biggest problem is the differing AT command sets.

    Best to buy two HC-05 modules from the same supplier preferably the type with a switch on them for placing it easily into AT command mode.

    The best way to program the HC-05 Bluetooth modules is by using a simple FTDI module.

    Just remember to wire RX to TX and TX to RX.

    You can use the Arduino's Serial monitor or X-CTU or I can also recommend RealTerm to act as the serial monitor.

    Adjust the baud rate to suit the Bluetooth modules you have (in my case default is 38400 Baud), this changes from firmware to firmware so beware).

    Designating the Master and Slave BlueTooth Module.

    Starting with the SLAVE module :-

    Press the button whilst powering up and this should place it into the AT command mode.

    Type in the serial monitor these following commands to configure as Slave.

    AT                        // Are you there?
    OK                        // Yes I am here
    AT+ROLE=0                 // Change to SLAVE Mode
    OK                        // confirmed
    AT+ADDR                   // Ask for address of the SLAVE module?
    +ADDR:98d3:31:204e02      // make a note we need it below
    Next to the MASTER module :-

    Press the button whilst powering up and this should place it into the AT command mode.

    Type in the serial monitor these following commands to configure as Master.

    AT                        // Are you there?
    OK                        // Yes I am here
    AT+ROLE=1                 // Change to Master Mode
    OK                        // confirmed
    AT+BIND=98d3:31:204e02    // Address of the SLAVE above

    Switch the power off both modules and back on again, after a couple of handshakes the Bluetooth modules should pair up and create a Serial Bluetooth Tube.

    What ever you serial data you send at one end gets received at the other and Vice Versa.

    Its important to match the baud rate of your serial data to the speed of the BlueTooth link

    (in my case above my Atmel chip is sending Serial data @38400 Baud which then send over the Bluetooth link @38400 Baud and the receiver Atmel receives @38400).

    If you wish to speed up or slow down the Baud rate then issue these commands :-

    AT+UART                 // What is your Baud Rate?
    +UART:38400,0,0         // 38400 Baud 1stop bit no parity
    AT+UART=9600,0,0        // Set new Baud Rate to 9600 Baud 1 stop no parity

View all 18 project logs

  • 1
    Step 1

    Build Instructions.

    Print the 3D sole as your starting point . Downloaded from here

    0.2cm Z steps with 100% infill should do the trick.

  • 2
    Step 2

    Install the Piezo elements with long connecting wires (and just hop the common wire from sensor to sensor) , at the same time connect a 1Megohm resistor across each Piezo to discharge capacitive effects.

  • 3
    Step 3

    Build the 16 channel ADC module with the Arduino Pro Mini MCU, there are a number of variants .....

    1. Version MPC3008 (High speed)

    2. Version ADS1115 (High 16bit resolution) which is the current software supported solution.

    This type board configuration allowed 4 of them to be stacked together in parallel.

    Using this generic circuit :-

    Attach the Flying leads off the sensor to the ADC Banks as indicated above, and connect the common return wire from the Piezos to ground.

    I used a 3.3 Volts regulated supply using 2x 500ma/hr lipos.

View all 6 instructions

Enjoy this project?



naella wrote 03/06/2019 at 10:41 point

Hi, i really liked the project and im working on viewing heatmap also but using an arduino and FSR sensors, do you think the code would work with them ?

  Are you sure? yes | no

SangY wrote 07/13/2016 at 10:17 point

Hi, Chipro. glad to see you. I am Sang. I and couiple of my friends are lookinmg at insole with piezo sensors. Our goal is not to produce insoles, but we are more interested on information side collected from insoles. Anyway lets be in touch. BTW, do you use just PZT, or Single chrystal piezo ?  

  Are you sure? yes | no

chiprobot wrote 07/13/2016 at 13:48 point

Hoi Homeaway

I am using 16 Piezo crystal Elements (the cost effective type).

What application do you have in mind for the collected data ?.

  Are you sure? yes | no

SangY wrote 07/14/2016 at 03:19 point

we just started a smart-kit ptototype project for insoles or shoes. The reason we call it a smart-kit instead of smart insole is we just want to stay open to  future product form or the way we deliver it to users, but smart-kit itself looks very similar to yours.  Difference could be.. we use high-performance Single-chrystal piezo, cut much smaller than yours, to get more precise data.
Besides smart-kit, we plan to build mock-up platform to analyse data and turn it to reusable information blocks for users and 3rd parties who can add more value with their expertise. 

Your ideas on spin-offs make sense, and we also discussed most of those, but it's too early to decide, we just think it's time to focus on the prime goal of whether we can get precise data on GRF/Gait and exploit more information from big data we collect. 

  Are you sure? yes | no

Charles Fried wrote 06/07/2016 at 19:21 point

In the hope to contribute I though I would also share a pressure report which was very kindly carried out by my local orthotist on a high end RsScan system. It should give you an idea of the data you can expect. Although the values you get from a static system (RsScan) will be different than the ones from an insole sensor, hence the viability of it. I found a paper on this if you're interested.

  Are you sure? yes | no

chiprobot wrote 06/08/2016 at 07:24 point

Thanks Charles for the great link ... yes this is the style of presentation I am looking to create.

Bugbear at the moment is either to attach a tft screen to it (easy option) or write an APP for it (not so easy option however the "end product" way to go, I know nothing about writing app's hence the tft will happen in parallel just to get something to visualise) .

  Are you sure? yes | no

Joshua Hsu wrote 03/20/2018 at 21:51 point

Charles, I know this is almost two years later, but thank you. This link helped immensely for my team's project.

  Are you sure? yes | no

Charles Fried wrote 06/07/2016 at 18:54 point

I have another question if you don't mind, in regards to using SPI with two MCP3008.

Did you wire them in a similar fashion to this? 

If possible, I would love see the code.


  Are you sure? yes | no

chiprobot wrote 06/08/2016 at 07:14 point

Yes indeed exactly the way you indicate above. (code is in one of my Logs also above)

#define CLOCK_PIN 14
#define MOSI_PIN 13
#define MISO_PIN 12



pin 15 and 16 being the enable pins.

I tried to common the enable pins at the start as on some SPI devices you can pole multiple devices (i.e. the directing the shift register output of one 3008 into the shift register input of the second 3008 etcetcetc and scooting out the values this way meaning one enable pin to control multiple 3008's) however I was unable to "Borg" the necessary shift register assignments in the arduino library. (maybe I pick it up again to free up some pins).

  Are you sure? yes | no

jas wrote 06/07/2016 at 06:45 point

hi. Can we discuss about this more on my email or on whatsapp? 

We have been working on foot projects for quite sometime and can give you more inputs.


  Are you sure? yes | no

Charles Fried wrote 06/07/2016 at 18:51 point

I've just started my thesis project which involves building some insole pressure sensors, do you mind if I join the conversation?

  Are you sure? yes | no

chiprobot wrote 06/08/2016 at 07:32 point

Hi jas

Thanks for your interest in the project, It would be really useful if any inputs to the project are posted on this page, then the whole hackaday community will be able to benefit from your added knowledge.

Do you have a link to your foot projects ?... that would be great.

  Are you sure? yes | no

Charles Fried wrote 05/13/2016 at 20:22 point

This looks great however I'm a little intrigued about your choice of piezo sensors?  

Wouldn't a Flexiforce for example give you more accurate readings?

  Are you sure? yes | no

chiprobot wrote 05/23/2016 at 14:39 point

ermm Flexiforce is a piezo element!! it also cost circa $20/sensor. The ones I have cost $2 for 20.

  Are you sure? yes | no

Charles Fried wrote 05/23/2016 at 14:59 point

Ok that makes sense, I didn't know they used the same technology. I'm also looking to create something very similar. I'm intrigued to know a little more on how you intend to extrapolate the pressure between each sensor? Will you be writing an extra log on this?

  Are you sure? yes | no

chiprobot wrote 05/23/2016 at 15:09 point

Indeed it took me by surprise too.. I only found out after checking the sparkfuns Flexiforce range. At moment I am more concerned in creating a real time remote data transfer link .. With regards to the extrapolation, its still early days, as I currently try to get my head around creating its "APP" overlay which is slowing me down as I have little experience .... As I am visually orientated then the Gui hopefully will display a colour stress map .. so yes extra logs are for sure on the way.

  Are you sure? yes | no

Charles Fried wrote 05/24/2016 at 09:36 point

Nice, I'll be keeping a close eye on your progress.

If it helps at all, I'll be using Arduino + Processing for the GUI which seems like a good choice.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates