adxl 335 auslesen

Hallo Forengemeinde,
wie einige Fragen welche ich in diesem Forum gelesen habe, fängt auch meine damit an, dass ich neu in der Arduino-Welt bin.

Ich habe mir einen Sensor ADXL 335 zugelegt und mir ein Arduino Micro Board geliehen.
Auf einer Steckplatte habe ich beide miteinander verbunden (3,3 V, GND, A0=x, A1=y, A2=z).
Bei dem ganzen habe ich mich an ein Tutorial der FH Trier orientiert: Arduino Tutorial: Kapitel 3.3.1: "Der Beschleunigungssensor (ADXL 335)" (2/2) - YouTube

int pinX = A0;     // X-Achse
int pinY = A1;     // Y-Achse
int pinZ = A2;     // Z-Achse

void setup()
  {
  Serial.begin(9600);
  }

void loop()
  {
  // Sensorwerte ausgeben
  Serial.print(analogRead(pinX));
  Serial.print(";");
  Serial.print(analogRead(pinY));
  Serial.print(";");
  Serial.print(analogRead(pinZ));
  Serial.print(";");
  Serial.println();
  // etwas warten
  delay(200);
  }

Ich habe in der Arduino-Software entsprechend mein Board und meine Com-Schnittstelle ausgewählt.
Reset-Button am Board gedrückt und dann auf upload.
Meine Daten welche mir ausgespuckt werden, sind aber nicht das was ich haben möchte.
Und zwar laufen die so hoch und runter (Sensor steht still):
0;0;0;
194;217;178;
43;73;91;
168;210;219;
366;411;385;
783;936;845;
789;983;983;
958;1016;1005;

Wahrscheinlich mache ich einen ganz simplen Fehler, welchen ich aber noch nicht entdeckt habe.
Wäre super, wenn mir jmd ein Tipp geben könnte woran das liegen könnte.
Vielen Dank schonmal

Wenn der Sensor mit 3,3 V versorgt wird und der Sensor nur Spannungen zw. 0 V und der Versorgungsspannung ausgibt, kann analogRead keine Werte größer als ~670 erreichen. Daher tippe ich auf einen Vertratungsfehler. Entweder sind die Stromversorgung oder die Datenleitungen nicht richtig verbunden.
Zweitens: Nach dem Reset sollten zwar alle I/O-Pins als Input konfiguriert sein, mach aber sicherheitshalber für jeden der 3 Eingänge pinMode(pin, INPUT) in setup().

saarda:
Wäre super, wenn mir jmd ein Tipp geben könnte woran das liegen könnte.

Ändert sich daran etwas, wenn Du viel schneller ausliest, z.B. mit folgender loop-Funktion:

void loop()
  {
  // Sensorwerte ausgeben
  int x,y,z;
  for (int i=0;i<100;i++)
  {
    x=analogRead(pinX);
    y=analogRead(pinY);
    z=analogRead(pinZ);
    // etwas warten
    delay(2);
  }
  Serial.print(x);
  Serial.print(";");
  Serial.print(y);
  Serial.print(";");
  Serial.print(z);
  Serial.print(";");
  Serial.println();
}

Also 100 mal lesen mit nur 2ms delay, dann jeden hundertsten Messwert ausgeben?
Laufen die Werte dann noch genau so, oder ändert sich etwas?

Wenn die Werte dann immer noch hochlaufen oder unregelmäßig sind: Ändert sich etwas, wenn Du aus diesen 100 Werten den Mittelwert bildest und dann nach jeweils 100 Messungen den Mittelwert anzeigst? Z.B. mit diesem loop-Code:

void loop()
  {
  // Sensorwerte ausgeben
  long x=0,y=0,z=0;
  for (int i=0;i<100;i++)
  {
    x+=analogRead(pinX);
    y+=analogRead(pinY);
    z+=analogRead(pinZ);
    // etwas warten
    delay(2);
  }
  Serial.print(x/100);
  Serial.print(";");
  Serial.print(y/100);
  Serial.print(";");
  Serial.print(z/100);
  Serial.print(";");
  Serial.println();
}

Hallo ihr zwei,

zunächst vielen Dank für eure Hilfe und Tipps, sorry dass meine Antwort etwas auf sich warten ließ, leider stand noch ein bisschen was anderes am WE an.

