ADXL335 Hilfe

Hallo Liebe Arduino Gemeinde.

Ich hoffe Ihr könnt mir weiterhelfen.Mein Problem besteht darin dass ich nicht weiss wie ich den ADXL so nützen kann dass wenn ich ihn schnell kippe ich ihn quasi als Schalter benützen kann.
Zum Beispiel ich kippe den ADXL nach vorn und er ADXL übernimmt die Funktion eines Drucktasters.In etwa so:

Ungefähr ab 02:55 seht ich was ich meine.
Derzeit ist es so dass ich dafür einen Druckknopf benötige.

Liebe Grüße

Christian

Lösungsansatz:

Der ADXL gibt dir analog die LINEAREN Beschleunigungen in x, y und z -Richtung. Du kannst (sofern der Sensor im Normalzustand senkrecht steht, die x bzw. y -Werte (hängt von der Kipprichtung ab) dank Gravitation als Winkelmesser benutzen (Messwert ist proportional zum Sinus des Kippwinkels). Was du nun machst, ist in zeitlich konstanten Abständen den Sensor auslesen und die Differenz der Beschleunigung zum letzten Messwert bilden - überschreitet sie eine Schranke, dann löst der "Schalter" aus.

Was komplizierter ist aber wahrscheinlich bessere Ergebnisse liefert ist ein Ringarray - das z. B. immer die 16 letzten Messwerte speichert, so kannst du die Differenzen über größere Zeiträume ausrechnen!

Einen alternativen Lösungsweg bietet ein Gyroskop, mit dem kannst du Rotationsgeschwindigkeiten Direkt messen - sobald die Geschwindigkeit eine Schranke überschreitet, löst der Schalter aus. Einen einfachen Gyro findest du z. B. in der MPU 6050.

Zuerst einmal vielen Dank für die schnelle Antwort. Das Problem ist nur dass ich was Arduino angeht ein laienhafter Benutzer bin und ich denke diese Form von Programmierung übersteigt meinen Horizont. Falls du dich aber erbarmen willst und mir Codetechnisch ein wenig unter die Arme greifen könntest wär ich dem nicht abgeneigt.

Liebe Grüße

Christian

Hist:
Falls du dich aber erbarmen willst und mir Codetechnisch ein wenig unter die Arme greifen könntest wär ich dem nicht abgeneigt.

haha :slight_smile:

Ich nehme mal an du hast den ADXL bereits korrekt an dein Arduino angeschlossen (Achtung: Versorgung mit 3.3 V, nicht mit 5 V!), jede Achse liefert einen analogen Messwert, daher verbindest du die 3 Ausgänge des Sensors mit 3 beliebigen der anaolgen Eingänge A0-A5 des Arduinos.
Ungetestet:

#define X_AXIS A0 //Du hast die X-Leitung mit Analog0 verbunden.
#define INTERVAL 50 //alle 50 Millisekunden messen, Wert muss evtl angepasst werden um bessere Ergebnisse zu erzielen
#define TRESHOLD 20 //Schranke für auslöser - ein kleinerer Wert erhöht die Sensibilität

void setup(){
  pinMode(X_AXIS, INPUT);
}

void loop(){
  if (ReadSensor()){ //Hat der Sensor ausglöst?
    //Mach etwas


  }
}


bool ReadSensor(){
  static unsigned long lastTime = millis();  //Variable für Zeitmerker
  static int lastValue = analogRead(X_AXIS); //Variable für letzten Messwert
  if (millis()-lastTime < INTERVAL) return false; //Zeit noch nicht abgelaufen
  int value = analogRead(X_AXIS); //Sensor abrufen
  int differenz = abs( lastValue-value ); //Differnz bilden abs() = Betragsfunktion
  lastValue = value; //Messwert für nächstes Mal speichern
  return (differenz > TRESHOLD); //größer als Schranke?
}

Probiers mal aus, evtl musst du TRESHOLD und INTERVAL noch anpassen bis es gut funktioniert.

Gruß,
Marv

Vielen vielen Dank dass du mir hier mit Rat und Tat zur Seite stehst.
Ich dachte ich schliesse nur eine Achse an, da es beim Kippen ja nur auf die zu Kippen Achse ankommt (und der im Viedo das auch so macht :roll_eyes: )
Nebenbei poste ich dir einmal den Code der allerdings noch per Tastendruck auslöst.

#include <Servo.h>
//servo 1 
Servo myservo; 
Servo myservo1;
int val; // variable for reading the pin status
int val2; // variable for reading the delayed/debounced status
int buttonState;
int pos = 0;
int pos1 = 180;
int servostatus = 0;
int switchPin =2; // Switch connected to digital pin 2
int ledPin = 5;
int ledPin2 = 18;
void setup() // run once, when the sketch starts
{
//servo 1 

myservo.attach(9); 
myservo1.attach(10);
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT); 
buttonState = digitalRead(switchPin); 
myservo.write(0);
myservo1.write(175);
pinMode(ledPin2, OUTPUT);
}

