Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Arduino 101 - Robe assortie à motif Intel Curie

Composants et fournitures

Bande NeoPixel
Peut être remplacé par des LED RVB individuelles.
× 1
Arduino 101
× 1
Interrupteur à bouton-poussoir SparkFun 12mm
× 1
Résistance 10k ohm
× 1
Câbles de raccordement (générique)
Vous aurez peut-être besoin de longs fils pour guider les LED de votre épaule à votre main.
× 1
Batterie 9V (générique)
× 1
Connecteur 9V vers Barrel Jack
× 1
LED Adafruit Flora RGB Neopixel - Pack de 4
Ceci peut être utilisé pour remplacer la bande Neopixel.
× 1
Fil conducteur à coudre
Option pour remplacer certains fils.
× 1

Outils et machines nécessaires

Pistolet à colle chaude (générique)
machine à coudre (générique)
Fer à souder (générique)

Applications et services en ligne

Arduino IDE

À propos de ce projet

Présentation

Je suis un ingénieur et un artiste qui aime les projets qui combinent la science et les arts. J'ai créé des modèles de vêtements avec des microcontrôleurs intégrés afin que certaines fonctionnalités des composants électroniques puissent être utilisées pour améliorer le thème de la conception. Pour ce projet, je souhaite utiliser le moteur de correspondance de motifs (PME) et l'accéléromètre à l'intérieur d'Intel Curie sur Arduino 101. Curie est conçu pour les applications PME car il a une capacité de réseau neuronal mais il n'y a pas eu beaucoup d'exemples PME là-bas . J'espère que cet exemple pourra vous inspirer pour extraire la capacité PME de Curie.

La robe utilise une page de mon roman graphique comme tissu. Une scientifique et son robot regardent dans le télescope. Au fur et à mesure que le porteur dessine un motif dans l'air, un ensemble de LED disposées en forme de constellations brillera dans le ciel nocturne sur le tissu.

Mode d'emploi

*Remarque :suite à la publication de ce projet, j'ai rénové la partie circuit électronique. Une méthode améliorée pour attacher les LED au tissu et comment les rendre durables est maintenant publiée ci-dessous après l'étape 3.

** Mise à jour :porter cette robe pour quelques événements de démonstration toute la journée a fourni une estimation de la durée de vie de la batterie. Pour alimenter cette robe, la pile 9 V doit être changée environ toutes les 3 heures. La batterie ne se décharge pas mais elle descend en dessous de 9 V, ce qui la rend inefficace pour faire la correspondance de motif. Vous pouvez économiser la batterie pour d'autres utilisations.

Étape 1

J'ai utilisé une bande NeoPixel d'Adafruit, je l'ai découpée en morceaux et je les ai disposées en forme de constellations. N'hésitez pas à utiliser d'autres types de LED telles que les LED RVB individuelles. Collez-les ou cousez-les sur le tissu de base.

Étape 2

Mettez un tissu d'entoilage sur le dessus et vous pourrez délimiter les constellations. Cette étape est facultative mais j'ai trouvé utile d'avoir plusieurs couches de tissus pour renforcer la structure. J'ai en fait cousu un autre tissu épais sur le dos du tissu de base. Donc trois couches au total comme base, prenant en sandwich les LED.

Étape 3

Soudez les LED. Si vous utilisez les LED individuelles cousables, vous pouvez également utiliser des fils conducteurs pour les connecter. Dans tous les cas, c'est beaucoup de travail manuel et demande de la patience. Comme j'ai quatre constellations (Orion, Grande Ourse, Cygnus et Cassiopée), je les ai séparées en quatre traces. Chacun sera connecté à une broche Arduino 101 différente.

Étapes améliorées

Le tissu que j'ai utilisé pour les étapes ci-dessus était trop doux, ce qui permet de plier facilement les LED et les fils, brisant les joints de soudure. J'ai refait tout le processus avec la méthode améliorée suivante.

Positionnez les LED

J'ai utilisé une bande NeoPixel d'Adafruit, je l'ai découpée en morceaux et je les ai disposées en forme de constellations. N'hésitez pas à utiliser d'autres types de LED telles que les LED RVB individuelles. Collez-les ou cousez-les sur le tissu de base.

Le feutre est un beau type de tissu épais qui donne de la structure et fonctionne bien avec de la colle chaude. Disposez les LED dans des positions respectives de sorte que lorsqu'elles s'allument, leurs positions reflètent les étoiles dans les constellations.

Planifiez les LED et les fils

