亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino 101 - 英特尔居里图案搭配连衣裙

组件和用品

NeoPixel strip
可以用单独的 RGB LED 代替。
× 1
Arduino 101
× 1
SparkFun 按钮开关 12mm
× 1
电阻 10k ohm
× 1
跳线(通用)
您可能需要长电线将 LED 从您的肩膀引导到您的手。
× 1
9V 电池(通用)
× 1
9V to Barrel Jack Connector
× 1
Adafruit Flora RGB Neopixel LED - 4 个装
这可以用来替换 Neopixel 条。
× 1
可缝纫导电线
替换一些电线的选项。
× 1

必要的工具和机器

热胶枪(通用)
缝纫机(通用)
烙铁(通用)

应用和在线服务

Arduino IDE

关于这个项目

简介

我是一名工程师和艺术家,喜欢将科学与艺术相结合的项目。我一直在制作嵌入微控制器的服装设计,以便可以使用电子元件的某些功能来增强设计主题。对于这个项目,我想在 Arduino 101 上使用 Intel Curie 内部的模式匹配引擎 (PME) 和加速度计。 Curie 是为 PME 应用程序而设计的,因为它具有神经网络功能,但那里没有很多 PME 示例.我希望这个例子可以启发你提取 Curie 的 PME 能力。

这件衣服使用我的图画小说的一页作为面料。一位科学家和她的机器人正在看着望远镜。当穿着者在空中画一个图案时,一组排列成星座形状的LED灯就会在织物上的夜空闪耀。

说明

*注:此项目发布后,我对电子电路部分进行了翻新。在第 3 步之后,现在发布了一种将 LED 连接到布上的改进方法以及如何使它们耐用。

** 更新:穿着这件衣服参加一些全天的演示活动提供了对电池寿命的估计。为这件衣服供电,大约每 3 小时需要更换 9 V 电池。电池不会耗尽,但会降至 9 V 以下,这使得模式匹配效率低下。您可以将电池留作其他用途。

第一步

我使用了 Adafruit 的 NeoPixel 条带,将其切成碎片并将它们排列成星座的形状。随意使用其他类型的 LED,例如单独的 RGB LED。将它们粘在或缝在底布上。

步骤 2

在上面放一块接口织物,你可以勾勒出星座的轮廓。这一步是可选的,但我发现使用多层织物来加强结构很有帮助。我实际上在底布的背面缝了另一块厚布。所以总共三层作为基础,夹着LED。

步骤 3

焊接 LED。如果您使用可缝制的单个 LED,您还可以使用导电线将它们连接起来。无论哪种方式,都是大量的体力劳动,需要耐心。由于我有四个星座(猎户座、北斗七星、天鹅座和仙后座),我将它们分成了四个轨迹。每个都将连接到不同的 Arduino 101 引脚。

改进步骤

我用于上述步骤的织物太软,很容易弯曲 LED 和电线,破坏焊点。我用以下改进的方法重新完成了整个过程。

定位 LED

我使用了来自 Adafruit 的 NeoPixel 条带并将其切成碎片并将它们排列成星座的形状。随意使用其他类型的 LED,例如单独的 RGB LED。将它们粘在或缝在底布上。

毛毡是一种很好的厚织物,可以提供结构并且与热胶配合得很好。将LED排列在各自的位置,当它们点亮时,它们的位置会反射出星座中的星星。

规划 LED 和电线

在几个点将 LED 条纹粘在毛毡上。不要在整条胶条下面涂胶水,因为你需要一些余地来滑动热缩管,如图所示。将绞合线切割成合适的长度,并将它们放在同一块毛毡上的相对位置上。我建议暂时不要热粘合电线。我的数字在这方面是一个错误。相反,最好用临时胶带将电线固定在其位置,以便在将电线焊接到 LED 时,可以调整电线位置。

准备好缝制所有部件

图中显示我准备了四个星座(猎户座、北斗七星、天鹅座和仙后座)到四个独立的部分。在焊点周围焊接和热收缩后,您可以将所有东西紧紧地粘在毛毡上。

测试!