void loop() // run over and over again

//servo 1
{
val = digitalRead(switchPin); // read input value and store it in val
delay(10); // 10 milliseconds is a good amount of time
val2 = digitalRead(switchPin); // read the input again to check for bounces
if (val == val2) { // make sure we got 2 consistant readings!
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
if (servostatus == 0) { // is the light off?
servostatus = 1; // turn light on!

myservo.write(0);
myservo1.write(180);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(00);


// fading
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue); 
delay(30); 


}

} else {
servostatus = 0; // turn light off!


digitalWrite(ledPin, LOW);
delay(15);
digitalWrite(ledPin2, LOW);
myservo.write(180);
myservo1.write(0);






}
}
}
buttonState = val; // save the new state in our variable
} 
}

Liebe Grüße

Chris

Hist:
Ich dachte ich schliesse nur eine Achse an, da es beim Kippen ja nur auf die zu Kippen Achse ankommt (und der im Viedo das auch so macht :roll_eyes: )

Klar, außer du willst kippen noch in den anderen Richtungen abfragen. Sonst reicht X auf A0 völlig aus.
Um deinen Code leserlich zu fromatieren, kannst du mit Strg+T im Arduino Editor die automatische Einrückfunktion benutzen - dann siehst du immer gleich welche klammern zueinander gehören, etc!

zum Code:
delay (00); ist sinnlos, weg damit. Allgmein sollte man auf delays verzichten, gerade bei Programmen, die schnell reagieren sollen sind die ein absolutes no-go! Du hast ja in deiner Hauptabrufschleife keins drin (außer das zum Entprellen, wobei man das auch anders macht!). Achtung: Die während der Delays kann der Microcontroller nicht auf den Sensor reagieren - fadende LEDs sehen vielleicht nett aus, sind aber hier erstmal störend!

Jetzt basteln wir den Code zusammen. Ich hab die ReadSensor()-Funktion so verändert, dass sie die Differenz ausgibt, dann kannst du auch die Kipprichtung (nach vorne oder nach hinten) abfragen:

#include <Servo.h>

#define X_AXIS   A0 //Du hast die X-Leitung mit Analog0 verbunden.
#define INTERVAL 50 //alle 50 Millisekunden messen, Wert muss evtl angepasst werden um bessere Ergebnisse zu erzielen
#define TRESHOLD 20 //Schranke für auslöser - ein kleinerer Wert erhöht die Sensibilität
#define ledPin   5

Servo myservo; 
Servo myservo1;

void setup()
{
  myservo.attach(9); 
  myservo1.attach(10);
  pinMode(ledPin, OUTPUT); 
  pinMode(X_AXIS, INPUT);
  myservo.write(0);
  myservo1.write(175);
}

void loop()
{
  int sensorVal = ReadSensor();
  if (sensorVal>TRESHOLD){ //Hat der Sensor ausglöst?
    digitalWrite(ledPin, HIGH);
    myservo.write(0);
    myservo1.write(180);
  }
  else if (sensorVal < -TRESHOLD){ //andere Kipprichtung?
    digitalWrite(ledPin, LOW);
    myservo.write(180);
    myservo1.write(0);
  }
}


int ReadSensor(){
  static unsigned long lastTime = millis();  //Variable für Zeitmerker
  static int lastValue = analogRead(X_AXIS); //Variable für letzten Messwert
  if (millis()-lastTime < INTERVAL) return false; //Zeit noch nicht abgelaufen
  int value = analogRead(X_AXIS); //Sensor abrufen
  int differenz = lastValue-value; //Differnz bilden abs() = Betragsfunktion
  lastValue = value; //Messwert für nächstes Mal speichern
  return differenz;
}

Vielen Dank für den Code. Ich hab das heute mal probiert doch es funktioniert nicht ganz so wie gewollt. Denn wenn ich ihn bewege gibt er zwar ein Signal aus doch auch nur solang ich ihn bewege sobald ich langsamer werde oder ganz aufhör zu schütteln macht er nix mehr.In der Praxis sieht es dann so aus als ob die Servos epileptische Anfälle hätten da sie ja ständig hin und her schalten

lg Chris

Also willst du jetzt einen Kipp- oder einen Schüttelsensor? Mein Programm stellt die Servos auf Pos1 wenn man schnell nach links KIPPT und aus Pos2 wenn man schnell nach rechts KIPPT. Klar dass die wild werden wenn du den Sensor schüttelst ;)

Doch doch ich will ja einen Kippsensor. Imgrunde genau wie im Video sprich ich kippe ihn schnell ein die eine Richtung und die Servos fahren rauf und in die andere Richting und die Servos fahren runter.

Lg

Chris

