Led IceSkater Jacket (Neopixel und Beschleunigungssensor und Gyro)

Hallo.
ich möchte für einen Eiskunstläufer eine Jacke mit LED Beleuchtung basteln.
Ein NeopixelStrip soll am Arm befestigtwerden und über einen Beschleugigungssensor/Gyro/Magnetometer angesteuert werden.
Wenn der Eisläufer den arm mit einen bestimmten Geschwindigkeit bewegt(Wurfbewegung) soll ein Effekt ausgeführt
werden.
Die Farbe des Effekts soll je nach Wurfrichtung(oben,waagerecht,unten) geändert werden.
Habe ein Program geschrieben und das Funktioniert auch (so lala).
Vielleich kann mir jemand ein paar Tips geben oder hat ein Beispielprogram für mich.
Danke im vorraus
Micha

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS0.h>
#include <Adafruit_Sensor.h>  // not used in this demo but required!
#include <Adafruit_NeoPixel.h>

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(70, 6, NEO_GRB + NEO_KHZ800);
// i2c
Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0();

void setupSensor()
{
  // 1.) Set the accelerometer range
  lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_2G);
  //lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_4G);
  //lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_6G);
  //lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_8G);
  //lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_16G);
  
  // 2.) Set the magnetometer sensitivity
  lsm.setupMag(lsm.LSM9DS0_MAGGAIN_2GAUSS);
  //lsm.setupMag(lsm.LSM9DS0_MAGGAIN_4GAUSS);
  //lsm.setupMag(lsm.LSM9DS0_MAGGAIN_8GAUSS);
  //lsm.setupMag(lsm.LSM9DS0_MAGGAIN_12GAUSS);

  // 3.) Setup the gyroscope
  lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_245DPS);
  //lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_500DPS);
  //lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_2000DPS);
}
// lower number = more sensitive
#define MOVE_THRESHOLD 12000

void setup()
{
  Serial.begin(9600);
  
  // Try to initialise and warn if we couldn't detect the chip
  if (!lsm.begin())
  {
    Serial.println("Oops ... unable to initialize the LSM303. Check your wiring!");
    while (1);
  }
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop()
{
  // Take a reading of accellerometer data
  lsm.read();
 // Serial.print("Accel X: "); Serial.print(lsm.accelData.x); Serial.print(" ");
 // Serial.print("Y: "); Serial.print(lsm.accelData.y);       Serial.print(" ");
 // Serial.print("Z: "); Serial.print(lsm.accelData.z);     Serial.print(" ");

  // Get the magnitude (length) of the 3 axis vector
  // http://en.wikipedia.org/wiki/Euclidean_vector#Length
  double storedVector = lsm.accelData.x*lsm.accelData.x;
  storedVector += lsm.accelData.y*lsm.accelData.y;
  storedVector += lsm.accelData.z*lsm.accelData.z;
  storedVector = sqrt(storedVector);
  //Serial.print("Len: "); Serial.println(storedVector);
  
  // wait a bit
  delay(100);
  
  // get new data!
  lsm.read();
  double newVector = lsm.accelData.x*lsm.accelData.x;
  newVector += lsm.accelData.y*lsm.accelData.y;
  newVector += lsm.accelData.z*lsm.accelData.z;
  newVector = sqrt(newVector);
  //Serial.print("New Len: "); Serial.println(newVector);
  
  // are we moving
  if (abs(newVector - storedVector) > MOVE_THRESHOLD) {
    Serial.println("throw!");
    Serial.print("Accel X: "); Serial.print(lsm.accelData.x); Serial.print(" ");
    Serial.print("Y: "); Serial.print(lsm.accelData.y);       Serial.print(" ");
    Serial.print("Z: "); Serial.print(lsm.accelData.z);     Serial.print(" ");
    Serial.print("New Len: "); Serial.println(newVector);
    
   // colorWipe(strip.Color(0, 0, 255), 50); // Blue
  lauflicht(strip.Color(0,0, 255), 20); // Blue
  }
}


// Lauflicht in eine Richtung
void lauflicht(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<14; i++) {
      strip.setPixelColor(i, c);
      strip.setPixelColor(27-i, c);
      strip.setPixelColor(28+i, c);
      strip.setPixelColor(55-i, c);
      strip.setPixelColor(56+i, c);    
      strip.show();
      delay(wait);
      strip.setPixelColor(i, 0);
      strip.setPixelColor(27-i, 0);
      strip.setPixelColor(28+i, 0);
      strip.setPixelColor(55-i, 0);
      strip.setPixelColor(56+i, 0);
      strip.show();
      delay(wait);
  }
}  
  
  
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
      strip.setPixelColor(i, 0);
      strip.show();
      delay(wait);
  }
}

Bitte verwende für Listings die CODE Tags und nicht die QUOTE Tags.
Du weißt schon daß 70 Neopixel ca 4,2A brauchen?
Andere Ratschläge müssen andere geben :wink: :wink:
Grüße Uwe

Hi,

schau mal hier Sign in - Google Accounts , die basteln sich gerade alle LED Jacken fuer Burning Man. Dort werden die auftretenden Herausforderungen (Verkabelung, Stromversorgung/Akkutypen, Diffusoren, Code, Bedienungsinterface) und deren Loesungen ausfuehrlich diskutiert.

