Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Componentes e Materiais

Ferramentas Necessárias

Aplicativos e Serviços Online

Sobre o Projeto

Medição de pressão plantar já é usada em diversas situações: informa mecânica da marcha, aplicações clínicas e esportivas. Este projeto usa sensores para entender distribuição de peso. Visualização em tempo real do mapeamento de pressão facilita compreensão dos dados.

Hardware Necessário

Ligação do Circuito

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Notas rápidas sobre o circuito:

FSRs — Leia antes de soldar: Seja extremamente cauteloso ao soldar fios nos FSRs. Não tente se não tem certeza da habilidade. Solda muito rápido ou o plástico derrete. Aprendi da pior forma...

FSR não tem polaridade (lado positivo/negativo).

Resistores podem ser alterados para escalar leituras.

Terra/5V: Todos sensores soldados na linha 5V e comum.

Acelerômetro: Pode omitir se não precisar. Não é estritamente necessário para medir pressão, mas ajuda na análise de aceleração/ciclo de marcha.

Fixando Hardware na Palmilha

Recomendo fazer isso após rodar o código primeiro, pois erros de solda serão detectados então, evitando refazer a fixação.

FSRs fixados em três pontos da palmilha: superior esquerdo (eversão), superior direito (inversão), calcanhar (pressão no calcanhar). Encontrar o melhor ponto é tentativa e erro: onde o valor analógico mais varia ao caminhar.

Fita adesiva prende os fios; movimento causa interferência nas leituras. Usei velcro na sola e dentro do sapato para fixar a palmilha.

Acelerômetro colado com fita dupla-face na parte traseira do calcanhar do sapato.

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Medindo as Forças

Agora pronto para medir forças. (Assumo familiaridade com biblioteca Thinger.io; veja seção "Enviar dados via Thinger.io").

Programa tem cabeçalho longo com variáveis de configuração (WiFi, credenciais Thinger.io) e arrays globais. Optei por arrays para cada sensor FSR (tamanho 3). Evite muitas variáveis globais por efeitos colaterais, mas necessárias para Thinger.io.

Código explicado nos comentários. Download do código completo ao final.

#define _DEBUG_ // habilita Serial Monitor
#include <WiFi101.h>
#include <ThingerWifi101.h>
#include <Wire.h> // Acelerômetro
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <Adafruit_NeoPixel.h>

#define USERNAME "seuUsuario"
#define DEVICE_ID "seuDeviceID"
#define DEVICE_CREDENTIAL "suaCredencial"
#define SSID "seuSSID"
#define SSID_PASSWORD "suaSenha"

// FSR sensors
#define noFSRs 3
#define FSR1 A1
#define FSR2 A2
#define FSR3 A3

float fsrVoltageArray[3];
float fsrForceArray[3];
float fsrWeightInGramsArray[3];
int pinArray[3] = {FSR1, FSR2, FSR3};
float forceMaxArray[3] = {100.0, 100.0, 100.0};
float million = 1000000.0;
float conversionToKgrams = 1.0/9.80665;
long K = 1000;
long R = 10*K; // R em kOhm
long Vcc = 5000; // 5V=5000mV, 3.3V=3300mV
float voltageMax = 0.98 * Vcc; // 95% de Vcc

ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

Conexão Thinger.io configurada via:

ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

Credenciais obtidas na sua conta Thinger.io.

No setup(), inicia serial e WiFi:

void setup(void) {
  Serial.begin(115200);
  thing.add_wifi(SSID, SSID_PASSWORD);
}
void loop(void) {
  thing.handle();
}

Definimos "things" (conceito chave Thinger.io) para enviar dados à nuvem. Cada "thing" é como uma função com estrutura especial.

Thing "pressure" lê valores brutos dos 3 FSRs e imprime no Serial; também envia ao canal "out".

thing["pressure"] >> [](pson & out) {
  out["FSR1"] = analogRead(FSR1);
  Serial.print("FSR1:"); Serial.println(analogRead(FSR1));
  out["FSR2"] = analogRead(FSR2);
  Serial.print("FSR2:"); Serial.println(analogRead(FSR2));
  out["FSR3"] = analogRead(FSR3);
  Serial.print("FSR3:"); Serial.println(analogRead(FSR3));
};

Thing "voltage" lê e escala tensão (0-5000mV) via map, armazena em fsrVoltageArray.

thing["voltage"] >> [](pson & out) {
  for (int FSR = 0; FSR < noFSRs; FSR++) {
    fsrVoltageArray[FSR] = 0.0;
    fsrForceArray[FSR] = 0.0;
    int fsrPin = pinArray[FSR];
    int fsrReading = analogRead(fsrPin);
    fsrVoltageArray[FSR] = (float) map(fsrReading, 0, 1023, 0, 5000); // ajuste 5000 se não 5V
  }
  out["FSR1voltage"] = fsrVoltageArray[0];
  out["FSR2voltage"] = fsrVoltageArray[1];
  out["FSR3voltage"] = fsrVoltageArray[2];
};

Thing "newton" — mais complexo: converte tensão para força em Newtons. Distingue casos limite: tensão muito alta (saturação), força muito pequena (ruído), caso normal (logaritmo para reduzir inclinação). Fórmulas aproximadas; cada sensor tem curva ligeiramente diferente, mas simplificamos.

thing["newton"] >> [](pson & out) {
  for (int FSR = 0; FSR < noFSRs; FSR++) {
    float force_value = (forceMaxArray[FSR]/voltageMax) * fsrVoltageArray[FSR];
    if (fsrVoltageArray[FSR] < voltageMax) {
      if (force_value <= 1.00) {
        fsrForceArray[FSR] = 0.0;
      } else {
        fsrForceArray[FSR] = log10(force_value);
      }
    } else {
      fsrForceArray[FSR] = log10(forceMaxArray[FSR]);
      Serial.print("Cut off activated for FSR = "); Serial.println(FSR);
    }
  }
  out["FSR1newton"] = fsrForceArray[0];
  out["FSR2newton"] = fsrForceArray[1];
  out["FSR3newton"] = fsrForceArray[2];
};

Thing "weight" — converte Newton para gramas.

thing["weight"] >> [](pson & out) {
  for (int FSR = 0; FSR < noFSRs; FSR++) {
    fsrWeightInGramsArray[FSR] = fsrForceArray[FSR] * conversionToKgrams * 1000.0;
  }
  out["FSR1weight"] = fsrWeightInGramsArray[0];
  out["FSR2weight"] = fsrWeightInGramsArray[1];
  out["FSR3weight"] = fsrWeightInGramsArray[2];
};

Configure dashboard no Thinger.io. Se tudo certo, parecerá com:

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Medindo Aceleração

Mais simples que pressão. Adicione bibliotecas Wire.h, Adafruit_Sensor.h, Adafruit_ADXL345_U.h e variáveis globais x,y,z.

No setup(), verifica sensor, define range 16G e cria thing "accelerometer" que envia aceleração x,y,z (m/s²) ao canal "out".

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
int x=0, y=0, z=0;

void setup(void) {
  Serial.begin(115200);
  if(!accel.begin()) {
    Serial.println("No ADXL345 detected");
  } else {
    accel.setRange(ADXL345_RANGE_16_G);
    thing["accelerometer"] >> [](pson& out){
      sensors_event_t event;
      accel.getEvent(&event);
      out["x"] = event.acceleration.x;
      out["y"] = event.acceleration.y;
      out["z"] = event.acceleration.z;
      Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" ");
      Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" ");
      Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.println(" m/s^2");
    };
  }
}

Saída esperada similar a:

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Juntando Tudo

Código completo no final da página.

Enviar Dados via Thinger.io

Biblioteca bem documentada aqui. Pontos-chave:

Estrutura (note ponto-e-vírgula após chave de fechamento):

thing["identificador"] >> [](pson& out) {
  // seu código
};

Chamada lambda function em C++. "thing" é palavra obrigatória. Identificador único por thing.

>> indica só saída. Entrada usa <<, bidirecional usa =. Nosso caso: só saída.

Argumento pson &out: estrutura de dados flexível (suporta JSON). Enviamos valores com out["chave_unica"] = valor.

Loop geralmente só chama thing.handle(). Cálculos ficam dentro dos "things" para atualização contínua.

Perguntas Frequentes

Nada acontece!
Verifique fiação. Se nada no Serial Monitor, confira se #define _DEBUG_ está na primeira linha. TLS pode interferir (desative com cuidado). Verifique conexão Thinger.io.
Saída diferente do esperado
Todo código que precisa atualizar está dentro de um "thing"? Fora não atualiza. Placas ESP não funcionam bem com FSRs por razão desconhecida.
Saída não atualiza regularmente
Removeu delay()? Taxa de atualização configurável no Thinger.io.
Quero tudo num gráfico só
Coloque todo código num único "thing".

Parabéns!

Espero que este tutorial ajude a entender FSRs, acelerômetros e Thinger.io. Adorarei sugestões de melhoria e ver suas criações!

Código

Smart-Insole-Tutorial (Arduino)

Código completo do tutorial

#define _DEBUG_ // Deve vir antes de qualquer include
/* Tutorial: https://www.hackster.io/projects/a5ceae */
#include <WiFi101.h>
#include <ThingerWifi101.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