und funktioniert das nicht? Spiel mal ein wenig mit den Werten für TRESHOLD und schau obs besser wird. Ich hab nochmal über den Code drübergeschaut, kann aber keinen Fehler finden - evtl "return 0" statt "return false", sollte aber kein Prob darstellen. Was macht die LEd eigentlich? Theoretisch solltest du die ein- und ausschalten können. Evtl mal die Servos wegmachen und eine Serielle Ausgabe am PC zum Debuggen. Oder vielleicht schaut jemand anders mal über den Code drüber, ich kann ihn grade nicht testen.

ich habe heute mal etwas verwegenes versucht und zwar hab ich anstatt des Schalters einfach denadxl auf A0 Angeschlossen und das alte Programm auf den anderen Eingang umgeschrieben und seltsamerweise funktioniert das. Allerdings kann ich so keien Sensivität einstellen.

Lg Chris

So seltsam ist es nicht, dass es funktioniert, aber es ist nicht das, was ich aus deinen Vorgaben herausgelesen habe:

Erklärung: Der ADXL gibt ein Analogsignal zw. 0 V und 3.3 V aus, hälst du den Sensor waagrecht ungefähr 1.65 V. Irgendwo in dem Bereich liegt die Grenze des Arduinos, wo er zwischen HIGH und LOW entscheidet, wenn du einen Eingang mit digitalRead abfragst. So kann ein bestimmter Kippzustand auch als gedrückter bzw losgelassener Taster interpretiert werden. ACHTUNG: diese Pegel uin diesem Berich sind nicht definiert - es ist daher wahrscheinlich, dass sie von der Versorgungspannung und anderen Faktoren abhängig sind. Es war Zufall, dass es bei dir gepasst hat! Da der Sensor nur den Kippwinkel und nicht die Kippgeschwindigkeit messen kann, löst auch ein langsames Neigen ein Umschalten aus. Falls dir das reicht, tausch dein digitalRead einfach durch ein analogRead() und einem Vergleich aus. Die Sensitivität kannst du dann wie in meinem Code einfach einstellen.

Wäre es zu forsch zu fragen ob du den von mir geposteten Code ummodellieren könntest?

Liebe Grüße Chris

Hist:
Wäre es zu forsch zu fragen ob du den von mir geposteten Code ummodellieren könntest?

Den von dir geposteten leider nicht, der ist grausam :smiley: … jedenfalls mit den delays :wink:
Ich hab jetzt erstmal meine Funktion abgeändert, ist jetzt deutlich vereinfacht, da du’s ja nicht mit Kippgeschwindigkeit brauchst:

#include <Servo.h>

#define X_AXIS   A0 //Du hast die X-Leitung mit Analog0 verbunden.
#define TRESHOLD 20 //Schranke für auslöser - ein kleinerer Wert erhöht die Sensibilität
#define ledPin   5

Servo myservo; 
Servo myservo1;

void setup()
{
  myservo.attach(9); 
  myservo1.attach(10);
  pinMode(ledPin, OUTPUT); 
  pinMode(X_AXIS, INPUT);
  myservo.write(0);
  myservo1.write(175);
}

void loop()
{
  int sensorVal = ReadSensor();

  if (sensorVal>TRESHOLD){ //Hat der Sensor ausglöst?
    digitalWrite(ledPin, HIGH);
    myservo.write(0);
    myservo1.write(180);
  }
  else if (sensorVal < -TRESHOLD){ //andere Kipprichtung?
    digitalWrite(ledPin, LOW);
    myservo.write(180);
    myservo1.write(0);
  }
}

int ReadSensor(){
  static int calibration = analogRead(X_AXIS); //Variable für Kalibration, wird nur das erste mal ausgeführt
  return analogRead(X_AXIS) -calibration;  //Sensor abrufen
}

Hallo Entschuldige für das späte melden , mir kam beruflich was dazwischen. Erstmal vielen lieben Dank für deine schier endlose Geduld mit mir ;), und jetzt zu den Code dieser code funktioniert weitaus besser als der erste, allerdings das einzige Problem daran ist dass die Servos nicht die angesteuerte Position halten sondern imgrunde mit dem Sensor mitfahren. Das heisst ich bewege den Sensor und sie fahren rauf bzw runter. Ich hätte es aber gerne so dass die Servos wenn ich den Sensor auf der x Achse nach vorne kippe /drehe die Servos die erste Position Anfahren und dort verweilen und umgekehrt. Imgrunde wie im Video da bewegt ihn der Mann auch ruckartig nach vorne und die Servos fahren "rauf" dann in die andere Richtung und die Servis fahren runter.

Liebe Grüße

Chris

P.S: Ich poste morgen (heute) mal ein Video vom derzeitigen Stand und vom Wunschzustand vielleicht ist es dann leichter für dich dass aus der Ferne zu bewerten.