Collez les bandes LED sur le feutre en quelques points. Ne pas mettre de colle sous toute la bande car il faut une certaine marge de manœuvre pour faire coulisser les tubes thermorétractables, comme indiqué sur la figure. Coupez les fils toronnés dans les bonnes longueurs et placez-les sur leurs positions relatives sur le même morceau de feutre. Je recommanderais de ne pas coller les fils à chaud pour l'instant. Mon chiffre ici est une bévue à cet égard. Au contraire, il est préférable de maintenir les fils dans leurs positions avec du ruban adhésif temporaire afin que lorsque vous soudez les fils aux LED, les positions des fils puissent être ajustées.

Préparez toutes les pièces à coudre

La figure montre que j'ai préparé quatre constellations (Orion, Grande Ourse, Cygnus et Cassiopée) sur quatre pièces distinctes. Après avoir soudé et thermorétracté autour des joints soudés, vous pouvez tout coller fermement sur le feutre.

A tester !

Testez votre circuit avant d'aller plus loin ! Peut juste faire un NeoPixel Strandtest pour chaque trace.

D'accord, j'ai mis le niveau sur "Facile" car scientifiquement ce n'est pas difficile une fois que vous avez compris le code, mais cela demande beaucoup de travail pour stabiliser les câbles sur le tissu.

Assurez-vous que votre IDE Arduino est la dernière version et dispose de la bibliothèque Curie PME. Je recommanderais d'utiliser l'éditeur Web Arduino. Téléchargez la bibliothèque ici.

Faire la robe

En parallèle (au sens figuré), confectionnez la robe. Après avoir testé le circuit, cousez les tissus de base avec les LED à l'intérieur de la robe. Les LED brilleront à travers les graphiques.

Comme vous pouvez le voir, l'Arduino 101 est dans ma main. J'ai fait un boîtier imprimé en 3D pour l'Arduino 101 et la batterie. Il y a de longs fils reliant les LED et la carte, qui sont cachés dans le manchon.

Le code ci-dessous vous donnera des informations sur la façon dont la carte est programmée. Après avoir flashé le code, entraînez d'abord les neurones afin qu'ils sachent quels modèles sont présents. Regardez cette vidéo à ~0:30 :

Pour plus de photos et d'autres conceptions tech-mode/peintures sur tissu, consultez mon site Web :)

Code

  • PME_4LED_new.ino
  • PME_LED
