Winkelmessungen mit MPU6050 auf SD -Karte speichern?

Hallo,
das ist nur ein Beispiel zur Anschauung gewesen.

Funktion,mal so...
alle 5 Sekunden zählt der Zaehler eins hoch.
Wenn der Zähler den Wert 12 erreicht hat, dann wir er wieder auf 0 gesetzt und fängt von vorne an.
Das Ding zählt also nur bis 12.

05 Sekt - Zähler = 1
10 Sekt - Zähler = 2
15 Sekt - Zähler = 3
20 Sekt - Zähler = 4
u.s.w

Jetzt kannst Du:

  if (Zaehler == 5
  {
  mache etwas
 }

Immer wenn der Zähler den Wert 5 erreicht hat, dann "mache" etwas.
Von 5 bis 5 dauert hier durch den Intervall? Na, wie lange? genau!

Wenn Du alle 5 Sekunden etwas machen möchtest, dann tausche den Zähler gegen Deine Funktion aus.

unsigned long Intervall = 5000;

das ist die Intervall-Zeit, die kannst Du ändern.

Wie gesagt, der Zähler ist nur ein Beispiel dafür was man alle 5 Sekunden machen könnte.
Gruß und Spaß
Andreas

Hab ich versucht, brachte leider nichts.

Tommy (und du ?) habt leider vergessen, dass saveData() oberhalb der
if (previousmillis ...
Abfrage zu entfernen...

SkobyMobil:
das ist nur ein Beispiel zur Anschauung gewesen.

Jetzt kannst Du:

  mache etwas

Hallo Andreas,
Schon klar, dass das zur Anschauung war, aber dein Beispiel sollte helfen.
Anstatt einem Wert alle paar Sekunden werde ich versuchen den Mittelwert zu speichern.
Gruss
Norbert

michael_x:
Tommy (und du ?) habt leider vergessen, dass saveData() oberhalb der
if (previousmillis ...
Abfrage zu entfernen...

Hatte ich raus gemacht! Auch nicht funktioniert.

Stelle doch mal wieder den vollständigen aktuellen Sketch hier ein. Bei den ganzen Bruchstücken verliert man leicht den Überblick.

Gruß Tommy

Hallo,
wenn man sich Deinen Sketch aus #19 anschaut, dann ist das "dummes Zeug´s"
was Du da anstellt.

Mit jedem Durchlauf "loop" greifst Du auf den Sensor zu.
Wenn das dann erledigt ist rufst Du "saveData()" auf.

Das ist Müll hoch4.
Du weißt nicht, wie schnell dieser Ablauf von statten geht, soll heißen:
Du bist wahrscheinlich weit ausserhalb der Spezifikation Deines Sensor.

Warum? Weil Du wahrscheinlich zu schnell den Sensor ausliest. Schaue mal ins
Datenblatt wie schnell Du da sein darfst. Ich weiß nicht in was für einem Mode
Du den Sensor betreibst.

So, und bei 20° daneben brauchst Du weder einen Mittelwert noch eine Stelle
nach dem Komma. Das kann man besser mit dem Auge schätzen.

Dein ganzes millisZeugs hat auch nichts in der Funktion zu suchen.

Wenn Du die Werte des Sensor benötigst, dann solltest Du sie holen wenn Du
sie brauchst- und noch wichtiger, wenn der Sensor sie auch liefern kann.
Ungefähr so:

loop()
{
hole alle 250ms einmal einen Wert vom Sensor
berechne diesen Wert
bringe diesen Wert in das richtige Format
speicher diesen Wert auf SD
SDspeicher()
}

SDspeicher()
{
schreibe den Wert auf SD
}

Ich würde einmal mit einem Intervall von 500ms anfangen. Schneller werden
kannst Du immer noch. Mußt mal sehen wie schnell Deine SD-Geschichte ist.
Als erstes würde ich mal den Sensor kalibrieren, 20° kannst Du vergessen.
Gruß und Spaß
Andreas

Andreas und Tommy, ihr habt recht, ich fange nochmal an das von Grund neu aufzubauen.

Ich stell das ein sobald ich das habe!

Immernoch zu viele Daten, ABER diese sind jetzt in der richtigen Groessenordnung. Siehe Grafik anbei.

Jedoch muss ich nun mal sehen wie ich die Datenmenge deutlich reduzieren kann.

Hatte "smoothing" versucht....das brachte leider nichts.

// Still producing too much data!

#include <SD.h>
#include<SPI.h>
#include<Wire.h>
//
const int MPU_addr=0x68;
double AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
uint32_t timer; 
double compAngleX, compAngleY; 
#define degconvert 57.2957786 

unsigned long interval = 5000;
long previousMillis;
int count = 1;

void setup()
{
  Wire.begin();
  #if ARDUINO >= 157
  Wire.setClock(400000UL); 
  #else
    TWBR = ((F_CPU / 400000UL) - 16) / 2;
  #endif

  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  
  Wire.write(0);     
  Wire.endTransmission(true);

Serial.begin(9600);
Serial.print("Initializing SD card...");
pinMode(4, OUTPUT);

if (!SD.begin(4)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
  //setup starting angle
  //1) collect the data
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  
  AcX=Wire.read()<<8|Wire.read();     
  AcY=Wire.read()<<8|Wire.read();  
  AcZ=Wire.read()<<8|Wire.read();  
  Tmp=Wire.read()<<8|Wire.read();  
  GyX=Wire.read()<<8|Wire.read();  
  GyY=Wire.read()<<8|Wire.read();  
  GyZ=Wire.read()<<8|Wire.read();  


  double roll = atan2(AcY, AcZ)*degconvert;
  double pitch = atan2(-AcX, AcZ)*degconvert;

 
  double gyroXangle = roll;
  double gyroYangle = pitch;
  double compAngleX = roll;
  double compAngleY = pitch;
  
  timer = micros(); 
}
//
void loop(){
    
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  
  AcX=Wire.read()<<8|Wire.read();       
  AcY=Wire.read()<<8|Wire.read();  
  AcZ=Wire.read()<<8|Wire.read();  
  Tmp=Wire.read()<<8|Wire.read();  
  GyX=Wire.read()<<8|Wire.read();  
  GyY=Wire.read()<<8|Wire.read();  
  GyZ=Wire.read()<<8|Wire.read();  
  
  double dt = (double)(micros() - timer) / 1000000; 
  timer = micros(); 

  double roll = atan2(AcY, AcZ)*degconvert;
  double pitch = atan2(-AcX, AcZ)*degconvert;

  double gyroXrate = GyX/131.0;
  double gyroYrate = GyY/131.0;

  compAngleX = 0.99 * (compAngleX + gyroXrate * dt) + 0.01 * roll; 
  compAngleY = 0.99 * (compAngleY + gyroYrate * dt) + 0.01 * pitch; 

delay(1);

saveData();  
}

void saveData(){
if(SD.exists("data.csv")){ 
  Serial.println("Creating data.csv...");
  File data = SD.open("data.csv", FILE_WRITE);
  if (data) {
  (millis() - previousMillis > interval);
    previousMillis = millis();
    (count++);}
    if (count == 12){
    (count = 0);}
    if (count = 12){
    Serial.print(compAngleX, 3);Serial.print (",");
    Serial.println(compAngleY, 3);
    data.print(compAngleX, 3);data.print (",");
    data.println(compAngleY, 3);
    data.close();}
}}

Hallo,
definiere "Datenmenge"
Gruß und Dank
Andreas

Die einzige Aktion, die die "Datenmenge" begrenzt, ist der Zugriff auf die SD.
Dir war aber schon so einiges über Zeitablaufsteuerung gesagt worden. Warum nutzt Du das nicht?

Gruß Tommy

Tommy56:
Die einzige Aktion, die die "Datenmenge" begrenzt, ist der Zugriff auf die SD.
Dir war aber schon so einiges über Zeitablaufsteuerung gesagt worden. Warum nutzt Du das nicht?

Setze mich morgen dran. Hatte versucht wie Andreas vorgeschlagen hatte erst mal die Daten richtig hin zu bekommen. Das schaut jetzt gut aus und die Qualitaet der Messwerte geht vor.

SkobyMobil:
So, und bei 20° daneben brauchst Du weder einen Mittelwert noch eine Stelle
nach dem Komma. Das kann man besser mit dem Auge schätzen.

Als erstes würde ich mal den Sensor kalibrieren, 20° kannst Du vergessen.

Gruß und Spaß
Andreas

Hier ein kleines Update:

Der Sketch funktioniert auch mit dem Nano und einem SD-Modul (so wie es geplant war).

Da ich auch die Zeit mit aufzeichnen will werde ich nun noch ein RTC-Modul (DS1307) mit dran machen. Dann sollte das speichern von alle 30 Sekunden auch kein Problem mehr sein. Leider alles immer dieser Sparversand (letzten Freitag gingen die Dinger schon raus und sollen zwischen kommenden Samstag und Dienstag ankommen).

MPU leg ich auf 0x68 und RTC auf 0x69 oder anders herum.

Anbei ein keines Foto....

Der DS1307 ist sehr ungenau. Nimm lieber einen DS3231. Es sei denn, Du willst nur über kurze Zeitspannen messen.

Gruß Tommy

MPU leg ich auf 0x68 und RTC auf 0x69 oder anders herum

Ich kenn keinen DS1307 Chip, bei dem du die I2C-Adresse vorgeben könntest. ( Immer 0x68 )

Und keine große Angst vor der Ungenauigkeit (wenn du das Teil schon bestellt hast). Die hängt bei DS1307 am Quarz, ist sicherlich deutlich schlechter als DS3231, aber durch den sind die jungen Leute etwas verwöhnt worden. 5..10 Minuten zwischen zwei Sommerzeit-Umschaltungen sollte nicht allzu tragisch sein.

Ich hab eine mechanische Uhr, die geht in den zwei Tagen nach dem Aufziehen erst mal zwei Minuten vor und gleicht das dann bis zum Rest der Woche langsam aus...

michael_x:
Ich kenn keinen DS1307 Chip, bei dem du die I2C-Adresse vorgeben könntest. ( Immer 0x68 )

Und keine große Angst vor der Ungenauigkeit (wenn du das Teil schon bestellt hast). Die hängt bei DS1307 am Quarz, ist sicherlich deutlich schlechter als DS3231, aber durch den sind die jungen Leute etwas verwöhnt worden. 5..10 Minuten zwischen zwei Sommerzeit-Umschaltungen sollte nicht allzu tragisch sein.

Ich hab eine mechanische Uhr, die geht in den zwei Tagen nach dem Aufziehen erst mal zwei Minuten vor und gleicht das dann bis zum Rest der Woche langsam aus...

Man muss sich nicht immer am Schlechtesten orientieren. Das mechanische Schätzeisen ist ja auch unter den mechanischen Uhren schon am unteren Ende des Brauchbaren.

Da der TO nichts genaueres zu seinen Messabsichten gesagt hat, kann da 5-10 Minuten Abweichung im Halbjahr bei Langzeitmessungen schon zu viel Ungenauigkeit sein oder auch nicht.

Gruß Tommy

Hallo,
"Das mechanische Schätzeisen ist ja auch unter den mechanischen Uhren schon am unteren Ende des Brauchbaren."

He, he! Pass mal auf was Du hier schreibst. :wink:
Ich habe auch so ein mechanisch-analoges präzises ZeitMessGerät am Arm, nennt man Chronometer.
47 Sekunden in der Woche sind kein Problem, und- läuft auch noch, wenn "Stecker raus".
Gruß und Spaß
Andreas

Ich habe auch eine mechanische Armbanduhr. Die hat aber höchstens 2 Sekunden Differenz im Monat.
Das Schöne ist, sie zieht sich durch die Bewegung des Arms selbst auf.

2 Minuten am Tag wäre für mich indiskutabel. Das ist für mich unter der Brauchbarkeitsgrenze. Deshalb Schätzeisen - das bezog sich auf die konkret angesprochene Uhr, nicht auf alle mechanischen Uhren.

Gruß Tommy

Tommy56:
Der DS1307 ist sehr ungenau. Nimm lieber einen DS3231. Es sei denn, Du willst nur über kurze Zeitspannen messen.

Gruß Tommy

Die Dinger sind leider schon unterwegs, aber haben auch nur 4 Euro fuenf Stueck gekostet. Also falls das nichts taugt, ab in den Muell damit.

Messzeitraum ist denke ich eher durch die Batterie beschraenkt. Vielleicht mal 14 Tage. Wahscheinlich muss ich dann auch die LEDs von den Arduinos und der MPU runtermachen um Strom zu sparen. Der Uno und das Ethernet hatten meine 9V Billigbatterie innerhalb von 15 Minuten leer.

Was dabei raus kommen soll ist sowas:

Basiert auch nur auf einen ATMEGA328!

Für 14 Tage Messdauer reicht wohl auch ein DS1307 aus.

Gruß Tommy

Das ist für mich unter der Brauchbarkeitsgrenze. Deshalb Schätzeisen - das bezog sich auf die konkret angesprochene Uhr, nicht auf alle mechanischen Uhren.

Ich vergass zu erwähnen, dass die erwähnte Uhr über hundert Jahre alt ist und vor Jahrzehnten einem alten Uhrmacher (und mir) viel Freude bereitet hat, als der mir helfen durfte, die wichtigsten Lager einzeln zu erneuern. Er hatte ein Riesen-Sortiment an Messing-Kram und war so froh, dass er sich geweigert hatte, das Zeug wegzuschmeissen.

Natürlich gab es auch damals schon bessere Uhren. Dass man sie beim wöchentlichen Aufziehen richtig stellt und sie in der Woche +- 2 Minuten "genau" geht, ist für meinen Geschmack annehmbar. Wenn es mal genauer sein muss, schau ich aufs Handy :wink:

Das wichtigste für den Logger-Anwendungsfall hier ist doch, dass die Zeit nicht nach jedem Batteriewechsel des Arduino komplett weg ist...