Difference between revisions of "Luftkissenbahn und Federpendel"

From phyphox
Jump to navigation Jump to search
(Created page with "{{Infobox Experiment | Name = Drehrate und Beschleunigung | Category = Arduino library experiments | Sensors = MPU-6050 }} Auch wenn man für viele Beschleunigungsexperimen...")
 
 
(35 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{Infobox Experiment
 
{{Infobox Experiment
  | Name = Drehrate und Beschleunigung
+
  | Name = Luftkissenbahn und Federpendel
 
  | Category = Arduino library experiments
 
  | Category = Arduino library experiments
  | Sensors = MPU-6050
+
  | Sensors = distance, acceleration
 
}}
 
}}
Auch wenn man für viele Beschleunigungsexperimente prinzipiell den im Smartphone verbauten Beschleunigungs- und Drehratensensor verwenden könnte, macht auch hier ein externer Sensor sehr viel Sinn:
+
Sowohl beim Federpendel als auch bei Versuchen auf der Luftkissenbahn, wo man Weg, Geschwindigkeit und Beschleunigung messen möchte, bietet sich eine Kombination aus Abstands- und Beschleunigungssensor an. Der Arduino Nano 33 BLE verfügt über einen eingebauten Beschleunigungssensor. Über den I2C-Bus lässt sich zusätzlich ein Time-of-Flight-Sensor anschließen, siehe https://phyphox.org/wiki/index.php/Distanzsensor_(Federpendel). So lassen sich beim Federschwinger die Elongation (millimetergenau) und die Beschleunigung des Schwingers gleichzeitig messen. Bei der Luftkissenbahn bekommt man so das Weg-Zeit und das Beschleunigung-Zeit-Diagramm parallel in Echtzeit. Die aktuelle Geschwindigkeit lässt sich über einen Differenzenquotienten aus den Wegdaten berechnen.
  
1. Man möchte nicht, dass ein Smartphone bei einer Messung Schaden nimmt.
+
Unten gibt es zwei Programme. Variante 1 verzichtet auf die Geschwindigkeit, liefert dafür aber zwei Abstandsinformationen (mit und ohne Offset). Die 2. Variante berechnet die Momentangeschwindigkeit mit zentralen Differenzenquotienten aus dem Signal des ToF-Sensors. Das ist natürlich etwas rauschig, funktioniert aber gar nicht so schlecht. Einfach mal ausprobieren.
  
2. Man weiß nicht millimetergenau, wo genau die Sensoren im Smartphone verbaut sind.
+
Beim Federpendel wird die Sensorbox unter den Schwinger geklettet. Der Abstand wird zum Tisch gemessen. Eine positive Beschleunigung ist hier also in die negative z-Richtung des Sensorkoordinatensystems gerichtet (siehe Vorzeichen in Programmierung). In den Rohdaten des Beschleunigungsensors ist schon eine leichte Verkippung messbar. Deshalb wird beim Einschalten oder Resetten des Sensorsormoduls die Beschleunigung auf Null tariert (Offsetmessung, siehe Programmierung). Gleiches geschieht mit dem Abstand. In zwei Views kann der Abstand nach Wunsch untariert oder tariert dargestellt werden (Programmcode 1).
  
