Arduino Uno + LCD Keypad Shield + Temperatursensoren

Hallo an Alle,

ich bin neu hier und auch noch relativ neu bei der Programierung des Arduino. Ich habe schon die Beispielprojekte erfolgreich durchprobiert und möchte mich jetzt an ein größeres Projekt wagen und benötige Hilfe von erfahrnen Programmierern :slight_smile:

Ich möchte mir mit oben genannter Hardware ein Temperaturlogger bauen (so ist das Ziel).

Da ich aber das Teil nicht so häufig benutzen werde, möchte ich kein Realtimeshield verwenden, sondern beim starten, einmal die aktuelle Uhrzeit und Datum per Tasten eingeben. Wenn das erfolgt ist, sollen die Daten intern weiterlaufen (für die Speicherung auf SD Karte) das Display gelöscht werden und mir dann die Werte der Temperatursensoren angezeit werden.

Soweit soll der erste Schritt sein. Ich habe auch schon einen Sketch der "fast" das so macht wie ich es möchte, aber eben nur fast. Ich kann die Uhrzeit und das Datum einstellen, doch es bleibt immer auf der Anzeige zu sehen. Dadurch bekomme ich nur 2 Werte der Temperatursensoren noch angezeigt, da mir der Platz auf der Anzeige fehlt. ICh möchte aber 4 Sensoren anzeigen.

Bitte schaut auch mal meinen Sketch an und gebt mir Hilfe bei der Umsetzung meines Vorhabens. Ich danke schon mal im Voraus für Euche tatkräftige Unterstützung.