Es ist tatsächlich ein Verdrahtungsfehler gewesen, scheinbar hatten die Pins keinen richtigen Kontakt. Jetzt passts :slight_smile:

Danke nochmal

Sorry muss hierzu nochmal eine Frage stellen.

Ich hatte bisher ein Arduino Micro eines Freundes ausgeliehen und nun mir ein Uno zugelegt.
Meine Werte des Beschleunigungssensors variieren je nachdem welches der beiden Arduino ich verwende. Am Code ändere ich nichts, bei den Tools passe ich lediglich Board und Schnittstelle an und die Position des Sensors bleibt konstant.

Dennoch erhalte ich für das Micro:
324;328;404;
324;329;404;

und für das Uno:
350;355;433;
349;355;432;
349;354;433;

wie kommt dieser Unterschied von ~30 im Messbereich zu Stande?

Normal müsste für 0g die Werte ~330 ausgespuckt werden, somit wären die Werte meines Uno zu hoch, die des Micro etwas zu gering was aber wohl noch im Toleranzbereich liegen kann

Die Werte sind von der Versorgungsspannung abhängig. Verwendet man USB vom Computer als Betriebsspannung, so kommen nur ca. 4,7 V am Arduino an, bei einem Ladegerät z. B. 5,1 V etc. So kann das je nach Aufbau der Schaltung des Arduinos (Spannungsregler, Diode etc) auch unterschiedlich sein. Miss mal die Spannung zw GND und VCC, da wirst du den Unterschied sehen!
Du darfst nicht mit Absolutwerten rechnen, sondern kalibrierst deinen Sensor in den ersten paar sek nach Programmstart mit dem Durchschnittswert, ab dann nimmst du immer nur die Differenzen zu diesen Referenzwerten.

Danke für die Hilfe!
jop da habe ich einen Unterschied. Beim Uno habe ich eine Spannung von 3,3V anliegen und beim Micro 2,6V.

Alles klar, meine Referenzwerte habe ich aufgezeichnet, Durschnittswert gebildet. Jo dann bin ich mal gespannt was für Werte ich erhalte.

Der ganze Aufbau soll dazu dienen um Belastungen eines Bauteils bei dessen Transport nachzuempfinden, wenn noch jmd Ideen hat was man aufnehmen sollte, immer her damit :wink: Temperatursensor liegt schon bereit, da mache ich mich die Tage dran zu schaffen

Hallo!

..steh grad voll am Schlauch, wegen:

Du darfst nicht mit Absolutwerten rechnen, sondern kalibrierst deinen Sensor in den ersten paar sek nach Programmstart mit dem Durchschnittswert, ab dann nimmst du immer nur die Differenzen zu diesen Referenzwerten.

Das Teil funktioniert doch mit Gravity, hab zum Kalibrieren. einen Würfel und den Sketch:

/*****************************************************************************/
//	Function:	 To calibrate the parameters and it will recommend parameter 
//				setting and print to the serial monitor.So the values of the
//				marco definitions in the ADXL335.h should be modified.
//  Hardware:    Grove - 3-Axis Analog Accelerometer
//	Arduino IDE: Arduino-1.0
//	Author:	 Frankie.Chu		
//	Date: 	 Jan 11,2013
//	Version: v1.0
//	by www.seeedstudio.com
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//
/*******************************************************************************/

