Mein Projekt SD-Logger

Ich baue mir gerade eine SD-Logger. Bisheriger Stand ist:

  • Sensoren an I2C-Bus werden ausgelesen, im Atmega umgewandelt und in einer Datei gespeicehrt.
    *auf Tastendruck wird ein File erzeugt, im header wird reingeschrieben Datum_Uhrzeit_Spaltenindizes und namen.
    *es ist möglich in bestimmten zeitlichen abständen abzuspeichern 1 sek intervall, 10 sek intervall 100ms Intervall etc

Angeschlossen sind rtc von Maxim, Drucksensor&Temperatursensor von amsys, SD-Shield.

Hab noch rumliegen und soll eingebaut werden: GPS µblox LEAH4H, AD-wandler MAX127(I2C Anschluss, kein pwm sondern reiner ANAlog-Ausgang,zudem 12bit und nicht 8-Bit)

Der quellcode:

#define datumadresse 0x68
#define address2 0x78
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin 10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int  buttonPin = 2;
const int chipSelect = 10;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
int testPin=0;
int add=0;
int zeitintervall=10000;
int zaehlvariable=0;
int spaltenwert=3600;
int i=0;
char name[]="Datei00.csv";
int Druck1;// variablen für die einzelnen Bytes
  int Druck2;
  int Druck;
  int Temperatur1;
  int Temperatur2;
  int Temperatur;
  int ausgabewert_Druck;
  int ausgabewert_Temperatur;
 
void setup()
{ RTC.begin();
 if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  RTC.adjust(DateTime(__DATE__, __TIME__));
 int Druck1;// variablen für die einzelnen Bytes
  int Druck2;
  int Druck;
  int Temperatur1;
  int Temperatur2;
  int Temperatur;
  int ausgabewert_Druck;
  int ausgabewert_Temperatur;
 
  pinMode(buttonPin, INPUT);
  Wire.begin();
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
 // pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  


}

void loop()
{
  
  File dataFile = SD.open(name, FILE_WRITE);
  
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter, DEC);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      dataFile.close();
      Serial.println("off"); 
      digitalWrite(9,LOW);
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;
 if (buttonPushCounter % 2 == 0 && millis()%zeitintervall==0&&zaehlvariable<spaltenwert)
 {   
   if(zaehlvariable==0){
     DateTime now = RTC.now();
  dataFile.print(now.year(),DEC);
    dataFile.print('.');
    dataFile.print(now.month(),DEC);
    dataFile.print('.');
    dataFile.print(now.day(),DEC);
    dataFile.print('/');
    dataFile.print(now.hour(),DEC);
    dataFile.print(':');
    
   dataFile.print(now.minute(),DEC);
   dataFile.print(':');
   dataFile.print(now.second(),DEC);
   dataFile.print('\n');
 
   
      String headerString = "";
      headerString += "index"; 
     headerString += ",";
     headerString += "Luftdruck[mbar]"; 
     headerString += ",";
     headerString += "1.Byte";
     headerString += ",";
     headerString += "2.Byte";
     headerString += ",";
     headerString += "Temperatur[°C]";
     headerString += ",";
     headerString += "1.Byte";
     headerString += ",";
     headerString += "2.Byte";
     headerString += ",";
     
      dataFile.println(headerString);
     dataFile.close();
     Serial.println(name);
   }
  zaehlvariable++;
//  Wire.begin();
  Wire.beginTransmission(address2); // drucksensor initialisieren
  Wire.send(add);// Zeiger auf 0 setzen
  Wire.requestFrom(address2, 4);// bescheid sagen wiviele Bytes kommen. nämlich 4
  
     Druck1 = Wire.receive(); //1.Byte
     //Serial.println(Druck1);
     //delay(50);
     Druck2 = Wire.receive();//2.Byte
    //Serial.println(Druck2);
     //delay(50);
    Temperatur1 = Wire.receive();//3.byte
    // Serial.println(Temperatur1);
    Temperatur2 = Wire.receive();//4.Byte
    //Serial.println(Temperatur2);
    Wire.endTransmission();// ende der übertragung
     

  Druck = (((256*Druck1+Druck2)-3277)/58)+758;
  Temperatur=(((256*Temperatur1+Temperatur2)-3277)/238.31)-25;

    add++;
   if(add==3){
     add=0;
   }
 //Serial.println(taster);
  String dataString = "";
  dataString += String(millis()/1000);
  dataString += ",";
  dataString += String(Druck);
  dataString += ",";
  dataString += String(Druck1);
  dataString += ",";
  dataString += String(Druck2); 
  dataString += ",";
  dataString += String(Temperatur);
  dataString += ",";
  dataString += String(Temperatur1);
  dataString += ",";
  dataString += String(Temperatur2);
 
  
 // if the file is available, write to it:
  
    digitalWrite(9,HIGH);
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
    Serial.println(zaehlvariable);
    
  
 
   }
  if(zaehlvariable==spaltenwert){
    //char i2;
    i++;
    //i2=i;
    zaehlvariable=0;
    name[5]=i/10+'0';
    name[6]=i%10+'0';
   Serial.println(name);
   }
     else{
     digitalWrite(9,LOW);
   }
     
}

