×

Arduino智能鞋垫来检查你的压力分布

消耗积分:0 | 格式:zip | 大小:0.10 MB | 2022-10-26

吴湛

分享资料个

描述

压力测量已经在各种情况下使用。它提供有关步态力学的信息并具有广泛的应用,例如在临床情况和运动中。在这个项目中,传感器用于深入了解重量分布。还包含压力映射的实时可视化,因为它使您更容易理解您的数据。

所需硬件

  • Arduino MKR1000 - 大多数带有 Wi-Fi 的 3.3V 或 5V 板都可以完成这项工作,但我不鼓励为此使用 ESP。由于某种原因,多个 ESP 板在创建此项目时返回了不准确的测量值。
  • 力敏电阻器 (3)。我使用了 Interlink 402 (100 N)。我还使用了更昂贵的 Interlink 406,但事后看来,402 也可以。使用更多 FSR 以获得更好的准确性。
  • 10K 电阻。更改电阻器以将读数缩放到您想要的范围内。电阻越高,增量越大。在此处查找更多信息。
  • 加速度计,我用的是 16G ADXL345。使用它来测量脚的加速度和运动。
  • 一个烙铁把它们放在一起。由于显而易见的原因,鳄鱼夹在鞋子中不能很好地工作。

接线

 
pYYBAGNYjcKAXNpPAAFYV9al5ao801.png
我们的硬件示意图
 

关于电路的一些快速说明:

FSR:在开始焊接之前阅读内容:将电线焊接到 FSR 时要格外小心。如果您不确定自己是否具备技能,请不要尝试这样做。您需要非常快速地焊接它,否则塑料会熔化。相信我,我发现它很困难......

FSR 没有正面或负面的一面,因此您不必担心。

正如我之前提到的,您可以更改电阻以将读数调整到您喜欢的范围内。

接地/5V:如您所见,所有传感器都焊接到 5V 线和公共端。

加速度计:如果您的项目不需要加速度计,您可以不使用它。如果您只是想测量压力,则不必使用它,但如果您想测量加速度,或者需要分析步态周期,它可能会派上用场。然而,这对于本教程并不是绝对必要的。

将硬件连接到鞋垫

我建议先运行代码后执行此操作,因为如果您犯了任何焊接错误,您会在那时发现它。如果您需要重新焊接任何东西,这可能会为您节省一些将硬件连接和重新连接到鞋垫的麻烦。

FSR 固定在鞋垫的三个点上。左上 FSR 测量外翻,右上 FSR 测量内翻,足跟处的 FSR 测量足跟压力。为您的 FSR 找到合适的位置是一个尝试的问题。安装它们的最佳位置是行走时模拟值变化最大的位置。

胶带用于将电线固定到位。如果它们移动,可能会干扰 FSR 读数。我还在鞋底底部和鞋内侧使用了魔术贴,以将鞋垫固定到位。

如果您使用加速度计,请将加速度计连接到鞋跟的后部。为此,我使用了双面胶带。

 
poYBAGNYjciAdwajAAjIoNdYEqA017.jpg
FSR的位置
 

测量力

现在我们都准备好测量力了。注意:在接下来的两节中,我假设您熟悉 Thinger.io 库。有关这方面的更多信息,请参阅标题为“通过 Thinger.io 发送数据”的部分。

该程序有相当长的标题部分,包括设置所需的变量,如 WiFi 连接数据。这部分还包括程序中使用的全局变量,主要是数组。我做出的一个重要选择是尽可能多地使用数组。这个想法是为每个 FSR 传感器使用单独的阵列元素。所以在这种情况下,数组的长度为 3。

不要养成使用太多全局变量的习惯,因为会有不必要的副作用。我们之所以使用它们,是因为在某些情况下,它们是通过Thinger.io发送数据所必需的。

代码在评论中解释。我们将逐步完成代码。您可以下载下面的完整代码。

#define _DEBUG_ //enables us to use the Serial Monitor
#include 
#include 
#include  //Accelerometer
#include  //Accelerometer
#include  //Accelerometer
#include 
#define USERNAME "yourUsername"
#define DEVICE_ID "yourDeviceID"
#define DEVICE_CREDENTIAL "yourDeviceCredential"
#define SSID "yourSSID"
#define SSID_PASSWORD "yourSSIDPassword"
//*FSR sensors*/
#define noFSRs 3 // Number of FSRs connected
#define FSR1 A1 
#define FSR2 A2 
#define FSR3 A3 
float fsrVoltageArray[3];       // The analog reading converted and scaled to voltage as a floating point number
float fsrForceArray[3];         // The force in Newton
float fsrWeightInGramsArray[3]; // Weight converted to grams
int   pinArray[3]       = {FSR1, FSR2, FSR3};    // The pin ID for the three devices
float forceMaxArray[3]  = {100.0, 100.0, 100.0}; // Maximum forces supported
float million = 1000000.0; // Unit for "1/micro
float conversionToKgrams = 1.0/9.80665;
long K       = 1000;
long R       = 10*K;    // R in K Ohm
long Vcc     = 5000;    // 5V=5000mV, 3.3V = 3300 mV
float voltageMax = 0.98 * Vcc; // Maximum voltage set to 95% of Vcc. Set the force to the maximum beyond this value.
ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