Beispielcode fuer schicke Effekte findest Du dort auch reichlich, z.B. meine FunkyClouds Sammlung FunkyClouds (alpha version) · GitHub mit dutzenden Beispieleffekten. Ist vielleicht auch hilfreich, um komplexe LED Animationen grundsaetzlich zu verstehen.
Hier ein paar Videos von mir http://forum.arduino.cc/index.php?topic=238567.0, am Ende (Seite 3) siehst Du Animationen basierend auf Sensordaten (Sound). Kannst Du auch alles auf 1D (Strip statt Matrix) mappen...

Deinen Code habe ich mal ueberflogen und aufgehoert zu lesen, als ich das erste delay gesehen habe... Lies mal das hier http://playground.arduino.cc/Learning/BlinkWithoutDelayDe

Und nimm die FastLED lib. Das Beispiel Fire2012 ist auch schoen und kann leicht mit Sensordaten reaktiv gemacht werden.

Wie man die Gyrodaten sinnvoll auswertet (filterst), findest Du hier im Forum in den Quadrocopter Threads.

Die Idee hat uebrigens viel Potential, wenn Du verschiedene Messwerte mit verschiedenen Funktionen kombinierst, z.B. x-Beschleunigung mit Helligkeit (bei Pirouette), y mit Flasheffekten oder Lauflichtgeschwindigkeit (beim Sprung) usw. usf.

Viel Spass beim Spielen und Entdecken und mit besten Gruessen,

Helmuth

hi,
Ich werde mich mal durcharbeiten.
Mein Problem sind auch nicht die Effekte sondern die Auswertung der Gyro;Mag und Acc Daten.
Danke für die Links.

mfg Micha

Hi Micha,

zerlege Dein Problem in kleinere. Fang erstmal mit der Visualisierung der Sensordaten an, vielleicht mittels eines kleinen Processing Graph Scripts, um ein Gefuehl dafuer zu bekommen, wie wild die Daten ungefiltert aussehen.

Dann filtere diese Daten und visualisiere sie wieder. Ausgabe als Diagramm oder von mir aus einfach als Textmode Bargraph im Serial Monitor.

Wenn ich mir Deinen Code ansehe, wuerde ich sagen, dass die Effekte schon noch ein Problem sind. Deine simple Logik "wenn Messwert groesser x, dann starte statischen Effekt" wird dich und den Eiskunstlaeufer nicht gluecklich machen.

Schreibe dynamische Effekte mit Parametern, welche permanent durchlaufen und in Abhaengigkeit der gefilterten Sensordaten ihr Aussehen veraendern. Im Detail in FunkyClouds demonstriert und dokumentiert.

Alles andere wird Mist, bzw. funktioniert nur "so lala", wie Du bereits selber festgestellt hast.

Gruesse

Helmuth

Noch etwas Grundsaetzliches: Was Du vorhast ist nicht trivial und mit ein bisschen Copy + Paste Code kommst Du da nicht weiter.

Beschaeftige Dich mit den Grundlagen, lies und verstehe Beispiele. Das Du es verstanden hast, erkennst Du daran, dass Du den Code fuer eine Funktion komplett selber schreiben kannst.

Verwende aussagekraeftige Variablennamen. Schreibe uebersichtlichen Code in kleinen Bloecken. Zerlege alles in Funktionen. Guter Code liest sich wie ein Struktogramm. Kommentiere den Code uebersichtlich und reichlich und erklaere dabei, WARUM Du etwas tust.

Verzichte auf blockierende Delays. Der EINZIGE legitime Grund ein Delay zu verwenden, ist der, wenn ein Sensor beim Auslesen ein spezielles Timing erfordert.

Fang mit etwas einfachem an, z.B. EINE LED geht an, solange eine Messwertgrenze ueberschritten wird. Experimentiere damit, bis es perfekt funktioniert. Wenn es auf dem Tisch perfekt funktioniert, teste es in der Realitaet, also auf dem Eis. Verbessere die Logik und den Code. Wenn es dann dort in der realen Anwendung perfekt funktioniert, kuemmere Dich um den naechsten Schritt, z.B. EINE LED aendert die Helligkeit in Abhaengigkeit des Messwertes, usw.

Visualisiere alle Inputdaten, um zu sehen, welche Spikes im Datenstrom sind. http://arduino.cc/en/tutorial/Graph Lege sinnvolle Grenzen fuer Zeitfenster und Triggerpunkte fest, um die Daten auszuwerten, z.B. reagiere nur auf eine Datenaenderung, welche laenger als 50 mS anhaelt oder experimentiere mit Durchschnittswerten ueber 100 mS u.s.w.

Berichte hier von Deinem Fortschritt und jeder wird Dir gern helfen, auftretende Detailprobleme zu loesen. Du wirst Dich schon etwas tiefer mit der Materie befassen muessen, damit es am Ende eine gute Show fuer das Publikum und fuer Dich und den Eiskunstlaeufer ein Erfolgserlebnis wird. 8)

Ich hoffe, diese Tips helfen Dir erstmal weiter, viele Erkenntnisse und viel Erfolg wuenscht Dir

Helmuth