在继续之前测试您的电路!可以对每条轨迹进行 NeoPixel Strandtest。

好吧,我把这个级别设置为“简单”,因为从科学上讲,一旦你理解了代码并不难,但确实需要做很多工作来稳定织物上的电缆。

确保您的 Arduino IDE 是最新版本并且具有 Curie PME 库。我建议使用 Arduino Web 编辑器。在此处下载库。

做衣服

同时(比喻性地)制作这件衣服。测试电路后,将带有 LED 的底布缝到裙子的内侧。 LED 将通过图形发光。

如您所见,Arduino 101 在我手中。我为 Arduino 101 和电池制作了一个 3D 打印外壳。 LED和电路板之间有长线连接,隐藏在套管中。

下面的代码将为您提供有关如何对电路板进行编程的信息。刷入代码后,首先训练神经元,以便它们了解存在哪些模式。在 ~0:30 观看此视频:

如需更多照片和其他科技时尚/织物绘画设计,请查看我的网站 :)

代码

  • PME_4LED_new.ino
  • PME_LED
PME_4LED_new.inoArduino
这是上一个脚本的更新脚本。它存储训练数据。目前,它设置了一个初始化步骤。通电时,第一组 LED 显示红色。将 Arduino101 平放,USB 端口指向水平方向,同时按下按钮,允许在之前的培训中使用。松开按钮时,这些 LED 指示灯先变为绿色,然后变为蓝色,表明系统已准备就绪。如果将 Arduino101 保持在 USB 端口指向垂直方向,同时按下按钮,之前的训练数据将被删除。释放按钮后可以重新训练系统。
/* * 本示例演示使用模式匹配引擎 (CuriePME) * 对来自 CurieIMU 的加速度计数据流进行分类。 * * 首先,草图会提示你在空中画一些字母(想象一下你在一块看不见的白板上写字,用你的白板作为*笔),这些运动的IMU数据被用作训练数据* PME。训练完成后,您可以继续绘制字母,PME * 将尝试猜测您正在绘制哪个字母。 * * 此示例需要将按钮连接到数字引脚 4 * https://www.arduino.cc/en/Tutorial/Button * * 注意:为获得最佳效果,请绘制至少 1-2 英尺高的大字母。 * * 版权所有 (c) 2016 英特尔公司。版权所有。 * 请参阅文件末尾的许可通知。 */#include "CurieIMU.h"#include "CuriePME.h"#include #include #include #define PINM 6 //// NeoPixels 是什么引脚连接到?#define PINC 3#define PINS 9#define PINS 5 Adafruit_NeoPixel stripM =Adafruit_NeoPixel(10, PINM, NEO_GRB + NEO_KHZ800); /// 条带长 15 像素。您可以针对单个条带中的像素数更改此值。 , NEO_GRB + NEO_KHZ800);int tr =0; //一些变量来保存“颜色目标”和“颜色当前”以进行平滑...int tg =0;int tb =0;int r =0;int g =0;int b =0;int rawX =0; ///// 保存居里加速度计的值int rawY =0;//int rawZ =0;float angle =0.0;/* 这控制了在训练期间必须绘制字母的次数。 * 任何高于 4 的数字,您可能没有足够的神经元来容纳字母表中的所有 26 个字母 *。低于 4 意味着您训练字母的工作更少,*但 PME 可能更难对字母进行分类。 */const unsigned int trainingReps =4;/* 如果你愿意,可以将其增加到 'AZ'——只是需要更长的时间来训练 */const unsigned char trainingStart ='A';const unsigned char trainingEnd ='D'; /* 用于在绘制字母时发出信号的输入引脚 - 你*需要确保一个按钮连接到这个引脚 */const unsigned int buttonPin =4;/* 加速度计的采样率 */const unsigned int sampleRateHZ =200;/* 一个神经元可以容纳的字节数 */const unsigned int vectorNumBytes =128;/* 处理的样本数 (1 sample ==accel x, y, z) * 可以容纳在一个神经元内部 * /const unsigned int samplesPerVector =(vectorNumBytes / 3);/* 该值用于将 ASCII 字符 AZ * 转换为十进制值 1-26,然后再返回。 */const unsigned int upperStart =0x40;const unsigned int sensorBufSize =2048;const int IMUlow =-32768;const int IMUHigh =32767;const char *filename ="NeurDataDress.dat";void setup(){ Serial.begin(9600) ); //while(!Serial); pinMode(buttonPin, INPUT); /* 启动 IMU (Intertial Measurement Unit) */ CurieIMU.begin(); /* 启动 PME(模式匹配引擎)*/ CuriePME.begin(); CurieIMU.setAccelerometerRate(sampleRateHZ); CurieIMU.setAccelerometerRange(2); /* 在里面。 SPI Flash 芯片 */ if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)) { Serial.println("无法访问 SPI Flash 芯片"); } stripM.begin(); // 初始化新像素条 stripS.begin(); stripC.begin(); stripO.begin(); stripM.show(); // 将所有像素初始化为 'off' stripS.show(); stripC.show(); stripO.show(); solidM(stripM.Color(255, 0, 0), 50); //红色为准备好输入}/* 该函数读取上一个例子保存的文件 * 该文件包含所有学习到的数据,然后保存。 * 网络恢复后,无需重新训练即可再次对模式进行分类。*/void restoreNetworkKnowledge ( void ){ SerialFlashFile file; int32_t fileNeuronCount =0; Intel_PMT::neuronData 神经元数据; // 打开文件并写入测试数据 file =SerialFlash.open(filename); CuriePME.beginRestoreMode(); if (file) { // 遍历网络并保存数据。 while(1) { Serial.print("阅读神经元:"); uint16_t 神经元场[4]; file.read((空*)神经元场,8); file.read((void*)neuronData.vector, 128);神经元数据.context =神经元字段[0]; NeuronData.influence =神经元场[1];神经元数据.minInfluence =神经元字段[2];神经元数据.category =神经元字段[3]; if (neuronFields[0] ==0 ||neuronFields[0]> 127) 中断;文件神经元计数++; // 这部分只是在每个神经元恢复时打印出来, // 这样你就可以看到发生了什么。 Serial.print(fileNeuronCount); Serial.print("\n"); Serial.print(neuronFields[0]); Serial.print("\t"); Serial.print(neuronFields[1]); Serial.print("\t"); Serial.print(neuronFields[2]); Serial.print("\t"); Serial.print(neuronFields[3]); Serial.print("\t"); Serial.print(neuronData.vector[0]); Serial.print("\t"); Serial.print(neuronData.vector[1]); Serial.print("\t"); Serial.print(neuronData.vector[2]); Serial.print("\n"); CuriePME.iterateNeuronsToRestore(neuronData); CuriePME.endRestoreMode(); Serial.print("Knowledge Set Restored.\n");}boolean longPress=false;int startTime=0;int lastOrientation =- 1; // 前一个方向(用于比较)int lastReading =-1;boolean lastPress=false;void loop(){ intorientation =- 1; // 板的方向 StringorientationString; // 用于打印方向描述的字符串 // 板的方向: // 0:平面,处理器朝上 // 1:平面,处理器朝下 // 2:横向,模拟引脚向下 // 3:横向,模拟引脚向上 // 4:纵向,USB 连接器向上 // 5:纵向,USB 连接器向下 // 读取加速度计:int x =CurieIMU.readAccelerometer(X_AXIS); int y =CurieIMU.readAccelerometer(Y_AXIS); int z =CurieIMU.readAccelerometer(Z_AXIS); // 计算绝对值,确定最大的 int absX =abs(x); int absY =abs(y); int absZ =abs(z); if ( (absZ> absX) &&(absZ> absY)) { // 基于 Z 的基本方向 if (z> 0) {orientationString ="up";方向 =0; } else {orientationString ="向下";方向 =1; } } else if ( (absY> absX) &&(absY> absZ)) { // Y 的基本方向 if (y> 0) {orientationString ="digital pin up";方向 =2; } else {orientationString ="模拟引脚向上";方向 =3; } } else { // X 上的基本方向 if (x <0) {orientationString ="connector up";方向 =4; } else {orientationString ="连接器向下";方向 =5; } } // 如果方向改变了,打印出一个描述: if (orientation !=lastOrientation) { Serial.println(orientationString); lastOrientation =方向; } // 如果方向改变了,打印出一个描述: if (orientation !=lastOrientation) { lastOrientation =orientation; } int reading =digitalRead(buttonPin); if (lastReading !=reading) { Serial.print("buttonPin="); Serial.println(阅读); lastReading =阅读; } if (reading ==HIGH) { if (startTime ==0) { startTime=millis(); } else if ((millis() - startTime)>2000) { longPress=true; if (!lastPress) { Serial.println("longPress"); //绿色表示长按solidM(stripM.Color(0, 255, 0), 50);// Green lastPress=true; } } } if ( reading ==LOW &&longPress ) { blackout(5); Serial.print("方向="); Serial.print(方向); Serial.print(" SerialFlash.exists(filename)="); Serial.println(SerialFlash.exists(filename)); if (orientation!=4 &&SerialFlash.exists(filename)) { restoreNetworkKnowledge(); Serial.print("训练恢复。"); } else { trainLetters();停电(5); Serial.print("训练完成。"); } Serial.println("现在,画一些字母(记住"); Serial.println("按住按钮),看看PME是否可以对它们进行分类。"); solidM(stripM.Color(0, 0, 255), 500); //蓝色准备匹配停电(5); //关闭匹配 while (true) { match(); } }}void solidM(uint32_t c, uint8_t wait) { for (uint16_t i=0; i  (num * 3) - (step * 3)) { ret =samples[pos]; } else { ret =0; pos -=(步骤* 3); for (unsigned int i =0; i  sensorBufSize) { break; } } } undersample(accel, samples, vector);}void trainLetter(char letter, unsigned int repeat){ unsigned int i =0; while (i  
PME_LEDArduino
这是使用居里 PME 来控制 LED。它基本上是 Draw in the Air PME 代码和 Adafruit NeoPixel 示例代码的组合。这段代码不是我使用的(有点复杂),因为我怀疑你会做出完全相同的星座排列。相反,这是一个通用代码,您可以对其进行修改以个性化您的需求,例如您可以更改如何为不同的 LED 灯条分配引脚。我以后可能会用改进的代码更新它。
/* * 这个例子演示了使用模式匹配引擎 (CuriePME) * 对来自 CurieIMU 的加速度计数据流进行分类。代​​码是对 Draw in the Air 示例的修改: * https://github.com/01org/Intel-Pattern-Matching-Technology * * 首先,草图会提示您在空中绘制图案(想象一下您正在隐形白板上书写,使用您的白板作为* pen),并且来自这些运​​动的 IMU 数据用作 * PME 的训练数据。训练完成后,您可以继续绘制字母,PME * 将尝试猜测您正在绘制哪个字母。 * * 此示例需要将按钮连接到数字引脚 4 * https://www.arduino.cc/en/Tutorial/Button * * 注意:为获得最佳效果,请绘制至少 1-2 英尺高的大字母。 * * 版权所有 (c) 2016 英特尔公司。版权所有。 * 请参阅文件末尾的许可通知。 */#include "CurieIMU.h"#include "CuriePME.h"#include #define PIN 6 //// what pin are the NeoPixels connected to?Adafruit_NeoPixel strip =Adafruit_NeoPixel(54, PIN, NEO_GRB + NEO_KHZ800); /// 条带长 15 像素。您可以根据自己的 strip.int tr =0; 中的像素数更改此设置。 //一些变量来保存“颜色目标”和“颜色当前”以进行平滑...int tg =0;int tb =0;int r =0;int g =0;int b =0;int rawX =0; ///// to hold values from the Curie's accelerometerint rawY =0;//int rawZ =0;float angle =0.0;/* This controls how many times a letter must be drawn during training. * Any higher than 4, and you may not have enough neurons for all 26 letters * of the alphabet. Lower than 4 means less work for you to train a letter, * but the PME may have a harder time classifying that letter. */const unsigned int trainingReps =4;/* Increase this to 'A-Z' if you like-- it just takes a lot longer to train */const unsigned char trainingStart ='A';const unsigned char trainingEnd ='D';/* The input pin used to signal when a letter is being drawn- you'll * need to make sure a button is attached to this pin */const unsigned int buttonPin =4;/* Sample rate for accelerometer */const unsigned int sampleRateHZ =200;/* No. of bytes that one neuron can hold */const unsigned int vectorNumBytes =128;/* Number of processed samples (1 sample ==accel x, y, z) * that can fit inside a neuron */const unsigned int samplesPerVector =(vectorNumBytes / 3);/* This value is used to convert ASCII characters A-Z * into decimal values 1-26, and back again. */const unsigned int upperStart =0x40;const unsigned int sensorBufSize =2048;const int IMULow =-32768;const int IMUHigh =32767;void setup(){ Serial.begin(9600); // while(!Serial); pinMode(buttonPin, INPUT); /* Start the IMU (Intertial Measurement Unit) */ CurieIMU.begin(); /* Start the PME (Pattern Matching Engine) */ CuriePME.begin(); CurieIMU.setAccelerometerRate(sampleRateHZ); CurieIMU.setAccelerometerRange(2); trainLetters(); //Serial.println("Training complete. Now, draw some letters (remember to "); // Serial.println("hold the button) and see if the PME can classify them."); strip.begin(); // 初始化新像素条 strip.show(); // Initialize all pixels to 'off'}void loop (){ /// these functions are written out at the bottom of the sketch. Serial.println("Training complete. Now, draw some letters (remember to ");Serial.println("hold the button) and see if the PME can classify them."); byte vector[vectorNumBytes]; unsigned int category; char letter; char pattern; /* Record IMU data while button is being held, and * convert it to a suitable vector */ readVectorFromIMU(vector); /* Use the PME to classify the vector, i.e. return a category * from 1-26, representing a letter from A-Z */ category =CuriePME.classify(vector, vectorNumBytes); if (category ==CuriePME.noMatch) { Serial.println("Don't recognise that one-- try again."); //theaterChase(); theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); // delay(10); } else { letter =category + upperStart; pattern =letter; if ( pattern =='A' ) { //red colorWipe(strip.Color(0, 255, 0), 50); // Green theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='B') { colorWipe(strip.Color(255, 0, 0), 50); // Red theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='C') { colorWipe(strip.Color(0, 0, 255), 50); // Blue theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='D') { colorWipe(strip.Color(255, 0, 255), 50); // Blue theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); }Serial.println(letter); } }/* Simple "moving average" filter, removes low noise and other small * anomalies, with the effect of smoothing out the data stream. */byte getAverageSample(byte samples[], unsigned int num, unsigned int pos, unsigned int step){ unsigned int ret; unsigned int size =step * 2; if (pos <(step * 3) || pos> (num * 3) - (step * 3)) { ret =samples[pos]; } else { ret =0; pos -=(step * 3); for (unsigned int i =0; i  sensorBufSize) { break; } } } undersample(accel, samples, vector);}void trainLetter(char letter, unsigned int repeat){ unsigned int i =0; while (i  

示意图

It's just connecting the LEDs to the Arduino 101 pins and a button to pin 4 (as described in the code:https://www.arduino.cc/en/Tutorial/Button). The circuit diagram is similar to this Fritzing from Adafruit:https://learn.adafruit.com/adafruit-neopixel-uberguide/basic-connections
I plugged the 9 V battery directly into the barrel jack.

制造工艺

  1. 服装图案
  2. 构建没有跳线的 Arduino 面包板
  3. 带 LED 和压电扬声器的 DHT11 传感器
  4. Arduino Spybot
  5. FlickMote
  6. 自制电视 B-Gone
  7. 主时钟
  8. Arduino + LEDs + MIDI 键盘 + MuseScore =Piano Tutor
  9. Alexa 通过 Raspberry Pi 控制 LED
  10. 找到我
  11. Arduino Power
  12. 英特尔 Arduino 101 BLE Blynk Tank