#include "ADXL335.h"
int zero_x;
int zero_y;
int zero_z;
int max_x,max_y,max_z;//when 1g
float sensitivity;
ADXL335 accelerometer;
void setup()
{
	Serial.begin(9600);
	accelerometer.begin();
	int x,y,z;
	for(int i = 0;i < 20;i ++)accelerometer.getXYZ(&x,&y,&z);
	Serial.println("The calibration starts: ");
	Serial.println("First, make sure that Z-axis direction is straight up");
	Serial.println("please type any charactor if you are ready");
	while(Serial.available() == 0);
	delay(100);
	while(Serial.available() > 0)Serial.read();
	calibrate(&x,&y,&z);
	zero_x = x;
	zero_y = y;
	max_z = z;
	Serial.println("Second, make sure that X-axis direction is straight up");
	Serial.println("please type any charactor again if you are ready");
	while(Serial.available() == 0);
	delay(100);
	while(Serial.available() > 0)Serial.read();
	calibrate(&x,&y,&z);
	zero_z = z;
	float zero_xv,zero_yv,zero_zv;
	zero_xv = (float)zero_x*ADC_REF/ADC_AMPLITUDE;
	zero_yv = (float)zero_y*ADC_REF/ADC_AMPLITUDE;
	zero_zv = (float)zero_z*ADC_REF/ADC_AMPLITUDE;
	sensitivity =(float)(max_z - zero_z)*ADC_REF/ADC_AMPLITUDE;
	Serial.print("ZERO_X = ");
	Serial.println(zero_xv);
	Serial.print("ZERO_Y = ");
	Serial.println(zero_yv);
	Serial.print("ZERO_Z = ");
	Serial.println(zero_zv);
	Serial.print("SENSITIVITY = ");
	Serial.println(sensitivity,2);
	Serial.println("please modified the macro definitions with these results in ADXL335.h");
}
void loop()
{

}
void calibrate(int* _x,int* _y,int* _z)
{
	int x,y,z;
	int sum_x,sum_y,sum_z;
	accelerometer.getXYZ(&x,&y,&z);
	float ax,ay,az;
	accelerometer.getAcceleration(&ax,&ay,&az);
	if((abs(ax) < 0.06)&&(abs(ay) < 0.06))
	{
		
		*_x = x;
		*_y = y;
		*_z = z;
	}
	else if((abs(ax) < 0.06)&&(abs(az) < 0.06))
	{
		*_x = x;
		*_y = y;
		*_z = z;
	}
	else if((abs(az) < 0.06)&&(abs(ay) < 0.06))
	{
		*_x = x;
		*_y = y;
		*_z = z;
	}
	else Serial.println("calibrate error");
}

..nach dem Eintragen der Offsetwerte in ADXL335.h hab ich dann stabile G-0 an allen 3 Achsen,
sofern die ausrichtung vom Sensor passt.
Da sich ja die Y- Achse aus der Z-X Kalibrierung ergibt, kann doch eine Mittelwertbildung keine korrekten Werte liefern ?

mfg Martin

@Wasjetzt
Klar, für eine saubere Kalibrierung des Sensors ist es sinnvoll so die Nullwertdefinitionen zu speichern. Nur liegt in diesem Fall das Probelm an einer anderen Stelle. Ist die Versorgungsspannung des Sensors oder des Arduinos andres als bei der Kalibrierung, hilft es nichts wenn der Sensor im Programm perfekt kalibriert ist! Die Kalibrierung, oder besser gesagt die Referenzwertbestimmung muss immer dynamisch beim Programmstart erfolgen, da alles stark von der Versorgungsspannung abhängig ist. Vor allem bei Batteriebetrieb ist das ein nicht zu vernachlässigendes Problem. Besser ist es, wenn auch die Versorgungsspannung des Sensors gemessen wird (einfach an einen weiteren Analogeingang anschließen) und dann immer im Verhältnis gerechnet wird:

Referenzwert (beim Programmstart):
Zero_X = map(analogRead(x_pin),0,analogRead(VccSensor),0,200);

Messwert:
x = map(analogRead(x_pin),0,analogRead(VccSensor),0,200)-Zero_X;

Hallo!
Danke für die Ausführung. Hab das mit dem Kalibrieren falsch verstanden.
VCC kompensation kann man ja öfters brauchen.
Verwende die ADXL335.h und hol mit
accelerometer.getAcceleration(&ax,&ay,&az); die G-Werte ...
die sind bei 5V und 3,3 gleich und der Sensor machts auch mit.

mfg Martin

@MGOS :
wie kommst Du bei:
Zero_X = map(analogRead(x_pin),0,analogRead(VccSensor),0,200);
auf die 200?

Und allgemein in die Runde gefragt:
Ich stehe etwas auf dem Schlauch, denn ich kann die von Euch benutzte Lib ADXL335 nirgends finden. Und ja, ich habe schon danach gegoogelt. Ich komme dann nur auf eine Version von GitHub von Derek Chafin, die aber nicht mit der von Euch verwendeten identisch ist.

Schönen Ostermontag!

Hallo!

Die von Frankie Chu findest hier:

mfg Martin