3. Sensoren wie der hier verwendete MPU-6050 sind günstig, gut und dank der I2C-Bus-Schnittstelle sehr einfach zu verlöten.
+
Da ein Gyroskop sowieso mit verbaut ist, lässt sich eine Messung zur Zentrifugalbeschleunigung (siehe https://phyphox.org/wiki/index.php/Drehrate_und_Beschleunigung) auch gleich noch mit in view3 integrieren. So hat man insbesondere für Physik im 11. und 12. Jg. einen sehr universellen Sensor.
 
 
Hier soll der Sensor für Beschleunigungsmessungen auf der Luftkissenbahn sowie für Drehraten- und Zentrifugalbeschleunigungsmessungen eingesetzt werden. Aus diesem Grund ist das Programm so aufgebaut, dass der Sensor die Resultierende aus ax und ay sowie die Resultierende Drehrate aller drei Achsen übermittelt. Direkt nach dem Starten oder einem Reset muss der Sensor einige Sekunden ruhen. Während dieser Zeit wird die Beschleunigung auf null Tariert. So wird die Erdbeschleunigung herausgerechnet, falls der Sensor schief liegt. Der Sensor funktioniert so gut, dass aus den Parabeln im 3. Graph millimetergenau der Radius zur Dreachse ermittelt werden kann. Wichtig ist, dass der Sensor entweder in der Drehebene liegt oder ggf. schief mit x-Richtig radial ausgerichtet, wie auf dem folgenden Foto.
 
  
 
<gallery widths=500px heights=400px>
 
<gallery widths=500px heights=400px>
File:Drehrate.jpg|Aufbau
+
File:Nano33_Luftkissenbahn1.jpg|Beschleunigungs- und Abstandsmessung auf Luftkissenbahn
File:Drehrate_2.jpg|Aufbau mit Schumpfschlauch und Klettband
+
File:Nano33 Luftkissenbahn2.jpg|Arduino Nano 33 BLE mit ToF-Sensor
 +
File:Nano33_Federpendel1.jpg|Arduino Nano 33 BLE mit ToF-Sensor unter Federpendel
 +
File:Federpendel velocity2.jpg|Alternativer Code (s. u.) mit Geschwindigkeitsgraph über zentrale Differenzenquotienten
 +
File:Nano33 Luftkissenbahn5.jpg|Alternativer Code (s. u.) mit Geschwindigkeitsgraph über zentrale Differenzenquotienten
 +
File:Nano33 Luftkissenbahn6.jpg|Die mithilfe einer Ausgleichsgeraden ermittelte Beschleunigung passt perfekt zu den Werten des Beschleunigungssensors
 
</gallery>
 
</gallery>
  
 
==Aufbau==
 
==Aufbau==
Die Verkabelung des Sensors ist wieder wie üblich: 3V3 – Vin, Gnd – Gnd, SCL – 22,  
+
Die Verkabelung des Sensors ist wieder wie üblich: 3-6V – 3V3, Gnd – Gnd, SCL – A5, SDA –A4. Als Stromversorgung dient hier ein schalbarer 4,5-V-Batteriehalter, auf den der Nano mit Pilzkopfband geklettet ist. Der ToF-Sensor wurde mit etwas Heißkleber auf den Nano neben das Kommunikationsmodul geklebt.
SDA –21. Als Stromversorgung dient hier einfach eine kleine Powerbank, auf die der ESP32 mit Doppelseitigem Klebeband befestigt wird. Der MPU-6050 wurde mit etwas Heißkleber auf den ESP32 neben das Kommunikationsmodul geklebt und am Ende alles mit Schrumpfschlauch versiegelt.
 
  
 
==Programmierung==
 
==Programmierung==
Der ESP32 wird über die Arduino IDE programmiert. Es müssen die Definitionen für den ESP32 und die phyphox-Bibliothek installiert sein. Siehe dazu das Video unter [[:Category: Arduino library experiments]].
+
Der Arduino Nano 33 BLE wird über die Arduino IDE programmiert. Es müssen die Definitionen für den Nano und die phyphox-Bibliothek installiert sein. Siehe dazu das Video unter [[:Category: Arduino library experiments]].
  
Es ist darauf zu achten, dass jeder ESP32 eine eigene Kennung hat (diese wird in ''PhyphoxBLE::start("Thermometer_01")'' festgelegt). Anschließend kann über das Plus-Symbol in phyphox ein Bluetooth-Experiment hinzugefügt werden, das Experiment wird dann automatisch geladen.
+
Möchte man mehrere Sensoren basteln, ist darauf zu achten, dass jeder eine eigene Kennung hat (diese wird in ''PhyphoxBLE::start("DistanceGyroAcceleration_01");'' festgelegt). Anschließend kann über das Plus-Symbol in Phyphox ein Bluetooth-Experiment hinzugefügt werden, das Experiment wird dann automatisch geladen.
  
 
<pre>
 
<pre>
 +
#include <phyphoxBle.h>
 +
#include <Wire.h>
 +
#include <VL53L1X.h>
 +
#include <Arduino_LSM9DS1.h>
 +
float x ,y ,z, OffsetX, OffsetY, OffsetZ, Beschleunigung, az, OffsetS, Elong, Distance, ZentrifugalBeschl, wx, wy, wz, Drehrate;
 +
VL53L1X sensor;
 +
void setup()
 +
{
 +
  PhyphoxBLE::start("DistanceGyroAcceleration");                //Start the BLE server
 +
 +
  //Experiment
 +
    PhyphoxBleExperiment experiment;
 +
 +
    experiment.setTitle("Abstand");
 +
    experiment.setCategory("Arduino Experiments");
 +
    experiment.setDescription("Abstand, Beschleunigung und Drehrate für Federschwinger, Luftkissenbahn und Drehschleuder");
 +
 +
//Views
 +
PhyphoxBleExperiment::View view1;
 +
view1.setLabel("az, s - Offset");
 +
PhyphoxBleExperiment::View view2;
 +
view2.setLabel("az, s");
 +
PhyphoxBleExperiment::View view3;
 +
view3.setLabel("Zentrifugal, Drehrate");
 +
//Graph
 +
PhyphoxBleExperiment::Graph graph1;
 +
  graph1.setLabel("Elongation");
 +
  graph1.setUnitX("s");
 +
  graph1.setUnitY("mm");
 +
  graph1.setLabelX("t");
 +
  graph1.setLabelY("s");
 +
  graph1.setChannel(0,1);
 +
PhyphoxBleExperiment::Graph graph2;
 +
  graph2.setLabel("Beschleunigung");
 +
  graph2.setUnitX("s");
 +
  graph2.setUnitY("m/s2");
 +
  graph2.setLabelX("t");
 +
  graph2.setLabelY("a");
 +
  graph2.setChannel(0,2);
 +
PhyphoxBleExperiment::Graph graph3;
 +
  graph3.setLabel("Abstand");
 +
  graph3.setUnitX("s");
 +
  graph3.setUnitY("mm");
 +
  graph3.setLabelX("t");
 +
  graph3.setLabelY("s");
 +
  graph3.setChannel(0,3);
 +
PhyphoxBleExperiment::Graph graph4;
 +
  graph4.setLabel("Beschleunigung");
 +
  graph4.setUnitX("s");
 +
  graph4.setUnitY("m/s2");
 +
  graph4.setLabelX("t");
 +
  graph4.setLabelY("az");
 +
  graph4.setChannel(0,2);
 +
PhyphoxBleExperiment::Graph graph5; //axy von omega_res
 +
graph5.setLabel("Zentrifugalbeschleunigung");
 +
graph5.setLabelX("axy");
 +
graph5.setUnitX("1/s");
 +
graph5.setUnitY("m/s2");
 +
graph5.setLabelX("omega_xyz");
 +
graph5.setLabelY("axy");
 +
graph5.setStyle("dots");
 +
graph5.setChannel(5, 4);
 +
PhyphoxBleExperiment::Graph graph6;
 +
graph6.setLabel("Res. Drehrate");
 +
graph6.setLabelX("omega_xyz");
 +
graph6.setUnitX("s");
 +
graph6.setUnitY("1/s");
 +
graph6.setLabelX("t");
 +
graph6.setLabelY("omega_xyz");
 +
graph6.setChannel(0, 5);
 +
PhyphoxBleExperiment::Graph graph7; //axy von omega_res
 +
graph7.setLabel("Zentrifugalbeschleunigung");
 +
graph7.setLabelX("axy");
 +
graph7.setUnitX("s");
 +
graph7.setUnitY("m/s2");
 +
graph7.setLabelX("t");
 +
graph7.setLabelY("axy");
 +
graph7.setChannel(0, 4);
 +
 +
experiment.addView(view1);             
 +
  view1.addElement(graph1);             
 +
  view1.addElement(graph2);             
 +
experiment.addView(view2);             
 +
  view2.addElement(graph3);               
 +
  view2.addElement(graph4);
 +
experiment.addView(view3);               
 +
view3.addElement(graph5);
 +
view3.addElement(graph6);
 +
view3.addElement(graph7);
 +
PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server
 +
 +
 +
  Wire.begin();
 +
  while (!sensor.init())
 +
      delay(100);
 +
    sensor.setTimeout(500);
 +
 
 +
  sensor.setDistanceMode(VL53L1X::Short);
 +
  sensor.setMeasurementTimingBudget(20000);
 +
  sensor.startContinuous(20);
 +
 +
IMU.begin(); //Beschleunigungssensor starten
 +
delay(250); //Nach dem der Knopf geedrückt wird, muss sich das Ding kurz beruhigen
 +
// Offsetkorrektur Beschleunigung
 +
for(int i=0;i<100;i++){
 +
  IMU.readAcceleration(x, y, z);
 +
 +
  OffsetX += x;
 +
  OffsetY += y;
 +
  OffsetZ += z;
 +
  OffsetS += sensor.read();
 +
  delay(10);
 +
}
 +
OffsetX=OffsetX/100;
 +
OffsetY=OffsetY/100;
 +
OffsetZ=OffsetZ/100;
 +
OffsetS=OffsetS/100;
 +
Serial.begin(38400);//Falls man den Sensor an den PC anschließen möchte, für Abstandswerte
 +
}
 +
void loop()
 +
{
 +
Distance = sensor.read();
 +
Elong = Distance - OffsetS;
 +
IMU.readAcceleration(x, y, z);
 +
Beschleunigung =-9.81*(z- OffsetZ);
 +
ZentrifugalBeschl = 9.81 * sqrt(sq(x - OffsetX) + sq(y - OffsetY));
 +
IMU.readGyroscope(wx, wy, wz);
 +
Drehrate = 1.1148*6.28318530718*(sqrt(sq(wx) + sq(wy) + sq(wz))) / 360; //Kalibrierung Plattenspieler
 +
  PhyphoxBLE::write(Elong, Beschleunigung, Distance, ZentrifugalBeschl, Drehrate);    //Send value to phyphox
 +
  Serial.println(Distance);//Abstandswerte an den PC senden
 +
delay(10); 
 +
}
 +
 +
</pre>
 +
 +
==Alternative Programmierung==
 +
Die Geschwindigkeit kann als Differenzenquotient (zentrale differenzen) des Ortes gebildet werden. Das funktioniert gar nicht so schlecht. Hierfür werden die entsprechenden in Abstände in Arrays gespeichert, aus denen dann aktuellen Werte übertragen werden. Als Arraylänge wurde im Program einfach 5000 definiert, was hinreichend lang ist. Damit läuft es. Gute Programmierer haben sicherlich eine elegantere Lösung parat. Gerne verbessern!
 +
 +
<pre>
 +
#include <phyphoxBle.h>
 +
#include <Wire.h>
 +
#include <VL53L1X.h>
 +
#include <Arduino_LSM9DS1.h>
 +
float x ,y ,z, OffsetX, OffsetY, OffsetZ, az, OffsetS, Elong, Distance, ZentrifugalBeschl, wx, wy, wz, Drehrate;
 +
float t[5000];
 +
float Beschleunigung[5000];
 +
float distance[5000];
 +
float velocity[5000];
 +
 +
VL53L1X sensor;
 +
void setup()
 +
{
 +
  PhyphoxBLE::start("DistanceGyroAcceleration");                //Start the BLE server
 +
 +
  //Experiment
 +
    PhyphoxBleExperiment experiment;
 +
 +
    experiment.setTitle("Abstand");
 +
    experiment.setCategory("Arduino Experiments");
 +
    experiment.setDescription("Abstand, Beschleunigung, Geschwindigkeit und Drehrate für Federschwinger, Luftkissenbahn und Drehschleuder");
 +
 +
//Views
 +
PhyphoxBleExperiment::View view1;
 +
view1.setLabel("s, a");
 +
PhyphoxBleExperiment::View view2;
 +
view2.setLabel("s, v, az");
 +
PhyphoxBleExperiment::View view3;
 +
view3.setLabel("Zentrifugal, Drehrate");
 +
//Graph
 +
PhyphoxBleExperiment::Graph graph1;
 +
  graph1.setLabel("Auslenkung");
 +
  graph1.setUnitX("s");
 +
  graph1.setUnitY("mm");
 +
  graph1.setLabelX("t");
 +
  graph1.setLabelY("s");
 +
  graph1.setStyle("dots");
 +
  graph1.setChannel(0,1);
 +
PhyphoxBleExperiment::Graph graph2;
 +
  graph2.setLabel("Beschleunigung");
 +
  graph2.setUnitX("s");
 +
  graph2.setUnitY("m/s2");
 +
  graph2.setLabelX("t");
 +
  graph2.setLabelY("a");
 +
  graph2.setStyle("dots");
 +
  graph2.setChannel(0,2);
 +
PhyphoxBleExperiment::Graph graph3;
 +
  graph3.setLabel("Geschwindigkeit");
 +
  graph3.setUnitX("s");
 +
  graph3.setUnitY("m/s");
 +
  graph3.setLabelX("t");
 +
  graph3.setLabelY("v");
 +
  graph3.setStyle("dots");
 +
  graph3.setChannel(0,3);
 +
PhyphoxBleExperiment::Graph graph4;
 +
  graph4.setLabel("Phasendiagramm");
 +
  graph4.setUnitX("mm");
 +
  graph4.setUnitY("m/s2");
 +
  graph4.setLabelX("s");
 +
  graph4.setLabelY("v");
 +
  graph4.setStyle("dots");
 +
  graph4.setChannel(1,3);
 +
PhyphoxBleExperiment::Graph graph5; //axy von omega_res
 +
graph5.setLabel("Zentrifugalbeschleunigung");
 +
graph5.setLabelX("axy");
 +
graph5.setUnitX("1/s");
 +
graph5.setUnitY("m/s2");
 +
graph5.setLabelX("omega_xyz");
 +
graph5.setLabelY("axy");
 +
graph5.setStyle("dots");
 +
graph5.setChannel(5, 4);
 +
PhyphoxBleExperiment::Graph graph6;
 +
graph6.setLabel("Res. Drehrate");
 +
graph6.setLabelX("omega_xyz");
 +
graph6.setUnitX("s");
 +
graph6.setUnitY("1/s");
 +
graph6.setLabelX("t");
 +
graph6.setLabelY("omega_xyz");
 +
graph6.setChannel(0, 5);
 +
PhyphoxBleExperiment::Graph graph7; //axy von omega_res
 +
graph7.setLabel("Zentrifugalbeschleunigung");
 +
graph7.setLabelX("axy");
 +
graph7.setUnitX("s");
 +
graph7.setUnitY("m/s2");
 +
graph7.setLabelX("t");
 +
graph7.setLabelY("axy");
 +
graph7.setChannel(0, 4);
 +
 +
experiment.addView(view1);             
 +
  view1.addElement(graph1);             
 +
  view1.addElement(graph2);             
 +
experiment.addView(view2);
 +
  view2.addElement(graph1);             
 +
  view2.addElement(graph3);               
 +
  view2.addElement(graph2);
 +
experiment.addView(view3);               
 +
view3.addElement(graph5);
 +
view3.addElement(graph6);
 +
view3.addElement(graph7);
 +
PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server
 +
 +
 +
  Wire.begin();
 +
  while (!sensor.init())
 +
      delay(100);
 +
    sensor.setTimeout(500);
 +
 
 +
  sensor.setDistanceMode(VL53L1X::Short);
 +
  sensor.setMeasurementTimingBudget(20000);
 +
  sensor.startContinuous(20);
 +
 +
IMU.begin(); //Beschleunigungssensor starten
 +
delay(250); //Nach dem der Knopf geedrückt wird, muss sich das Ding kurz beruhigen
 +
// Offsetkorrektur Beschleunigung
 +
for(int i=0;i<100;i++){
 +
  IMU.readAcceleration(x, y, z);
  
 +
  OffsetX += x;
 +
  OffsetY += y;
 +
  OffsetZ += z;
 +
  OffsetS += sensor.read();
 +
  delay(10);
 +
}
 +
OffsetX=OffsetX/100;
 +
OffsetY=OffsetY/100;
 +
OffsetZ=OffsetZ/100;
 +
OffsetS=OffsetS/100;
 +
Serial.begin(38400);//Falls man den Sensor an den PC anschließen möchte, für Abstandswerte
 +
}
 +
void loop()
 +
{
 +
  for (int i = 0; i<5000; i = i + 1) {
 +
  IMU.readAcceleration(x, y, z);
 +
    Beschleunigung[i] = -9.81*(z - OffsetZ);
 +
    ZentrifugalBeschl = 9.81 * sqrt(sq(x - OffsetX) + sq(y - OffsetY));
 +
  Distance = sensor.read() - OffsetS;
 +
    distance[i]  = Distance;
 +
  IMU.readGyroscope(wx, wy, wz);
 +
  Drehrate = 1.1148*6.28318530718*(sqrt(sq(wx) + sq(wy) + sq(wz))) / 360; //Kalibrierung Plattenspieler
 +
  t[i] = millis();
 +
  if(i > 2) {
 +
    velocity[i-1] = ((distance[i] - distance[i-2]) / (t[i] - t[i-2]));
 +
    PhyphoxBLE::write(distance[i-1], Beschleunigung[i-1], velocity[i-1], ZentrifugalBeschl, Drehrate);
 +
    Serial.println(Distance);//Abstandswerte an den PC senden
 +
    delay(1);
 +
  }
 +
  }
 +
}
 
</pre>
 
</pre>
  

Latest revision as of 18:09, 7 December 2023

Luftkissenbahn und Federpendel
Experiment Luftkissenbahn und Federpendel
Category Arduino library experiments
Used sensors distance, acceleration

Sowohl beim Federpendel als auch bei Versuchen auf der Luftkissenbahn, wo man Weg, Geschwindigkeit und Beschleunigung messen möchte, bietet sich eine Kombination aus Abstands- und Beschleunigungssensor an. Der Arduino Nano 33 BLE verfügt über einen eingebauten Beschleunigungssensor. Über den I2C-Bus lässt sich zusätzlich ein Time-of-Flight-Sensor anschließen, siehe https://phyphox.org/wiki/index.php/Distanzsensor_(Federpendel). So lassen sich beim Federschwinger die Elongation (millimetergenau) und die Beschleunigung des Schwingers gleichzeitig messen. Bei der Luftkissenbahn bekommt man so das Weg-Zeit und das Beschleunigung-Zeit-Diagramm parallel in Echtzeit. Die aktuelle Geschwindigkeit lässt sich über einen Differenzenquotienten aus den Wegdaten berechnen.

Unten gibt es zwei Programme. Variante 1 verzichtet auf die Geschwindigkeit, liefert dafür aber zwei Abstandsinformationen (mit und ohne Offset). Die 2. Variante berechnet die Momentangeschwindigkeit mit zentralen Differenzenquotienten aus dem Signal des ToF-Sensors. Das ist natürlich etwas rauschig, funktioniert aber gar nicht so schlecht. Einfach mal ausprobieren.

Beim Federpendel wird die Sensorbox unter den Schwinger geklettet. Der Abstand wird zum Tisch gemessen. Eine positive Beschleunigung ist hier also in die negative z-Richtung des Sensorkoordinatensystems gerichtet (siehe Vorzeichen in Programmierung). In den Rohdaten des Beschleunigungsensors ist schon eine leichte Verkippung messbar. Deshalb wird beim Einschalten oder Resetten des Sensorsormoduls die Beschleunigung auf Null tariert (Offsetmessung, siehe Programmierung). Gleiches geschieht mit dem Abstand. In zwei Views kann der Abstand nach Wunsch untariert oder tariert dargestellt werden (Programmcode 1).

Da ein Gyroskop sowieso mit verbaut ist, lässt sich eine Messung zur Zentrifugalbeschleunigung (siehe https://phyphox.org/wiki/index.php/Drehrate_und_Beschleunigung) auch gleich noch mit in view3 integrieren. So hat man insbesondere für Physik im 11. und 12. Jg. einen sehr universellen Sensor.

Aufbau

Die Verkabelung des Sensors ist wieder wie üblich: 3-6V – 3V3, Gnd – Gnd, SCL – A5, SDA –A4. Als Stromversorgung dient hier ein schalbarer 4,5-V-Batteriehalter, auf den der Nano mit Pilzkopfband geklettet ist. Der ToF-Sensor wurde mit etwas Heißkleber auf den Nano neben das Kommunikationsmodul geklebt.

Programmierung

Der Arduino Nano 33 BLE wird über die Arduino IDE programmiert. Es müssen die Definitionen für den Nano und die phyphox-Bibliothek installiert sein. Siehe dazu das Video unter Category: Arduino library experiments.

Möchte man mehrere Sensoren basteln, ist darauf zu achten, dass jeder eine eigene Kennung hat (diese wird in PhyphoxBLE::start("DistanceGyroAcceleration_01"); festgelegt). Anschließend kann über das Plus-Symbol in Phyphox ein Bluetooth-Experiment hinzugefügt werden, das Experiment wird dann automatisch geladen.

#include <phyphoxBle.h> 
#include <Wire.h>
#include <VL53L1X.h>
#include <Arduino_LSM9DS1.h>
float x ,y ,z, OffsetX, OffsetY, OffsetZ, Beschleunigung, az, OffsetS, Elong, Distance, ZentrifugalBeschl, wx, wy, wz, Drehrate;
VL53L1X sensor;
void setup()
{
  PhyphoxBLE::start("DistanceGyroAcceleration");                //Start the BLE server
 
  //Experiment
    PhyphoxBleExperiment experiment;

    experiment.setTitle("Abstand");
    experiment.setCategory("Arduino Experiments");
    experiment.setDescription("Abstand, Beschleunigung und Drehrate für Federschwinger, Luftkissenbahn und Drehschleuder");

//Views
PhyphoxBleExperiment::View view1;
 view1.setLabel("az, s - Offset");
PhyphoxBleExperiment::View view2;
 view2.setLabel("az, s");
PhyphoxBleExperiment::View view3;
view3.setLabel("Zentrifugal, Drehrate");
//Graph
PhyphoxBleExperiment::Graph graph1;
  graph1.setLabel("Elongation");
  graph1.setUnitX("s");
  graph1.setUnitY("mm");
  graph1.setLabelX("t");
  graph1.setLabelY("s");
  graph1.setChannel(0,1);
PhyphoxBleExperiment::Graph graph2;
  graph2.setLabel("Beschleunigung");
  graph2.setUnitX("s");
  graph2.setUnitY("m/s2");
  graph2.setLabelX("t");
  graph2.setLabelY("a");
  graph2.setChannel(0,2);
PhyphoxBleExperiment::Graph graph3;
  graph3.setLabel("Abstand");
  graph3.setUnitX("s");
  graph3.setUnitY("mm");
  graph3.setLabelX("t");
  graph3.setLabelY("s");
  graph3.setChannel(0,3);
PhyphoxBleExperiment::Graph graph4;
  graph4.setLabel("Beschleunigung");
  graph4.setUnitX("s");
  graph4.setUnitY("m/s2");
  graph4.setLabelX("t");
  graph4.setLabelY("az");
  graph4.setChannel(0,2);
PhyphoxBleExperiment::Graph graph5; //axy von omega_res
 graph5.setLabel("Zentrifugalbeschleunigung");
 graph5.setLabelX("axy");
 graph5.setUnitX("1/s");
 graph5.setUnitY("m/s2");
 graph5.setLabelX("omega_xyz");
 graph5.setLabelY("axy");
 graph5.setStyle("dots");
 graph5.setChannel(5, 4);
PhyphoxBleExperiment::Graph graph6;
 graph6.setLabel("Res. Drehrate");
 graph6.setLabelX("omega_xyz");
 graph6.setUnitX("s");
 graph6.setUnitY("1/s");
 graph6.setLabelX("t");
 graph6.setLabelY("omega_xyz");
 graph6.setChannel(0, 5);
PhyphoxBleExperiment::Graph graph7; //axy von omega_res
 graph7.setLabel("Zentrifugalbeschleunigung");
 graph7.setLabelX("axy");
 graph7.setUnitX("s");
 graph7.setUnitY("m/s2");
 graph7.setLabelX("t");
 graph7.setLabelY("axy");
 graph7.setChannel(0, 4);

experiment.addView(view1);               
  view1.addElement(graph1);              
  view1.addElement(graph2);              
experiment.addView(view2);               
  view2.addElement(graph3);                 
  view2.addElement(graph4); 
experiment.addView(view3);                
 view3.addElement(graph5);
 view3.addElement(graph6);
 view3.addElement(graph7);
PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server


  Wire.begin();
  while (!sensor.init())
      delay(100);
    sensor.setTimeout(500);
  
  sensor.setDistanceMode(VL53L1X::Short);
  sensor.setMeasurementTimingBudget(20000);
  sensor.startContinuous(20);

IMU.begin(); //Beschleunigungssensor starten
delay(250); //Nach dem der Knopf geedrückt wird, muss sich das Ding kurz beruhigen
// Offsetkorrektur Beschleunigung
 for(int i=0;i<100;i++){
  IMU.readAcceleration(x, y, z);

  OffsetX += x;
  OffsetY += y;
  OffsetZ += z;
  OffsetS += sensor.read();
  delay(10);
 }
 OffsetX=OffsetX/100;
 OffsetY=OffsetY/100;
 OffsetZ=OffsetZ/100;
 OffsetS=OffsetS/100;
Serial.begin(38400);//Falls man den Sensor an den PC anschließen möchte, für Abstandswerte
}
void loop()
{
Distance = sensor.read();
Elong = Distance - OffsetS;
IMU.readAcceleration(x, y, z);
 Beschleunigung =-9.81*(z- OffsetZ);
 ZentrifugalBeschl = 9.81 * sqrt(sq(x - OffsetX) + sq(y - OffsetY));
IMU.readGyroscope(wx, wy, wz);
 Drehrate = 1.1148*6.28318530718*(sqrt(sq(wx) + sq(wy) + sq(wz))) / 360; //Kalibrierung Plattenspieler
  PhyphoxBLE::write(Elong, Beschleunigung, Distance, ZentrifugalBeschl, Drehrate);    //Send value to phyphox
  Serial.println(Distance);//Abstandswerte an den PC senden
delay(10);   
}

Alternative Programmierung

Die Geschwindigkeit kann als Differenzenquotient (zentrale differenzen) des Ortes gebildet werden. Das funktioniert gar nicht so schlecht. Hierfür werden die entsprechenden in Abstände in Arrays gespeichert, aus denen dann aktuellen Werte übertragen werden. Als Arraylänge wurde im Program einfach 5000 definiert, was hinreichend lang ist. Damit läuft es. Gute Programmierer haben sicherlich eine elegantere Lösung parat. Gerne verbessern!

#include <phyphoxBle.h> 
#include <Wire.h>
#include <VL53L1X.h>
#include <Arduino_LSM9DS1.h>
float x ,y ,z, OffsetX, OffsetY, OffsetZ, az, OffsetS, Elong, Distance, ZentrifugalBeschl, wx, wy, wz, Drehrate;
float t[5000];
float Beschleunigung[5000];
float distance[5000];
float velocity[5000];

VL53L1X sensor;
void setup()
{
  PhyphoxBLE::start("DistanceGyroAcceleration");                //Start the BLE server
 
  //Experiment
    PhyphoxBleExperiment experiment;

    experiment.setTitle("Abstand");
    experiment.setCategory("Arduino Experiments");
    experiment.setDescription("Abstand, Beschleunigung, Geschwindigkeit und Drehrate für Federschwinger, Luftkissenbahn und Drehschleuder");

//Views
PhyphoxBleExperiment::View view1;
 view1.setLabel("s, a");
PhyphoxBleExperiment::View view2;
 view2.setLabel("s, v, az");
PhyphoxBleExperiment::View view3;
view3.setLabel("Zentrifugal, Drehrate");
//Graph
PhyphoxBleExperiment::Graph graph1;
  graph1.setLabel("Auslenkung");
  graph1.setUnitX("s");
  graph1.setUnitY("mm");
  graph1.setLabelX("t");
  graph1.setLabelY("s");
  graph1.setStyle("dots");
  graph1.setChannel(0,1);
PhyphoxBleExperiment::Graph graph2;
  graph2.setLabel("Beschleunigung");
  graph2.setUnitX("s");
  graph2.setUnitY("m/s2");
  graph2.setLabelX("t");
  graph2.setLabelY("a");
  graph2.setStyle("dots");
  graph2.setChannel(0,2);
PhyphoxBleExperiment::Graph graph3;
  graph3.setLabel("Geschwindigkeit");
  graph3.setUnitX("s");
  graph3.setUnitY("m/s");
  graph3.setLabelX("t");
  graph3.setLabelY("v");
  graph3.setStyle("dots");
  graph3.setChannel(0,3);
PhyphoxBleExperiment::Graph graph4;
  graph4.setLabel("Phasendiagramm");
  graph4.setUnitX("mm");
  graph4.setUnitY("m/s2");
  graph4.setLabelX("s");
  graph4.setLabelY("v");
  graph4.setStyle("dots");
  graph4.setChannel(1,3);
PhyphoxBleExperiment::Graph graph5; //axy von omega_res
 graph5.setLabel("Zentrifugalbeschleunigung");
 graph5.setLabelX("axy");
 graph5.setUnitX("1/s");
 graph5.setUnitY("m/s2");
 graph5.setLabelX("omega_xyz");
 graph5.setLabelY("axy");
 graph5.setStyle("dots");
 graph5.setChannel(5, 4);
PhyphoxBleExperiment::Graph graph6;
 graph6.setLabel("Res. Drehrate");
 graph6.setLabelX("omega_xyz");
 graph6.setUnitX("s");
 graph6.setUnitY("1/s");
 graph6.setLabelX("t");
 graph6.setLabelY("omega_xyz");
 graph6.setChannel(0, 5);
PhyphoxBleExperiment::Graph graph7; //axy von omega_res
 graph7.setLabel("Zentrifugalbeschleunigung");
 graph7.setLabelX("axy");
 graph7.setUnitX("s");
 graph7.setUnitY("m/s2");
 graph7.setLabelX("t");
 graph7.setLabelY("axy");
 graph7.setChannel(0, 4);

experiment.addView(view1);               
  view1.addElement(graph1);              
  view1.addElement(graph2);              
experiment.addView(view2);
  view2.addElement(graph1);               
  view2.addElement(graph3);                 
  view2.addElement(graph2);
experiment.addView(view3);                
 view3.addElement(graph5);
 view3.addElement(graph6);
 view3.addElement(graph7);
PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server


  Wire.begin();
  while (!sensor.init())
      delay(100);
    sensor.setTimeout(500);
  
  sensor.setDistanceMode(VL53L1X::Short);
  sensor.setMeasurementTimingBudget(20000);
  sensor.startContinuous(20);

IMU.begin(); //Beschleunigungssensor starten
delay(250); //Nach dem der Knopf geedrückt wird, muss sich das Ding kurz beruhigen
// Offsetkorrektur Beschleunigung
 for(int i=0;i<100;i++){
  IMU.readAcceleration(x, y, z);

  OffsetX += x;
  OffsetY += y;
  OffsetZ += z;
  OffsetS += sensor.read();
  delay(10);
 }
 OffsetX=OffsetX/100;
 OffsetY=OffsetY/100;
 OffsetZ=OffsetZ/100;
 OffsetS=OffsetS/100;
Serial.begin(38400);//Falls man den Sensor an den PC anschließen möchte, für Abstandswerte
}
void loop()
{
  for (int i = 0; i<5000; i = i + 1) {
   IMU.readAcceleration(x, y, z);
    Beschleunigung[i] = -9.81*(z - OffsetZ);
    ZentrifugalBeschl = 9.81 * sqrt(sq(x - OffsetX) + sq(y - OffsetY));
   Distance = sensor.read() - OffsetS;
    distance[i]  = Distance;
  IMU.readGyroscope(wx, wy, wz);
   Drehrate = 1.1148*6.28318530718*(sqrt(sq(wx) + sq(wy) + sq(wz))) / 360; //Kalibrierung Plattenspieler
   t[i] = millis();
   if(i > 2) {
    velocity[i-1] = ((distance[i] - distance[i-2]) / (t[i] - t[i-2]));
    PhyphoxBLE::write(distance[i-1], Beschleunigung[i-1], velocity[i-1], ZentrifugalBeschl, Drehrate); 
    Serial.println(Distance);//Abstandswerte an den PC senden
    delay(1);
   }
  }
}

Arbeitsmaterialien