如果您还不了解所有内容,请不要惊慌。一旦你看过其余的代码,它就会更有意义。

我们想要可视化结果。为此,我们使用 Thinger.io Wi-Fi 库。此连接通过以下行设置:

ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

输入参数是通过您在 Thinger.io 上的帐户获得的,因此您需要先进行设置。

在 setup() 函数中,首先建立串行连接。随后调用创建 WiFi 连接。

void setup(void) {
 Serial.begin(115200); //Start Serial Communication
 thing.add_wifi(SSID, SSID_PASSWORD); //call to set up WiFi function
}
void loop(void) {
 thing.handle();
}

接下来,我们定义一个叫做“压力”的“事物”。“事物”是Thinger.io库中的一个关键概念。它的行为类似于函数,但具有特殊的结构。需要将结果数据发送到云端。有关此库的更多详细信息,请参阅“通过 Thinger.io 发送数据”部分。

称为“压力”的“事物”读取三个 FSR 传感器的值并将它们打印在串行控制台上。相同的值也被发送到“out”通道。通过这种方式,我们可以很容易地验证原始输入数据。

在名为“电压”的“事物”中,读取电压值并将其存储在名为“fsrReading”的局部变量中。使用“map”函数,该值相对于支持的最小值和最大值进行缩放,并返回到数组“fsrVoltageArray”中。通过 for 循环,我们确保每个 FSR 在这个结果数组中都有自己的位置。

请注意,所有代码都放在 setup 函数中。不要在循环中放任何东西(你可能已经习惯了)。Thinger.io库无法处理...

void setup(void) {
 Serial.begin(115200); //Start Serial Communication
 thing.add_wifi(SSID, SSID_PASSWORD); //call to set up WiFi function
  /*FSR sensors*/  
 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"] >> [](pson & out) {
   for (int FSR = 0; FSR < noFSRs; FSR++) {   
     fsrVoltageArray[FSR] = 0.0; // Reset values upon entry
     fsrForceArray[FSR]   = 0.0;
     int fsrPin   = pinArray[FSR];     
     int fsrReading = analogRead(fsrPin); 
     fsrVoltageArray[FSR] = (float) map(fsrReading, 0, 1023, 0, 5000); //change the 5000 to another value if you don't use a 5V device
   } //end of loop over FSR's
   out["FSR1voltage"] = fsrVoltageArray[0];
   out["FSR2voltage"] = fsrVoltageArray[1];
   out["FSR3voltage"] = fsrVoltageArray[2];
 };
void loop(void) {
 thing.handle();
  //Don't put any code here because Thinger.io won't like that.
}

在 for 循环完成后,这些值被发送到输出通道“out”。每个传感器都有一个唯一的字符串,例如“FSR1voltage”。

名为“newton”的“事物”是这个程序中最复杂的函数。它将电压转换为以牛顿为单位的力。再次使用 for 循环对每个 FSR 执行此操作。

计算相当复杂,因为我们需要区分几个极端情况。如果电压值太小或太大,我们为力分配一个固定值。如果电压在截止值之间,则使用对数函数来计算力。选择此功能是为了减小曲线的斜率。

请注意,这些公式只是近似值。每个传感器可能有(有些)不同的曲线,但为简单起见,我们在此不加以区分。

计算的结果值存储在数组“fsrForceArray”中。同样,每个 FSR 在此数组中都有自己的位置。三个最终值被发送到“out”输出通道。

最后的“事物”函数称为“权重”。应用直接转换以将力返回为以克为单位的重量。

thing["newton"] >> [](pson & out) {
   for (int FSR = 0; FSR < noFSRs; FSR++) {  
        // The value of the force F as a function of the voltage V is computed as: F(V) = (Fmax/Vmax) * V
        float force_value = (forceMaxArray[FSR]/voltageMax) * fsrVoltageArray[FSR];
        // Three situations are distinguished:
       //
        // 1. If V is too close to the maximum (as defined by voltageMax), the 
        //
        // 2. If the computed force F is too small, we set it to zero to avoidnoise effects.
        //
        // 3. In all other cases, we take the logarithmic value to reduce the sloop and
        if ( fsrVoltageArray[FSR] < voltageMax ) {
          // V is not too high in this branch
          if ( force_value <= 1.00 ) {
             fsrForceArray[FSR] = 0.0; // Force is too small, set it to zero
          } else {
            fsrForceArray[FSR] = log10(force_value); // Value is okay, take the log of this
          }
       } else {
          // Cap the force if the voltage is too close to Vcc (for Vcc it would be infinity)
          fsrForceArray[FSR] = log10(forceMaxArray[FSR]);
          Serial.print("Cut off activated for FSR = "); Serial.println(FSR);
       }
  } // End of loop over FSRs
     out["FSR1newton"] = fsrForceArray[0];
     out["FSR2newton"] = fsrForceArray[1];
     out["FSR3newton"] = fsrForceArray[2];
 }; //end of thing 
   thing["weight"] >> [](pson & out) {
   // Straightforward computation to convert the force in Newton to the weight in grams
   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];
 }; //end of thing