PME_4LED_new.inoArduino
Il s'agit d'un script mis à jour par rapport au précédent. Il stocke les données d'entraînement. Actuellement, il est configuré avec une étape d'initialisation. La première série de LED s'affiche en rouge lorsque l'appareil est sous tension. Tenir l'Arduino101 à plat avec le port USB pointant dans le sens horizontal, tout en appuyant sur le bouton, permet l'utilisation de la formation précédente. Ces LED passent au vert puis au bleu lorsque le bouton est relâché, indiquant que le système est prêt. Si l'Arduino101 est tenu avec le port USB pointant dans une direction verticale, tout en appuyant sur le bouton, les données d'entraînement précédentes sont effacées. Le système peut être réformé en relâchant le bouton.
/* * Cet exemple illustre l'utilisation du moteur de correspondance de modèles (CuriePME) * pour classer les flux de données d'accéléromètre de CurieIMU. * * Tout d'abord, le croquis vous invitera à dessiner des lettres dans les airs (imaginez simplement que vous écrivez sur un tableau blanc invisible, en utilisant votre tableau comme * stylo), et les données IMU de ces mouvements sont utilisées comme données d'entraînement pour le * PME. Une fois la formation terminée, vous pouvez continuer à dessiner des lettres et le PME* essaiera de deviner quelle lettre vous dessinez. * * Cet exemple nécessite qu'un bouton soit connecté à la broche numérique 4 * https://www.arduino.cc/en/Tutorial/Button * * REMARQUE :pour de meilleurs résultats, dessinez de grosses lettres, d'au moins 1 à 2 pieds de haut. * * Copyright (c) 2016 Intel Corporation. Tous les droits sont réservés. * Voir avis de licence à la fin du fichier. */#include "CurieIMU.h"#include "CuriePME.h"#include #include #include #define PINM 6 //// quelle broche sont les NeoPixels connecté à ?#define PINC 3#define PINS 9#define PINO 5 Adafruit_NeoPixel stripM =Adafruit_NeoPixel (10, PINM, NEO_GRB + NEO_KHZ800); /// la bande fait 15 pixels de long. Vous pouvez changer cela pour le nombre de pixels dans votre bande individuelle.Adafruit_NeoPixel stripS =Adafruit_NeoPixel(10, PINS, NEO_GRB + NEO_KHZ800);Adafruit_NeoPixel stripC =Adafruit_NeoPixel(10, PINC, NEO_GRB + NEO_KHZZ800);Adafruit_NeoPixel stripC =Adafruit_NeoPixel(10, PINC, NEO_GRB + NEO_KHZZ800); , NEO_GRB + NEO_KHZ800);int tr =0; //Certaines variables pour contenir "color-target" et "color-current" pour le lissage...int tg =0;int tb =0;int r =0;int g =0;int b =0;int rawX =0 ; ///// pour conserver les valeurs de l'accéléromètre de Curieint rawY =0;//int rawZ =0;float angle =0.0;/* Ceci contrôle combien de fois une lettre doit être dessinée pendant l'entraînement. * Tout supérieur à 4, et vous n'aurez peut-être pas assez de neurones pour les 26 lettres * de l'alphabet. Moins de 4 signifie moins de travail pour vous former une lettre, * mais le PME peut avoir plus de mal à classer cette lettre. */const unsigned int trainingReps =4;/* Augmentez ceci à 'AZ' si vous le souhaitez-- cela prend juste beaucoup plus de temps à former */const unsigned char trainingStart ='A';const unsigned char trainingEnd ='D'; /* La broche d'entrée utilisée pour signaler quand une lettre est dessinée - vous devrez * vous assurer qu'un bouton est attaché à cette broche */const unsigned int buttonPin =4;/* Taux d'échantillonnage pour l'accéléromètre */const unsigned int sampleRateHZ =200;/* Nombre d'octets qu'un neurone peut contenir */const unsigned int vectorNumBytes =128;/* Nombre d'échantillons traités (1 échantillon ==accel x, y, z) * pouvant tenir dans un neurone * /const unsigned int samplesPerVector =(vectorNumBytes / 3);/* Cette valeur est utilisée pour convertir les caractères ASCII AZ * en valeurs décimales 1-26, et inversement. */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 ); //pendant que(!Série); pinMode(boutonPin, INPUT); /* Démarrer l'IMU (Intertial Measurement Unit) */ CurieIMU.begin(); /* Démarrer le PME (Pattern Matching Engine) */ CuriePME.begin(); CurieIMU.setAccelerometerRate(sampleRateHZ); CurieIMU.setAccelerometerRange(2); /* Init. Puce SPI Flash */ if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)) { Serial.println("Impossible d'accéder à la puce SPI Flash"); } stripM.begin(); // initialiser la bande néopixel stripS.begin(); stripC.begin(); stripO.begin(); stripM.show(); // Initialise tous les pixels sur 'off' stripS.show(); stripC.show(); stripO.show(); solideM(bandeM.Couleur(255, 0, 0), 50); //Rouge pour prêt pour la saisie}/* Cette fonction lit le fichier sauvegardé par l'exemple précédent * Le fichier contient toutes les données qui ont été apprises, puis sauvegardées auparavant. * Une fois le réseau restauré, il est capable de classer à nouveau les modèles sans * devoir être recyclé.*/void restoreNetworkKnowledge ( void ){ SerialFlashFile file; int32_t fileNeuronCount =0; Intel_PMT::neuronData neuronData; // Ouvrir le fichier et écrire le fichier de données de test =SerialFlash.open(filename); CuriePME.beginRestoreMode(); if (file) { // itérer sur le réseau et enregistrer les données. while(1) { Serial.print("Reading Neuron:"); uint16_t neuronFields[4]; file.read( (void*) neuronFields, 8); file.read( (void*) neuronData.vector, 128 ); neuronData.context =neuronFields[0]; neuronData.influence =neuronFields[1]; neuronData.minInfluence =neuronFields[2]; neuronData.category =neuronFields[3] ; si (neuronFields[0] ==0 || neuronFields[0]> 127) pause ; fileNeuronCount++ ; // cette partie imprime simplement chaque neurone au fur et à mesure qu'il est restauré, // afin que vous puissiez voir ce qui se passe. 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; // orientation précédente (pour comparaison)int lastReading =-1;boolean lastPress=false;void loop (){ int orientation =- 1; // l'orientation du tableau String orientationString; // chaîne pour imprimer la description de l'orientation // Les orientations de la carte :// 0 :plat, processeur vers le haut // 1 :plat, processeur vers le bas // 2 :paysage, broches analogiques vers le bas // 3 :paysage, analogique broches vers le haut // 4:portrait, connecteur USB vers le haut // 5:portrait, connecteur USB vers le bas // accéléromètre de lecture:int x =CurieIMU.readAccelerometer(X_AXIS); int y =CurieIMU.readAccelerometer(Y_AXIS); int z =CurieIMU.readAccelerometer(Z_AXIS); // calcule les valeurs absolues, pour déterminer le plus grand int absX =abs(x); int absY =abs(y); int absZ =abs(z); if ( (absZ> absX) &&(absZ> absY)) { // orientation de base sur Z if (z> 0) { orientationString ="up"; orientation =0; } else { orientationString ="vers le bas"; orientation =1 ; } } else if ( (absY> absX) &&(absY> absZ)) { // orientation de base sur Y if (y> 0) { orientationString ="digital pin up"; orientation =2; } else { orientationString =« pince analogique vers le haut » ; orientation =3; } } else { // baser l'orientation sur X if (x <0) { orientationString ="connector up"; orientation =4; } else { orientationString ="connecteur vers le bas"; orientation =5; } } // si l'orientation a changé, affiche une description :if (orientation !=lastOrientation) { Serial.println(orientationString); lastOrientation =orientation; } // si l'orientation a changé, imprime une description :if (orientation !=lastOrientation) { lastOrientation =orientation; } lecture int =digitalRead(buttonPin); if (lastReading !=lecture) { Serial.print("buttonPin="); Serial.println(lecture); lastReading =lecture ; } if (lecture ==HIGH) { if (startTime ==0) { startTime=millis(); } else if ((millis() - startTime)>2000) { longPress=true; if (!lastPress) { Serial.println("longPress"); //vert pour un appui long solidM(stripM.Color(0, 255, 0), 50); // Vert lastPress=true; } } } if ( lecture ==LOW &&longPress ) { blackout(5); Serial.print("orientation="); Serial.print(orientation); Serial.print(" SerialFlash.exists(filename)="); Serial.println(SerialFlash.exists(nom de fichier)); if (orientation!=4 &&SerialFlash.exists(nom de fichier)) { restoreNetworkKnowledge(); Serial.print("Formation restaurée."); } else { trainLetters(); panne d'électricité (5) ; Serial.print("Formation terminée."); } Serial.println(" Maintenant, dessinez quelques lettres (rappelez-vous "); Serial.println(" maintenez le bouton enfoncé) et voyez si le PME peut les classer. "); solideM(bandeM.Couleur(0, 0, 255), 500); //Bleu pour prêt pour la correspondance blackout(5) ; //désactiver pour la correspondance while (true) { match(); } }}void solidM(uint32_t c, uint8_t wait) { for (uint16_t i=0; i  (num * 3) - (étape * 3)) { ret =échantillons[pos]; } else { ret =0; pos -=(étape * 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
Il s'agit d'utiliser le Curie PME pour contrôler les LED. Il s'agit essentiellement d'une combinaison du code Draw in the Air PME et de l'exemple de code Adafruit NeoPixel. Ce code n'est pas exactement ce que j'ai utilisé (ce qui est un peu complexe) car je doute que vous fassiez exactement le même type d'arrangement de constellation. Voici plutôt un code générique que vous pouvez modifier pour personnaliser votre besoin, par ex. vous pouvez changer la façon de distribuer les broches pour les différentes bandes LED. Je peux le mettre à jour avec un code amélioré plus tard.
/* * Cet exemple illustre l'utilisation du moteur de correspondance de modèles (CuriePME) * pour classer les flux de données d'accéléromètre de CurieIMU. Le code est une modification de l'exemple Draw in the Air :* https://github.com/01org/Intel-Pattern-Matching-Technology * * Tout d'abord, le croquis vous invitera à dessiner des motifs dans les airs (imaginez simplement * que vous écrivez sur un tableau blanc invisible, en utilisant votre tableau comme * stylo), et les données IMU de ces mouvements sont utilisées comme données d'apprentissage pour le * PME. Une fois la formation terminée, vous pouvez continuer à dessiner des lettres et le PME* essaiera de deviner quelle lettre vous dessinez. * * Cet exemple nécessite qu'un bouton soit connecté à la broche numérique 4 * https://www.arduino.cc/en/Tutorial/Button * * REMARQUE :pour de meilleurs résultats, dessinez de grosses lettres, d'au moins 1 à 2 pieds de haut. * * Copyright (c) 2016 Intel Corporation. Tous les droits sont réservés. * Voir avis de licence à la fin du fichier. */#include "CurieIMU.h"#include "CuriePME.h"#include #define PIN 6 //// à quelle broche les NeoPixels sont-ils connectés ?Adafruit_NeoPixel strip =Adafruit_NeoPixel(54, PIN, NEO_GRB + NEO_KHZ800); /// la bande fait 15 pixels de long. Vous pouvez changer cela pour le nombre de pixels dans votre strip.int individuel tr =0; //Some variables to hold "color-target" and "color-current" for smoothing...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(boutonPin, 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(); // intialize neopixel strip 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  

Schémas

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.

Processus de fabrication

  1. Patron de vêtements
  2. Créer des maquettes Arduino sans cavaliers
  3. Capteur DHT11 avec LED et haut-parleur piézo
  4. Arduino Spybot
  5. FlickMote
  6. Téléviseur maison B-Gone
  7. horloge maîtresse
  8. Arduino + LED + Clavier MIDI + MuseScore =Tuteur de piano
  9. LED contrôlées par Alexa via Raspberry Pi