/******************************************************************
 * Clock and clock adjust demo by "jurs" for German Arduino Forum *
 * Hardware required: keypad shield
 * Additional library required: Time library must be installed 
 ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>  
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2


// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };
enum menuStates {menuNONE, menuTIME, menuDATE, menuYEAR};

int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
  int adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}


#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
  static boolean buttonFired;
  static long buttonDownSince;
  int State=readPadButtons();
  if (State==btnNONE)  
  { // this button is not pressed at this time
    buttonFired=false;
    buttonDownSince=0;
  }
  else if (buttonDownSince==0)
  { // button is pressed but DEBOUNCETIME did not yet started counting
    buttonFired=false;
    buttonDownSince=millis();
  }
  if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
  { // button is pressed and DEBOUNCETIME passed, so fire the button
    buttonFired=true;
    return(State); // return button 
  }  
  return(btnNONE); // no button fired this time
}




void setup()  
{
  Serial.begin(9600);           // set serial interface to 9600 baud
  lcd.begin(16, 2);             // starts the LCD display (2 lines by 16 chars)
  setTime(1357002000);          // set some initial time
}


int menuState; // global variable to hold the menu status

void  updateDisplay()
// this function updates the display (time and menu status)
{
  char lcdline[17];
  sprintf(lcdline,"%02d:%02d:%02d",hour(),minute(),second());
  lcd.setCursor(0,0);
  lcd.print(lcdline);
  lcd.setCursor(0,1);
  if (menuState==menuTIME)
    lcd.print(F("Zeit einst"));
  else if (menuState==menuDATE)
  {
    lcd.print(F("Dat:"));
    sprintf(lcdline,"%02d.%02d.   ",day(),month());
    lcd.print(lcdline);
  }  
  else if (menuState==menuYEAR)
  {
    lcd.print(F("J:"));
    sprintf(lcdline,"%04d       ",year());
    lcd.print(lcdline);
  }  
  else  
   // lcd.print(F("Normalbetrieb   "));
   printZiffernGenulltOhnePunkt(day());
   lcd.print(".");
   printZiffernGenulltOhnePunkt(month());
   lcd.print(".");
  // printZiffernGenulltOhnePunkt(year());
   //lcd.print(".");
}


void checkForNewSecond()
// function will update the display once per second
{
  static long lastsecond;
  if (lastsecond!=now())
  {
    updateDisplay();
    lastsecond=now();
  }  
}


void handleMenuTimeButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(now()+3600);
      break;
    }
    case btnLEFT:
    {
      setTime(now()-3600);
      break;
    }
    case btnUP:
    {
      setTime(now()+60);
      break;
    }
    case btnDOWN:
    {
      setTime(now()-60);
      break;
    }
  }
}

void handleMenuDateButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(hour(),minute(),second(),day(),month()+1,year());
      break;
    }
    case btnLEFT:
    {
      setTime(hour(),minute(),second(),day(),month()-1,year());
      break;
    }
    case btnUP:
    {
      setTime(hour(),minute(),second(),day()+1,month(),year());
      break;
    }
    case btnDOWN:
    {
      setTime(hour(),minute(),second(),day()-1,month(),year());
      break;
    }
  }
}

void handleMenuYearButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    case btnUP:
    {
      if (year()<2038)
        setTime(hour(),minute(),second(),day(),month(),year()+1);
      break;
    }
    case btnLEFT:
    case btnDOWN:
    {
      if (year()>2000)
        setTime(hour(),minute(),second(),day(),month(),year()-1);
      break;
    }
  }
}

 

void handleNormalButton(int button)
{
  // nothing yet
}


void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
  int curButton;
  curButton=buttonPressed();
  if (curButton==btnNONE) return; // nothing to do if no button is pressed
  else if (curButton==btnSELECT) // switch menu status
  {
    if (menuState==menuNONE) menuState=menuTIME;  
    else if (menuState==menuTIME) menuState=menuDATE;  
    else if (menuState==menuDATE) menuState=menuYEAR;
    else menuState=menuNONE;
  }
  else if (curButton!=btnNONE) // falls eine Taste gedrückt wurde
  {
    if (menuState==menuTIME) handleMenuTimeButton(curButton);  // Zeit einstellen
    else if (menuState==menuDATE) handleMenuDateButton(curButton);  // Datum einstellen
    else if (menuState==menuYEAR) handleMenuYearButton(curButton);  // Jahr einstellen
    else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
  }
  
  updateDisplay();  
}

void printZiffernGenulltOhnePunkt(int zahl) // definieren Subroutine
{
  // verschoenern Anzeige, indem wir ...
  if(zahl < 10) // wenn kleiner als 10 ...
   {
     Serial.print("0"); // fuehrende 0 einfuegen
     lcd.print("0");  // fuehrende 0 einfuegen
   }
   Serial.print(zahl); // Ausgabe auf serieller Konsole
   lcd.print(zahl); // Ausgabe auf LCD     
}

void printZiffernGenulltmitPunkt(int zahl) // definieren Subroutine
{
  // verschoenern Anzeige, indem wir ...
  Serial.print(":"); // trennende ":" einfuegen
  lcd.print(":"); // trennende ":" einfuegen
  if(zahl < 10) // wenn kleiner als 10 ...
  {
     Serial.print('0'); // fuehrende 0 einfuegen
     lcd.print("0");
  }
  Serial.print(zahl); // Ausgabe auf serieller Konsole
  lcd.print(zahl);     
}



void loop()


{ 
  sensors.requestTemperatures();
      lcd.setCursor(11, 0);
      //lcd.print("0: ");
      lcd.print(sensors.getTempCByIndex(0));
     // lcd.print("C");
     
      lcd.setCursor(11, 1);
     // lcd.print("1: ");
      lcd.print(sensors.getTempCByIndex(1));
     // lcd.print("C");
  
  
     
  checkForNewSecond();      // einmal pro Sekunde das Display updaten
  handleButtons();
}

[code/]

Ich würde mich freuen wenn mir jemand helfen kann.

Du könntest die SW Emulation einer RTC nehmen zB http://www.leonardomiliani.com/2011/swrtc-un-orologio-in-tempo-reale-via-software/?lang=en
Grüße Uwe

Vielen Dank!

Ich möchte das Programm nur verändert haben. Wer kann mir helfen.

Musikhai:
Ich danke schon mal im Voraus für Euche tatkräftige Unterstützung.

Bevor Du meinen Beispiel-Sketch für ein Einstellmenü durch Deine Mangel gedreht hast, war es so, dass sämtliche Ausgaben auf dem LCD-Display in nur einer einzigen Funktion "updateDisplay()" erfolgten.

Und genau das machst Du am besten auch wieder: Statt Eingabe-Verarbeitung-Ausgabe in Deiner Erweiterung munter zu mixen, hältst Du die Ausgabe auf LCD wieder da zusammen, wo sie hingehört: In der Funktion "updateDisplay()".

Im Prinzip verstehe ich Dich so, dass der Sketch innerhalb des Menüs das macht (Zeit und Datum einstellen), was Du möchtest, nur die "Normalanzeige" möchtest Du anders haben. Das ist ganz einfach: Du prüfst am Anfang der Funktion, ob der menuState "menuNONE" ist, und wenn ja gibst Du die Daten genau so auf dem LCD aus wie es sein soll und verläßt danach die Funktion mit "return".

void  updateDisplay()
// this function updates the display (time and menu status)
{
  if (menuState==menuNONE)
  {
     // gib auf LCD aus was Du möchtest
     return;
  }
...

Außerdem mußt Du natürlich die verwarzte Temperaturabfrage anders machen: Zwischen
sensors.requestTemperatures();
und
temp1=sensors.getTempCByIndex(0);
temp2=sensors.getTempCByIndex(1);
müssen mindestens 750 ms Zeit vergangen sein. Wenn nicht, legt vermutlich die Dallas-Library die notwendige Pause per "delay()" Aufruf ein und versaut damit jedes interaktive Programm, das auf Tastendrücke umgehend und blitzschnell reagieren soll: Wenn gerade ein "delay(750)" läuft, ist das eine Blockierung des Programmablaufs für 750ms und das Programm kann in dieser Zeit nicht auf Tastendrücke reagieren. Du kannst es z.B. so lösen, daß Du die Temperaturauslesung auch an den Sekundentakt knüpfst, z.B. requestTemperatures() in geraden Sekunden und getTempCByIndex() in ungeraden Sekunden aufrufen.

Interaktive Programme müssen OHNE DELAY programmiert werden!
Und das gilt auch für Delay-Aufrufe in Libraries, die dürfen auch nicht stattfinden.
Ansonsten kann es sein, dass bei Vorhandensein von delay(750) eine Taste bis zu einer dreiviertel Sekunde gedrückt werden muss, damit das Programm darauf reagieren kann. Damit wird die Bedienung ganz schön hakelig.

Vielen Dank Jurs für deine Antwort.

Könntest du mir bitte hilfreicher unter die Arme greifen, denn ich habe glaube deine Orginalversion nicht mehr und weis auch leider nicht, wie ich das mit dem auslesen der Fühler anders programieren soll.

Ich würde mich über deine Hilfe sehr freuen!

Danke schon einmal im Voraus.

Hallo jurs,

ich habe gerade mal hier lange zurück gesehen und habe dort deine orginal Version des Sketches gefunden und sie auch gleich mal verändert.

Ich hoffe, dass der Sketch Deinen hohen Anforderungen gerecht wird :wink:

Nun möchte ich Ihn aber wie gesagt weiter ausbauen und mit dem Thema habe ich mich überhaupt noch nicht beschäfftigt. Ich möchte es wie gesagt als Themperaturlogger verwenden und das Datum, die Urzeit und die 4 Temperaturwerte auf einer SD Karte speichern, so dass ich die Werte dann mit Excel auswerten kann.

Ich hoffe du kannst mir dabei ebenfalls weiterhelfen. Danke schon mal und hier der momentan soweit funktionierende Sketch

/******************************************************************
 * Clock and clock adjust demo by "jurs" for German Arduino Forum *
 * Hardware required: keypad shield
 * Additional library required: Time library must be installed 
 ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>  
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2


// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };
enum menuStates {menuNONE, menuTIME, menuDATE, menuYEAR};

int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
  int adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}


#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
  static boolean buttonFired;
  static long buttonDownSince;
  int State=readPadButtons();
  if (State==btnNONE)  
  { // this button is not pressed at this time
    buttonFired=false;
    buttonDownSince=0;
  }
  else if (buttonDownSince==0)
  { // button is pressed but DEBOUNCETIME did not yet started counting
    buttonFired=false;
    buttonDownSince=millis();
  }
  if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
  { // button is pressed and DEBOUNCETIME passed, so fire the button
    buttonFired=true;
    return(State); // return button 
  }  
  return(btnNONE); // no button fired this time
}




void setup()  
{
  Serial.begin(9600);           // set serial interface to 9600 baud
  lcd.begin(16, 2);             // starts the LCD display (2 lines by 16 chars)
  setTime(19,31,0,16,7,11);    // set some initial time
}


int menuState; // global variable to hold the menu status

void  updateDisplay()
// this function updates the display (time and menu status)
{
  
  if (menuState==menuNONE)
  {
    
    sensors.requestTemperatures();
    lcd.setCursor(0, 0);
    lcd.print(sensors.getTempCByIndex(0));
    
     
    lcd.setCursor(0, 1);
    lcd.print(sensors.getTempCByIndex(1)); 
   
    lcd.setCursor(5, 0);                        //Zeichen löschen welche noch vom Menu der Zeiteinstellung zwischen den Temperaturwerten stehen
    lcd.print("      ");
    lcd.setCursor(5, 1);                        //Zeichen löschen welche noch vom Menu der Zeiteinstellung zwischen den Temperaturwerten stehen
    lcd.print("      ");    
   
    lcd.setCursor(11, 0);
    lcd.print(sensors.getTempCByIndex(2)); 
    
    lcd.setCursor(11, 1);
    lcd.print(sensors.getTempCByIndex(3)); 
    
      
    return;
 
 
  }
  
  char lcdline[17];
  sprintf(lcdline,"%02d:%02d:%02d",hour(),minute(),second());
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(lcdline);
  lcd.setCursor(0,1);
  if (menuState==menuTIME)
    lcd.print(F("Zeit einstellen "));
  else if (menuState==menuDATE)
  {
    lcd.print(F("Datum: "));
    sprintf(lcdline,"%02d.%02d.   ",day(),month());
    lcd.print(lcdline);
  }  
  else if (menuState==menuYEAR)
  {
    lcd.print(F("Jahr: "));
    sprintf(lcdline,"%04d      ",year());
    lcd.print(lcdline);  
     
}  
  
    else  
   
   // lcd.print("C");
  lcd.print(F("Normalbetrieb   "));
 // lcd.clear();
  

}


void checkForNewSecond()
// function will update the display once per second
{
  static long lastsecond;
  if (lastsecond!=now())
  {
    updateDisplay();
    lastsecond=now();
  }  
}


void handleMenuTimeButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(now()+3600);
      break;
    }
    case btnLEFT:
    {
      setTime(now()-3600);
      break;
    }
    case btnUP:
    {
      setTime(now()+60);
      break;
    }
    case btnDOWN:
    {
      setTime(now()-60);
      break;
    }
  }
}

void handleMenuDateButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(hour(),minute(),second(),day(),month()+1,year());
      break;
    }
    case btnLEFT:
    {
      setTime(hour(),minute(),second(),day(),month()-1,year());
      break;
    }
    case btnUP:
    {
      setTime(hour(),minute(),second(),day()+1,month(),year());
      break;
    }
    case btnDOWN:
    {
      setTime(hour(),minute(),second(),day()-1,month(),year());
      break;
    }
  }
}

void handleMenuYearButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    case btnUP:
    {
      if (year()<2038)
        setTime(hour(),minute(),second(),day(),month(),year()+1);
      break;
    }
    case btnLEFT:
    case btnDOWN:
    {
      if (year()>2000)
        setTime(hour(),minute(),second(),day(),month(),year()-1);
      break;
    }
  }
}



void handleNormalButton(int button)
{
  // nothing yet
}


void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
  int curButton;
  curButton=buttonPressed();
  if (curButton==btnNONE) return; // nothing to do if no button is pressed
  else if (curButton==btnSELECT) // switch menu status
  {
    if (menuState==menuNONE) menuState=menuTIME;  
    else if (menuState==menuTIME) menuState=menuDATE;  
    else if (menuState==menuDATE) menuState=menuYEAR;
    else menuState=menuNONE;
  }
  else if (curButton!=btnNONE) // falls eine Taste gedrückt wurde
  {
    if (menuState==menuTIME) handleMenuTimeButton(curButton);  // Zeit einstellen
    else if (menuState==menuDATE) handleMenuDateButton(curButton);  // Datum einstellen
    else if (menuState==menuYEAR) handleMenuYearButton(curButton);  // Jahr einstellen
    else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
  }
  updateDisplay();  
}


void loop()
{
  
  checkForNewSecond();      // einmal pro Sekunde das Display updaten
  handleButtons();
}

[code/]

Hallo an Alle,

es wäre sehr schön, wenn sich außer jurs noch jemand anderes mit dem beschrieben Thema auskennt und mir bei der Lösung meines Projektes behilflich sein könnte.

Vielen Dank

Hier noch einmal mein Hilferuf.

Wer kann mir helfen, meinen Shield so zu ändern, dass ich Datum, Zeit und die Temperaturwerte auf SD-Karte speichern kann um sie dann in Excel zu verarbeiten?

SD Karten Tutorial:

Versuch erst mal so irgendwelche Text drauf zu schreiben. Wenn das funktioniert kannst du das in dein Projekt integrieren. Da sind in der IDE auch Beispiele dabei, inklusive Daten-Logger. Wobei die Wahl von String-Objekten da keine so gute Idee ist, aber das geht genauso mit C-strings oder einfach Variablen.

Musikhai:
Ich hoffe, dass der Sketch Deinen hohen Anforderungen gerecht wird :wink:

Dein Sketch muss ja nur Deinen Anforderungen gerecht werden!

Funktioniert es denn jetzt mit der Anzeige so, wie Du es haben wolltest?

So wie es aussieht, hast Du jetzt die Temperaturmessung aus "Temperaturanforderung" und "Messwertablesung" mit der dreiviertel Sekunde Delay in die Normalanzeige gepackt. Dadurch ist zwar immer noch die drieviertel Sekunde Delay drin, aber es wird nicht mehr das gesamte Menü behindert, sondern Du brauchst nur um von der Normalanzeige ins Menü zu gelangen den Select-Button für bis zu 0,75 s gedrückt halten, danach funktioniert das Menü normal. Und es werden keine Temperaturen gemessen, bis das Menü wieder verlassen wird.

Wenn Du damit leben kannst, ist es doch OK.

Musikhai:
Wer kann mir helfen, meinen Shield so zu ändern, dass ich Datum, Zeit und die Temperaturwerte auf SD-Karte speichern kann um sie dann in Excel zu verarbeiten?

Eine Funktion zum Datenlogging von Temperaturen auf SD-Karte hatte ich hier schon mal gepostet:
http://forum.arduino.cc/index.php?topic=180875.msg1344151#msg1344151

Die beiden Funktionen
void logTemperatures(float t1, float t2, float t3)
und
void writeLogline(char* filename, char* line)
kannst Du in Deinem Sketch bestimmt verwenden, wenn Du logTemperatures() von 3 auf 4 zu loggende Temperaturen umschreibst und die Formatierung der Zeitangabe auf die von Dir verwendete Time-Library umschreibst.

Die von Dir in der updateDisplay() gemessenen Temperaturen dürftest Du nur nicht nach der Abfrage direkt mit print() nur auf das Display ausgeben, sondern die Temperaturen müßten auch in globalen Variablen zwischengespeichert werden, damit die in der loop-Funktion aufgerufene Datenloggerfunktion auf die jeweils aktuell gemessenen Temperaturen zugreifen kann, wenn die Zeit zum Schreiben einer neuen Zeile in die Logdatei gekommen ist.

Übrigens: Wenn Du keine Echtzeituhr verwendest, wird Dir die Arduino-Zeit ganz schön weglaufen, insbesondere bei moderneren Boards im R3-Design, die die Schwingfrequenz mit einem Resonator und nicht mit einem Schwingquarz stabilisieren. Mögliche Zeitabweichung z.B. 1 Sekunde auf 400 Sekunden, das macht auf einen Tag ca. 216 Sekunden Abweichung. Gggf. auch noch mehr sind möglich, wenn Du die aus der Taktfrequenz gebildete Zeit nicht regelmäßig mit einer Realtime-Clock synchronisierst.

Hallo jurs,

danke dir für deine Nachricht. Die Anzeige und die Einstellung funktioniert so wie ich es mir vorgestellt habe und ist für mich ok.

Jetzt zu dem Thema SD Karte. Also deinen Post finde ich gut und auch sicherlich sehr informativ. Leider bin ich mit der Programierung bzw. dem Einbau der Programmteile doch etwas überfordert.

Du kennst ja meine Vorstellungen. Könntest du mir bitte bei der Programierung für die SD Karte behilflich sein ? :wink:

Ich danke dir schon mal im Voraus.

Wer kann mir helfen, in mein vorhandenes Programm die Speicherung des Datums, der Urhzeit und der 4 Temperatursensoren auf eine SD Karte zu programieren, damit ich diese Daten auf meinem PC mit Excel lesen und weiterverwenden kann?

Ich bin für jede Hilfe sehr dankbar.

...damit ich diese Daten auf meinem PC mit Excel lesen und weiterverwenden kann?

Du kannst mit Excel ( oder openoffice-calc ) jede Textdatei importieren und dabei angeben, wie einzelne Spalten getrennt werden sollen (z.B. durch Tab ( dann müsste der Arduino ein '\t' in die Datei zwischen zwei Werte schreiben ), oder ein Semikolon )

Wenn die Datei die Endung .csv hat und du bei Excel deutsche Einstellungen hast, ist das Semikolon als Spaltentrenner schon vordefiniert und du kannst die Datei direkt in Excel öffnen.

Danke michael_x für deine Nachricht. Es geht mir aber nicht um das Auslesen und umwandeln der SD Karte, sonder um die Änderung meines Programms um die SD Karte mit meinen Daten zu beschreiben.

Da solltest du schon schreiben, was du aus jurs' "Beispielen" gemacht hast, und womit du warum nicht weiter kommst...

Hast du Schwierigkeiten, dies

void logTemperatures(float t1, float t2, float t3)
{
 ...
}

von hier : http://forum.arduino.cc/index.php?topic=180875.msg1344151#msg1344151 auf deine Bedürfnisse anzupassen ?

Manche mögen den kompletten Code sehen, andere bevorzugen einen Sketch der nur dein Problem zeigt.
Ich seh gern beides : nur das Problem, aber komplett kompilierbar :wink:

Hallo Michael_x,

mein Problem besteht darin, dass ich in mein Programm, welches bereits so funktioniert wie ich es haben möchte, nun noch die Speicherung der Daten (Datum, Uhrzeit, 4 Temperaturfühler) auf eine SD Karte speichern möchte. Diese Daten möchte ich dann am PC mit Excel auslesen und auswerten.

Wie gesagt ich bin programmiertechnisch nicht ganz so professionell bewandert und deshalb brauche ich die Hilfe zum Umbau des Programms.

Hier jetzt mein bestehendes Programm

/******************************************************************
 * Clock and clock adjust demo by "jurs" for German Arduino Forum *
 * Hardware required: keypad shield
 * Additional library required: Time library must be installed 
 ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>  
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2


// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };
enum menuStates {menuNONE, menuTIME, menuDATE, menuYEAR};


int backLight   = 10;    // LCD Panel Backlight LED connected to digital pin 10
int lightLevel  = 20;    // Initialise light 20


int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
  int adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}


#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
  static boolean buttonFired;
  static long buttonDownSince;
  int State=readPadButtons();
  if (State==btnNONE)  
  { // this button is not pressed at this time
    buttonFired=false;
    buttonDownSince=0;
  }
  else if (buttonDownSince==0)
  { // button is pressed but DEBOUNCETIME did not yet started counting
    buttonFired=false;
    buttonDownSince=millis();
  }
  if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
  { // button is pressed and DEBOUNCETIME passed, so fire the button
    buttonFired=true;
    return(State); // return button 
  }  
  return(btnNONE); // no button fired this time
}




void setup()  
{
  Serial.begin(9600);           // set serial interface to 9600 baud
  lcd.begin(16, 2);             // starts the LCD display (2 lines by 16 chars)
  setTime(19,31,0,25,8,13);    // set some initial time
}


int menuState; // global variable to hold the menu status

void  updateDisplay()
// this function updates the display (time and menu status)
{
  
  if (menuState==menuNONE)
  {
    
    sensors.requestTemperatures();
    lcd.setCursor(0, 0);
    lcd.print(sensors.getTempCByIndex(0),1);
    
     
    lcd.setCursor(0, 1);
    lcd.print(sensors.getTempCByIndex(1),1); 
   
    lcd.setCursor(4, 0);                        //Zeichen löschen welche noch vom Menu der Zeiteinstellung zwischen den Temperaturwerten stehen
    lcd.print("       ");
    lcd.setCursor(4, 1);                        //Zeichen löschen welche noch vom Menu der Zeiteinstellung zwischen den Temperaturwerten stehen
    lcd.print("       ");    
   
    lcd.setCursor(11, 0);
    lcd.print(sensors.getTempCByIndex(2),1); 
    
    lcd.setCursor(11, 1);
    lcd.print(sensors.getTempCByIndex(3),1); 
    
      
    return;
 
 
  }
  
  char lcdline[17];
  sprintf(lcdline,"%02d:%02d:%02d",hour(),minute(),second());
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(lcdline);
  lcd.setCursor(0,1);
  if (menuState==menuTIME)
    lcd.print(F("Zeit einstellen "));
  else if (menuState==menuDATE)
  {
    lcd.print(F("Datum: "));
    sprintf(lcdline,"%02d.%02d.   ",day(),month());
    lcd.print(lcdline);
  }  
  else if (menuState==menuYEAR)
  {
    lcd.print(F("Jahr: "));
    sprintf(lcdline,"%04d      ",year());
    lcd.print(lcdline);  
     
}  
  
    else  
   
   // lcd.print("C");
  lcd.print(F("Normalbetrieb   "));
 // lcd.clear();
  

}


void checkForNewSecond()
// function will update the display once per second
{
  static long lastsecond;
  if (lastsecond!=now())
  {
    updateDisplay();
    lastsecond=now();
  }  
}


void handleMenuTimeButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(now()+3600);
      break;
    }
    case btnLEFT:
    {
      setTime(now()-3600);
      break;
    }
    case btnUP:
    {
      setTime(now()+60);
      break;
    }
    case btnDOWN:
    {
      setTime(now()-60);
      break;
    }
  }
}

void handleMenuDateButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(hour(),minute(),second(),day(),month()+1,year());
      break;
    }
    case btnLEFT:
    {
      setTime(hour(),minute(),second(),day(),month()-1,year());
      break;
    }
    case btnUP:
    {
      setTime(hour(),minute(),second(),day()+1,month(),year());
      break;
    }
    case btnDOWN:
    {
      setTime(hour(),minute(),second(),day()-1,month(),year());
      break;
    }
  }
}

void handleMenuYearButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    case btnUP:
    {
      if (year()<2038)
        setTime(hour(),minute(),second(),day(),month(),year()+1);
      break;
    }
    case btnLEFT:
    case btnDOWN:
    {
      if (year()>2000)
        setTime(hour(),minute(),second(),day(),month(),year()-1);
      break;
    }
  }
}



void handleNormalButton(int button)
{
  // nothing yet
}


void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
  int curButton;
  curButton=buttonPressed();
  if (curButton==btnNONE) return; // nothing to do if no button is pressed
  else if (curButton==btnSELECT) // switch menu status
  {
    if (menuState==menuNONE) menuState=menuTIME;  
    else if (menuState==menuTIME) menuState=menuDATE;  
    else if (menuState==menuDATE) menuState=menuYEAR;
    else menuState=menuNONE;
  }
  else if (curButton!=btnNONE) // falls eine Taste gedrückt wurde
  {
    if (menuState==menuTIME) handleMenuTimeButton(curButton);  // Zeit einstellen
    else if (menuState==menuDATE) handleMenuDateButton(curButton);  // Datum einstellen
    else if (menuState==menuYEAR) handleMenuYearButton(curButton);  // Jahr einstellen
    else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
  }
  updateDisplay();  
}


void loop()
{
  analogWrite(backLight, lightLevel);  // schreibe an PIN10 LCD Beleuchtung den Wert siehe INT
  
  checkForNewSecond();      // einmal pro Sekunde das Display updaten
  handleButtons();
}

[code/]

Und hat dein LCD Keypad Shield auch einen SD Card Adapter ?
Oder hast du ein zusätzliches SD Card Shield das du huckepack mit draufsetzt?
Funktioniert der SD Card Adapter generell ? Beispiel-Sketche ...
Es gibt einige DataLogger Beispiele, funktionieren diese ? ( jurs' schon früher erwähntes Beispiel zum Daten aufzeichnen )
( Zusammen mit deinem LCD Shield ? )

Wie man generell zwei Beispiele in einen Sketch zusammenbringt hast du schonmal probiert ?

Für alle Fälle:

  • Alle #include zusammen, alle globalen Variablen zusammen, alles was beide Beispiele in setup und loop haben, zusammen, alle Funktionen zusammenkopieren ...
    Dann sich Gedanken um die Fehlermeldungen beim "Sketch Überprüfen" machen ... :wink:

Ich habe folgendes SD Shiel

und ich habe noch nicht probiert die beiden Beispiele zusammen zu kopieren. traue mich da irgend wie nicht ran und hatte gehofft, dass jemand hier, da ganz viel Ahnung hat und mein Programm bitte dahin gehen ergänzen bzw. verändern könnte.

Kann mir denn wirklich niemand bei der Realisierung meines Vorhabens behilflich sein ? :frowning: Schade

Hast du die SD Beispiele alleine denn schon zufriedenstellend am Laufen gehabt, mit deinem LC-Studio Modul ?
Da gibt es reichlich Diskussionen, ob die 5V Signale des Arduino so überhaupt zulässig sind.
http://forum.arduino.cc/index.php?topic=182819.msg1359735#msg1359735
http://forum.arduino.cc/index.php?topic=166445.msg1241848#msg1241848

Ich hab mit einer kleinen alten SD Karte und "Rückwärts-Dioden als Level-Shifter" Erfolg, aber es scheint auch oft "so" zu gehen.
Der Innenwiderstand eines Arduino Output scheint schon zu reichen...
http://forum.arduino.cc/index.php?topic=134481.msg1011244#msg1011244

Was die Software angeht:

ich habe noch nicht probiert die beiden Beispiele zusammen zu kopieren. traue mich da irgend wie nicht ran

Mach doch ein backup von deinem Sketch. Und dann frisch ans Werk :wink:

Der Arduino ist zum Selber Programmieren gemacht. Für Hilfe dabei ist dieses Forum...