不要忘记在 Thinger.io 上设置仪表板。我假设你知道它是如何工作的。

提示:如果一切都按预期工作,您的仪表板应该如下所示:

 
poYBAGNYjcyAYkaRAAQzd1Ek0tM184.png
Thinger.io 仪表板
 

测量加速度

这实际上比测量压力要容易得多。我们需要先在标题部分添加一些代码。我们首先包括库“Wire.h”(为了与 SDA 和 SDL 引脚通信)、“Adafruit_Sensor.h”和“Adafruit_ADXL345_U.h”。我们还需要三个新的全局变量,这样我们就可以测量和传输 x、y 和 z 轴上的加速度

不要删除您之前添加的库。您将需要这些来连接到Thinger.io。

在下一个代码块中,我们检查加速度计是否响应。如果没有,什么都不会发生。否则,定义范围并执行称为“加速度计”的“事物”。这会查询设备并将 x、y 和 z 方向的三个加速度值发送到输出“out”通道。

这部分代码类似于 Adafruit 包含的示例代码(文件 > 示例 > Adafruit ADXL345),但我省略了一些部分,因为我们不需要它们。

#include 
#include 
#include 
/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
int x = 0;
int y = 0;
int z = 0;  
void setup(void) {
 Serial.begin(115200);
if(!accel.begin()) {   // Initialize the sensor
  Serial.println("No ADXL345 detected");
} else {
  // Range for this sensor - If you don't know the range run the
  // displayDataRate of the example code of the ADXL345 provided by Adafruit
  accel.setRange(ADXL345_RANGE_16_G);
 thing["accelerometer"] >> [](pson& out){ // A new "thing" function for Thinger.io
     sensors_event_t event;
     accel.getEvent(&event);  // Get a new sensor event
     out["x"] = event.acceleration.x;  // Display the results (acceleration is measured in m/s^2)
     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.print("  ");Serial.println("m/s^2 ");
 }; //end of thing
} //end of if/else statement
}

提示:运行上面的代码后,您的输出应该类似于下面显示的示例

 
poYBAGNYjdCAISgDAALs38MwRBM534.png
Thinger.io 中加速度计的输出
 

把它们放在一起

请在页面底部找到完整代码:)

通过 Thinger.io 发送数据

这个库在这里有很好的文档但这里有一些重要信息可以使“事物”(不是双关语)更容易编写和使用。

Thinger.io是一个非常广泛的库。在本节中,我们只介绍我们的应用程序中需要和使用的功能。结构如下(注意右花括号“}”后面的分号“;”):

thing[] >> [](pson& out)
   {
       <your code>
   };

这在 C++ 中称为 lambda 函数。开始定义的强制性第一个词是“事物”,整个功能也称为“事物”。

字符串(例如 thing["myFirstThing"] )为函数命名。每个“事物”都需要有一个唯一的名称。

“>>”符号表示这个“事物”只有输出值。如果需要输入,请将其更改为“<<”。如果需要输入和输出,则应使用“=”符号。在我们的例子中,我们只有输出值。

参数“pson &out”意味着我们的输出值是通过一个名为“out”的数据结构发送的。数据类型“pson”非常灵活,可以包含各种类型的变量,还支持JSON文档。

在我们的代码中,我们使用o 向与程序第一部分中的"out[] = value" t调用连接的可视化显示发送值的形式。"ThingerWifi101 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL)"

您可能已经注意到,循环函数内通常没有太多代码。你只需要调用“thing.handle()”。您也可以在循环部分调用端点和流资源。所有其他代码都在您定义的“事物”中处理。

“事物”中的代码不断循环。如果您的数据定期更新,就像我们的例子一样,将您的计算放在“事物”中很重要。

常问问题

什么都没发生!

检查你的电线。有可能在这个级别出现了问题。如果串行监视器中没有出现任何内容,请检查“#define _DEBUG_”是否在代码的第一行。TLS 也可能会产生干扰。您可以禁用它,但要小心。还要检查您与Thinger.io的连接是否正常。

输出不如预期

是否所有需要在“事物”中更新的代码?如果它在“事物”之外,则不会更新。我还发现 ESP 设备无缘无故无法与 FSR 传感器很好地配合使用。

输出没有定期更新_ _

您是否在代码中添加了任何延迟?删除它们 :) 您可以在Thinger.io本身上设置刷新率。

我希望将所有输​​出都放在一张图中

将所有代码添加到单个“事物”中

做得好!

我希望本教程能帮助您了解 FSR 传感器、加速度计和 Thinger.io 的基础知识。我很乐意阅读任何改进此代码的建议,请不要害羞并分享您的创作!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !