Forum: Mikrocontroller und Digitale Elektronik ADXL193 - Beschleunigung auslesen


von Joni (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Für ein Projekt an der Hochschule versuche ich die Daten des 
Beschleunigungssensor ADXL 193 auszuwerten.
Der erste Versuch mit freiem Fall und Aufprall hat durchgehend die unten 
aufgeführten Daten geliefert.
Irgendwas läuft falsch.

Hat jemand eine Idee was das Problem sein könnte?


Bin ich prinzipiell richtig mit der Annahme das die Beschleunigung g 
über
die Formel g = ((Wert*(5/1024))/8 errechnet wird?

Danke für eure Hilfe!

Werte:

0
0
0
190
1023
1023
1023
1023
233
0
0
0
323
1023
1023
1023
1019
116
0
0
0
460
1023
1023
1023
917
9
0

von Test (Gast)


Lesenswert?

Joni schrieb:
> Der erste Versuch mit freiem Fall und Aufprall hat durchgehend die unten
> aufgeführten Daten geliefert.

Wieso?

Joni schrieb:
> Hat jemand eine Idee was das Problem sein könnte?

Schaltungsaufbau + Code herzeigen. So können wir nur raten.

Dein (offensichtlich mit 5V betriebener) 5V Mikrocontroller mit 10 Bit 
AD-Wandler lässt nur eine geringe Auflösung zu. Du verwendest wohl einen 
AD22283  mit einer Sensitivität von 8mV/g (typ). Deine ADC-Auflösung 
beträgt 5V/1024 = 4,88mV/Bit. Also hast du eine Auflösung (nicht 
Genauigkeit) von knapp 0.5g

Was hättest du denn anderst erwartet? Was ist das für ein Test? Wenn das 
Ding auf den Boden knallt sind 250g nichts.

Joni schrieb:
> g = ((Wert*(5/1024))/8

Prinzipiell ja. Wie sieht das im Code aus?

von Joni (Gast)


Lesenswert?

Hey danke schon mal für deine Antwort.

Es geht um den Test eines Helmes.
Ein Gewicht mit 5kg + Sensor kracht auf EPS Material.
Anhand der Beschleunigungsmesswerte soll das Dämpfungspotential bestimmt 
werden.
Fallhöhe sind 1,5m.
Die Daten werden über Arduino Leonardo und CoolTerm ausgelesen.
Erwartet hätte ich den Verlauf einer quadratischen Funktion oder 
ähnlich.
Beim Aufprall erreicht die Beschleunigungskurve ihr Maximum.


So sieht der Code aus:


int InputPin = A0;

int Wert;
int mv;
float g;

void setup() {
  // put your setup code here, to run once:

Serial.begin(9600); //Symbole pro Sekunde (Baudrahte)
(InputPin, INPUT);


}

void loop() {
  // put your main code here, to run repeatedly:


  Wert = analogRead(InputPin);

  mv = (Wert*(5/1024)) ; // Wert in mV
  g = (mv/8); // Wert in g
  Serial.println (g);

  delay(2);
}

von Ralf B. (Firma: Scorptech) (mad_scorp)


Lesenswert?

Dein Code sieht okay aus, aber passt irgendwie nicht zu den Werten, die 
du in deinem Eröffnungspost genannt hast. Sind das vielleicht direkt die 
Werte aus dem Sensor oder sollte das dein g sein?

Hast du mal gerechnet, was für Beschleunigungswerte du erwartest? Wie 
oben schon jemand geschrieben hat, die 250g können recht schnell 
erreicht werden, die 1023 deuten darauf hin, das der Sensor eben 
übersteuert ist.

Allgemein ist der Code vielleicht etwas langsam, wenn du ein schnelles 
Ereignis aufzeichnen willst. Serial.println braucht etwas Zeit und das 
delay am Ende macht es auch nicht unbedingt besser. Vielleicht solltest 
du eine Serie von Werten aufzeichnen und diese dann gesammelt ausgeben.

von Joni (Gast)


Lesenswert?

Danke für deine Antwort Ralf,

ja du hast Recht das sind die Werte direkt aus dem Sensor.
Eigentlich sollten die Werte unterhalb von 250 g liegen.
Entspricht denn 1023 dem Maximalwert?

von Test (Gast)


Lesenswert?

Hmm ja du hast ein völlig unterabgetastetes Signal das viel zu langsam 
digitalisiert wird.

Zudem siehst du wie das Signal an das Maximum des AD-Wandlers stößt. 
Vermutlich überschreitest du die maximale Belastbarkeit des Sensors. Der 
gibt maximale Spannung aus. Schau dir das doch mal mit einem Oszilloskop 
an. Langsame Zeitbasis und dann testest mal. Wenn du da mit dem Ergebnis 
zufrieden bist, kannst du überlegen es in den Controller zu bringen.

Ich sehe in deinen Rohdaten (?) wohl 3x Aufprall. Nur eben stößt dein 
Signal sofort an die Grenzen. Ich schätze mal dein Sensor ist einfach 
nicht für die Beschleunigungswerte die auftreten geeignet. Das kannst du 
aber mit einem Oszi herausfinden.

von guest (Gast)


Lesenswert?

Ralf B. schrieb:
> Dein Code sieht okay aus

Nö, so wie das dasteht sicher nicht.
Zu den Ausgaben weiter oben passt das aber tatsächlich nicht, der 
gezeigte Code würde ausschließlich Nullen ausgeben.

von Ralf B. (Firma: Scorptech) (mad_scorp)


Lesenswert?

guest schrieb:
> Nö, so wie das dasteht sicher nicht.
> Zu den Ausgaben weiter oben passt das aber tatsächlich nicht, der
> gezeigte Code würde ausschließlich Nullen ausgeben.

Hab nicht auf die Datentypen geachtet. Respekt, gut gesehen.

@TO: deine Division funktioniert so nicht, du musst 5.0 oder 1024.0 
schreiben. Oder du definierst diese beiden Werte direkt als float.

von Ralf B. (Firma: Scorptech) (mad_scorp)


Lesenswert?

Joni schrieb:
> Entspricht denn 1023 dem Maximalwert?

Der A/D Wandler hat 10bit, damit ist 1023 der Maximalwert.

von Joni (Gast)


Lesenswert?

Ich danke euch. Das sind gute Tipps

von guest (Gast)


Lesenswert?

Ralf B. schrieb:
> @TO: deine Division funktioniert so nicht, du musst 5.0 oder 1024.0
> schreiben. Oder du definierst diese beiden Werte direkt als float.

Da der AVR keine FPU hat macht das aber u.U. das Timing endgültig zu 
Sau.

Test schrieb:
> Hmm ja du hast ein völlig unterabgetastetes Signal das viel zu langsam
> digitalisiert wird.

OK analogRead ist auch nicht grade die schnellste Variante den ADC zu 
lesen und das Serial.println kommt auch noch dazu, da sind dann die 
floats wohl auch egal.

Die Formel stimmt aber so auch nicht, der Wert in mv ist in V nicht in 
mV.
Wenn ich das DB richtig lese hat der Sensor einen Offset, der in der 
Formel ebenfalls fehlt.

von Wolfgang (Gast)


Lesenswert?

Joni schrieb:
> Erwartet hätte ich den Verlauf einer quadratischen Funktion oder
> ähnlich.

Wofür erwartest du eine quadratische Funktion?
Bei konstanter Fallhöhe fällt dein Helm zunächst nahezu kräftefrei und 
prallt dann auf. Mit welcher Zeitauflösung erfasst du deine Werte?

von Joni (Gast)


Lesenswert?

Habe einen weiteren Versuch gestartet Fallhöhe 1m.
Habe die Daten dieses Mal mit einer Zeitauflösung 1 ms (delay(1);) 
erfasst.
Die Ergebnisse sind schon viel besser.
Jetzt habe ich das Problem das die Daten mit CoolTerm nicht zuverlässig 
und schnell genug erfasst werden.
Hat jemand eine Idee wie ich die Daten zuverlässig erfassen und 
speichern könnte?


Werte:

509
509
509
508
510
545
551
549
567
569
571
575
565
563
568
520
473
479
501
539
501
473
476
473
519
499
489
481
520
513

von Ralf B. (Firma: Scorptech) (mad_scorp)


Lesenswert?

Joni schrieb:
> Hat jemand eine Idee wie ich die Daten zuverlässig erfassen und
> speichern könnte?

Verschiedene Ideen, je nachdem wie kompliziert es sein soll.
1) SD Karte: einfach zu implementieren, Hardware shield ist günstig, 
Arduino hat eine Lib dafür und zum Übertragen auf den PC brauchst du nur 
die Karte rausnehmen und in den PC stecken
2) Speichern auf dem MC, externes Signal über Taster um die 
Umrechnung/das Auslesen zu starten,

Du kannst in Arduino auch abfragen, ob eine serielle Verbindung besteht, 
also ob der PC angeschlossen ist und damit das Auslesen beginnen. Auf 
jeden Fall empfehle ich zur Lektüre die Tutorials in diesem Forum zum 
AVR ADC und das Datenblatt für den MC der in deinem Arduino-Board 
werkelt.

Die Dinge aus dem Tutorial, also Steuerregister setzen und so weiter, 
funktionieren genau so in der Arduino-IDE. Interessant ist zB. die 
Möglichkeit die verschiedenen ADC Modi zu nutzen. Abhängig vom MC kann 
der ADC free running, single mode und auto-trigger. Man kann außerdem 
einen Interrupt auslösen, wenn die Messung abgeschlossen ist und ein 
Ergebnis im ADC Register steht.

von Wolfgang (Gast)


Lesenswert?

Joni schrieb:
> Habe die Daten dieses Mal mit einer Zeitauflösung 1 ms (delay(1);)
> erfasst.

Und was ist mit der Zeit für die Ausgabe mit Serial.println()?

Bei 9k6 Bd dauern 5 Zeichen so um die 5ms.

von Pete K. (pete77)


Lesenswert?

Wie lange soll der Aufprall denn dauern? Das sind doch wenige ms, wenn 
überhaupt.
Du brauchst einen großen RAM-Speicher für die Messwerte und nach Ende 
der Messung kannst Du diese ja seriell langsam ausgeben.

Mit 20 Zeilen Arduino Code ist das wohl nicht getan.

von Jim M. (turboj)


Lesenswert?

Pete K. schrieb:
> Du brauchst einen großen RAM-Speicher für die Messwerte und nach Ende
> der Messung kannst Du diese ja seriell langsam ausgeben.

Oder man nimmt einen Atmega32U4 (Arduino Mini Pro) und wirft die Werte 
schnell über USB CDC raus.

Aber auch da will man puffern.

von Joni (Gast)


Lesenswert?

Pete K. schrieb:
> großen RAM-Speicher für die Messwerte

Hmm okay. Kannst du vllt genauer erklären wie das funktionieren könnte.
Ich kann ja schlecht den RAM Speicher am Arduino erweitern oder?

Ja der Aufprall findet innerhalb weniger ms statt.

von Wolfgang (Gast)


Lesenswert?

Joni schrieb:
> Ja der Aufprall findet innerhalb weniger ms statt.

Dann wirst du ja nicht tausende von Messwerten aufzeichnen müssen, 
jedenfalls nicht, solange du mit 1kHz abtastest. Üblicherweise legt man 
einen Trigger fest und arbeitet mit definierter Pretrigger Aufzeichnung. 
Bei einem Arduino Due hättest du 96kB SRAM.
Selbst wenn du bei dem Arduino Leonardo bleibst und ansonsten ein 
bisschen RAM-sparend programmierst, würdest du dort locker 1000 
Messwerte ablegen können.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.