#define USERNAME "seuUsuario"
#define DEVICE_ID "seuDevice"
#define DEVICE_CREDENTIAL "suaCredencial"
#define SSID "seuSSID"
#define SSID_PASSWORD "suaSenha"

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
int x=0, y=0, z=0;

#define noFSRs 3
#define FSR1 A1
#define FSR2 A2
#define FSR3 A3

float fsrVoltageArray[3];
float fsrForceArray[3];
float fsrWeightInGramsArray[3];
int pinArray[3] = {FSR1, FSR2, FSR3};
float forceMaxArray[3] = {100.0, 100.0, 100.0};
float million = 1000000.0;
float conversionToKgrams = 1.0/9.80665;
long K = 1000;
long R = 10*K;
long Vcc = 5000;
float voltageMax = 0.98 * Vcc;

ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

void setup(void) {
  Serial.begin(115200);
  thing.add_wifi(SSID, SSID_PASSWORD);
  if(!accel.begin()) {
    Serial.println("No ADXL345 detected.");
  } else {
    accel.setRange(ADXL345_RANGE_16_G);
    thing["accelerometer"] >> [](pson& out){
      sensors_event_t event;
      accel.getEvent(&event);
      out["x"] = event.acceleration.x;
      out["y"] = event.acceleration.y;
      out["z"] = event.acceleration.z;
    };
  }
  thing["pressure"] >> [](pson & out) {
    out["FSR1"] = analogRead(FSR1);
    out["FSR2"] = analogRead(FSR2);
    out["FSR3"] = analogRead(FSR3);
  };
  thing["voltage"] >> [](pson & out) {
    for (int FSR = 0; FSR < noFSRs; FSR++) {
      fsrVoltageArray[FSR] = 0.0;
      fsrForceArray[FSR] = 0.0;
      int fsrPin = pinArray[FSR];
      int fsrReading = analogRead(fsrPin);
      fsrVoltageArray[FSR] = (float) map(fsrReading, 0, 1023, 0, 5000);
    }
    out["FSR1voltage"] = fsrVoltageArray[0];
    out["FSR2voltage"] = fsrVoltageArray[1];
    out["FSR3voltage"] = fsrVoltageArray[2];
  };
  thing["newton"] >> [](pson & out) {
    for (int FSR = 0; FSR < noFSRs; FSR++) {
      float force_value = (forceMaxArray[FSR]/voltageMax) * fsrVoltageArray[FSR];
      if (fsrVoltageArray[FSR] < voltageMax) {
        if (force_value <= 1.00) {
          fsrForceArray[FSR] = 0.0;
        } else {
          fsrForceArray[FSR] = log10(force_value);
        }
      } else {
        fsrForceArray[FSR] = log10(forceMaxArray[FSR]);
        Serial.print("Cut off activated for FSR = "); Serial.println(FSR);
      }
    }
    out["FSR1newton"] = fsrForceArray[0];
    out["FSR2newton"] = fsrForceArray[1];
    out["FSR3newton"] = fsrForceArray[2];
  };
  thing["weight"] >> [](pson & out) {
    for (int FSR = 0; FSR < noFSRs; FSR++) {
      fsrWeightInGramsArray[FSR] = fsrForceArray[FSR] * conversionToKgrams * 1000.0;
    }
    out["FSR1weight"] = fsrWeightInGramsArray[0];
    out["FSR2weight"] = fsrWeightInGramsArray[1];
    out["FSR3weight"] = fsrWeightInGramsArray[2];
  };
}

void loop(void) {
  thing.handle();
}

Esquemáticos

Três FSRs (com divisores de tensão) e um acelerômetro.

Construa uma Palmilha Inteligente para Monitorar Precisamente a Distribuição de Pressão Plantar

Processo de manufatura

  1. Bartender Inteligente: Construa sua Própria Estação de Coquetéis com Raspberry Pi
  2. ABB Lança Sensor Inteligente para Monitorar Saúde de Rolamentos e Reduzir Downtime
  3. Evolução Casa Inteligente: O Que o Futuro Reserva para Vida Conectada
  4. Maximize o ROI em Seus Investimentos em IoT: Um Guia Prático
  5. Sistemas de Gestão de Edifícios: Impulsionando Cidades Inteligentes com IoT
  6. Medir Eficientemente o Uso de Memória de Objetos Python com sys.getsizeof()
  7. Check-up Trimestral de Saúde da Cadeia de Suprimentos: Garanta Operações Suaves
  8. Teste de Tempo de Reação Preciso com Arduino UNO
  9. Por Que a Bomba de Água da Sua Casa Está com Dificuldades: Causas Comuns e Soluções
  10. Minimize Perdas de Pressão no Seu Sistema de Ar Comprimido