An dieser Stelle gestehe ich: das ganze ist sehr stark zusammen gestückelt.
Ich würde gerne einiges verbessern.
Für mich das offensichtlichste Problem ist derzeit die Geschichte mit dem Filenamen.
Es werden zwar immer neue Filenamen vergeben, wenn ich jedoch die Karte entferne um sie auszulesen und sie dann wieder zum beschreiben einführe, Werden die daten in das File ****00.csv geschrieben. Zwar werden sie angehangen und mit einem Timestamp versehen, aber ich fänd eine Abfrage ob der dateiname existiert schöner.

Weiter glaube ich, dass das jetztige auslösen des Schreibvorganges nicht gut gelöst ist. Es wird ja dauernd gefragt ob der Taster betätigt wurde. Das kostet Energie und wenn der SD-Logger mal im Batteriebetrieb laufen soll ist so ne arme kleine Bat. schnell leer gelutscht =(
Wie kann ich da den Spiess umdrehen?

Für weitere Anregungen, Beleidigungen und anderes Gedöns wäre ich dankbar :slight_smile:

AD-wandler MAX127(I2C Anschluss, kein pwm sondern reiner ANAlog-Ausgang,zudem 12bit und nicht 8-Bit)

Der MAX127 ist meines Wissens ein Analog-Digital-Wandler (8 Analogeingänge) kein Digital-Analog-Wandler (Analogausgang).

Weiter glaube ich, dass das jetztige auslösen des Schreibvorganges nicht gut gelöst ist. Es wird ja dauernd gefragt ob der Taster betätigt wurde. Das kostet Energie und wenn der SD-Logger mal im Batteriebetrieb laufen soll ist so ne arme kleine Bat. schnell leer gelutscht smiley-cry
Wie kann ich da den Spiess umdrehen?

Den größete Stromfresser sehe ich im GPS-Modul.
Das Abfragen eines Tasters kostet keine Energie. Das Drücken des Tasters hat einen Strom über dem Pullup/Pulldown -Widerstand zur Folge. Da dieser auch 100kOhm sein kann und man den Taster nicht andauernd drückt ist der Energieverbrauch minimal.

Grüße Uwe

Hallo Uwe, du hast natürlich recht, ich hab mich schlicht vertan.
Ein äquivaltenter DA-Wandler wird noch organisiert.

Zum GPS-Empfänger: Das werd ich wahrscheinlich über Bord werfen. Mit einer Batterie ist das zu aufwendig. Ich werde mich einfach auf das Loggen von Sensor-Signalen im Bereich von 0-5V beschränken.

Zur Allg. Programmierung, was kann ich da verbessern?