Suche

Daten mit einem Ethernet Shield auf einer SD Karte speichern

Inhaltsverzeichnis

Für dieses Projekt benötigst du

Zahlenreihe mit einem Ethernet Shield für Arduino abspeichern

Aufgabe: Mithilfe des Ethernet Shields sollen Daten auf einer SD-Karte gespeichert werden. Zunächst einfach nur eine Reihe von Zahlen, die vom Arduino erzeugt werden. Später sollen dann die Daten eines DHT11 Temperatur- und Feuchtigkeitssensors auf einer SD-Karte gespeichert werden.

Mit dem Ethernet Shield ist es möglich, einen Webserver für Daten einzurichten. Es kann jedoch auch unabhängig davon zur Datenspeicherung verwendet werden. Sensorwerte können mithilfe eines Codes auf der SD-Karte in dem Ethernet Shield gespeichert werden. In dieser Anleitung werden wir die zwei Werte (Temperatur und Feuchtigkeit) des DHT11, in Form einer Excel Tabelle, auf einer SD-Karte speichern.

DHT11 Sensor am Ethernet Shield

Der Programmcode

Im ersten Sketch sollen vom Arduino lediglich zwei Zahlenreihen erzeugt werden, die dann auf der SD-Karte abgespeichert werden. Alle weiteren Erklärungen erfolgen im Sketch.

Aufbau: Es muss lediglich das Ethernet-Shield auf das Arduino-Mikrocontrollerboard gesteckt werden.

#include <SD.h>      //SD Library hinzufügen
int a=0; // Variable für einen Zählvorgang
int b=0; // Variable für einen Zählvorgang
const int chipSelect = 4; //Chip Pin für die SD Karte(bei UNO 4,bei MEGA 53)

void setup() {
pinMode (13, OUTPUT);
  if (startSDCard() == true) // Durch den Rückgriff auf den Programmblock "startSDCard" wird die SD-Karte geprüft. Wenn die SD Karte gelesen werden kann dann soll die onboard-LED an Pin13 zweimal blinken
  { 
  digitalWrite(13, HIGH); //an
  delay(500);
  digitalWrite(13, LOW); //aus
  delay(500);
  digitalWrite(13, HIGH); //an
  delay(500);
  digitalWrite(13, LOW); //aus
  delay(500);
  }
}

void loop()
{
  File dataFile = SD.open("zaehlen.csv", FILE_WRITE); //Excel Datei auf der SD Karte anlegen mit dem Namen "zaehlen" 
a=a+1; // Unter der Variablen "a" wird jetzt der Wert a+1 gespeichert. Dadurch wird der Wert für "a" in jeden Durchgang um 1 erhöht.
b=b+2; // Unter der Variablen "b" wird jetzt der Wert b+2 gespeichert. Dadurch wird der Wert für "b" in jeden Durchgang um 2 erhöht.
dataFile.print(a); // Wert für "a" wird auf die SD-Karte gespeichert
dataFile.print(";"); // Es wird ein Semikolon in die CSV-Datei gespeichert, daduch lassen sich die Werte später als Tabelle getrennt darstellen.
dataFile.println(b); // Wert für "b" wird auf die SD-Karte gespeichert
dataFile.close(); // Die Datei wird vorrübergehend geschlossen.
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500); // Hier endet der Loop und beginnt dann wieder von vorne. Es werden im Sekundentakt die Werte für "a" und "b" in die Tabelle auf der SD-Karte gespeichert.
}

boolean startSDCard() // Dieser Programmblock wird benötigt, um zu prüfen, ob die SD-Karte einsatzbereit ist.
{
  boolean result = false;
  pinMode(4, OUTPUT); // 4 bei UNO, bei MEGA in 53 ändern

  if (!SD.begin(chipSelect)) //Überprüfen ob die SD Karte gelesen werden kann
  { 
    result = false;
  } 

  else // Wenn ja Datei wie im Loop anlegen
  {  
  File dataFile = SD.open("datalog.csv", FILE_WRITE);
   if (dataFile) 
    {
      dataFile.close();
      result = true;
    }
  }  
  return result;
}

Das Ergebnis auf der SD-Karte sieht danach so aus, wenn man die Datei „zaehlen.csv“ mit einem Editor öffnet:

1;2

2;4

3;6

4;8

5;10

6;12

… und so weiter.

Wenn diese Datei nun mit einem Tabellenkalkulationsprogramm wie Excel oder LibreOffice geöffnet wird, dann dient das Semikolon als Übergang in die nächste Zelle. Kombiniert mit der Darstellung als Diagramm, sehen die Daten dann so aus:

Auswertung der Messdaten in einem Tabellenkalkulationsprogramm

Messwerte eines DHT11 Sensors mit einem Ethernet-Shield auf einer SD-Karte speichern

Im zweiten Schritt möchten wir die Messwerte eines DHT11 Sensors erfassen und mithilfe des Ethernet Shields auf einer SD-Karte speichern. Die erfassten Messwerte sollen anschließend mit einem Tabellenkalkulationsprogramm ausgewertet werden.

Der Schaltplan

Ethernet Shield auf den Mikrocontroller stecken, DHT11 anschließen:

Pin „-“ an GND des Ethernet Shields
Pin „S“ an Pin D2 des Ethernet Shields
Mittlerer Pin an „5V“ des Ethernet Shields

Der Programmcode

#include "SD.h"     //SD Library hinzufügen
#include "DHT.h"      //DHT Library hinzufügen

#define DHTPIN 2      //Pin an dem der DHT angeschlossen ist festlegen
#define DHTTYPE DHT11   //DHT Typ festlegen: Hier DHT11
#define TEMPERATURE 1   
#define HUMIDITY 0     

int feuchte;
int temperatur;

DHT dht(DHTPIN, DHTTYPE); //Sensor initializieren
const int chipSelect = 4; //Chip Pin für die SD Karte(bei UNO 4,bei MEGA 53)

void setup() {

  if (startSDCard() == true) // Durch den Rückgriff auf den Programmblock "startSDCard" wird die SD-Karte geprüft. Wenn die SD Karte gelesen werden kann dann soll die onboard-LED an Pin13 zweimal blinken
  { 
  digitalWrite(13, HIGH); //an
  delay(500);
  digitalWrite(13, LOW); //aus
  delay(500);
  digitalWrite(13, HIGH); //an
  delay(500);
  digitalWrite(13, LOW); //aus
  delay(500);
  }
  
  Serial.begin(9600); //Serielle Verbindung starten
  dht.begin();       //DHT Sensor starten
  
}

void loop()
{
  File dataFile = SD.open("werte.csv", FILE_WRITE); //Excel Datei mit dem Namen „werte“ auf der SD-Karte anlegen  
  feuchte = dht.readHumidity(); //Feuchtigkeit auslesen
  temperatur = dht.readTemperature(); //Temperatur auslesen
  
  dataFile.print(feuchte); //Feuchtigkeit in die Excel Datei eintragen
  dataFile.print(";"); // Es wird ein Semikolon in die CSV-Datei gespeichert, daduch lassen sich die Werte später als Tabelle getrennt darstellen.
  dataFile.println(temperatur); //Temperatur in die Excel Datei eintragen. Durch den Befehl mit der Endung „ln“ („LN“ in Kleinbuchstaben) wird ein Zeilenumsprung in der Wertetabelle erzeugt.
  dataFile.close(); // Die Datei wird vorrübergehend geschlossen.

  delay(1000);
   Serial.print("Luftfeuchtigkeit: "); //Im seriellen Monitor den Text und 
  Serial.print(feuchte); //die Dazugehörigen Werte anzeigen
  Serial.println(" %");
  Serial.print("Temperatur: ");
  Serial.print(temperatur);
  Serial.println(" Grad Celsius");
}

 
  
boolean startSDCard() {
  boolean result = false;
  pinMode(4, OUTPUT); // 4 bei UNO, bei MEGA in 53 ändern

  if (!SD.begin(chipSelect)) { //Überprüfen ob die SD Karte gelesen werden kann
    result = false;
  } 
  else {  // Wenn ja Datei wie im Loop anlegen
      File dataFile = SD.open("datalog.csv", FILE_WRITE);
    if (dataFile) {
      dataFile.close();
      result = true;
    }
  }  
  return result;
}

float readSensor( int thisValue) {
  float result;

  if (thisValue == TEMPERATURE) {
    result = dht.readTemperature(); //Sensorwert auslesen und unter Temperature              speichern
  } 
  else if (thisValue == HUMIDITY)  //Sensorwert auslesen und unter Humidity                   speichern
 { 
 result = dht.readHumidity();   
  }

  if (isnan(result))  // Die Library des DHT Sensors sendet beim Verlust des Signals vom DHT11 den Befehl „isnan“. Die passiert bspw. wenn das Kabel der Datenleitung zum Sensor den Kontakt verliert. In dem Fall soll als „Messwert“ die Zahl -273 angezeigt und gespeichert werden. Da dies der tiefste zu erreichende Punkt ist, dürfte jedem klar sein, dass mit den Werten etwas nicht stimmt, und dass der Aufbau überprüft werden muss.
 {
     result = -273.0; 
  }
  return result;
}

Nachdem der Code hochgeladen wurde, wird immer nach fünf Sekunden ein Wert für die Temperatur und ein Wert für die Feuchtigkeit auf der SD-Karte in einer Excel Tabelle gespeichert. Das Ergebnis könnte in einem Tabellenkalkulationsprogramm dann so aussehen:

Die Messdaten des DHT11 in einem Tabellenkalkulationsprogramm

Das Ethernet Shield als Webserver

Aufgabe: Mit dem Temperatursensor TMP36 möchten wir die Raumtemperatur auslesen und per Ethernet Shield an eine Website im Heimnetz ausgeben.

Der Aufbau dieser Anleitung orientiert sich an der Anleitung Nr. 10 –  Temperaturen messen.

Da für diesen Sketch ein Ethernet Shield verwendet wird, muss eben dieses zuerst auf das Mikrocontroller-Board gesteckt werden. Im Anschluss muss eine Verbindung zwischen dem heimischen Router und dem Shield hergestellt werden. Schließen Sie dazu ein Ende des LAN-Kabels an Ihr Ethernet Shield und das andere Ende an den Router an. Nachdem die Verbindung hergestellt wurde, können Sie den Temperatursensor TMP36 wie folgt mit dem Shield verbinden. Bitte verwenden Sie eine externe Stromversorgung (9V Netzteil oder 9V Batterie), da dies die Sensorgenauigkeit wesentlich verbessert.

Der Schaltplan

Der Programmcode

Jedes Gerät in einem lokalen Netzwerk hat eine eigene IP-Adresse. Sie wird in eher seltenen Fällen statisch festgelegt, normalerweise vergibt der DHCP-Server (Dynamic Host Configuration Protocol) sogenannte dynamische IP-Adressen, die für jedes Gerät eindeutig sind. Außerdem hat jedes Gerät eine eindeutige MAC-Adresse (hier: 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED).
Im Sketch können eine statische IP-Adresse festgelegt oder eine dynamische IP-Adresse über DHCP verwendet werden. Der „Schalter“ statischeIP entscheidet darüber:

true: Sie müssen händisch eine IP-Adresse eingeben
false: Die IP-Adresse wird über DHCP vergeben.
Sollten Sie sich für eine statische IP-Adresse entscheiden, müssen Sie eine freie IP-Adresse im Netzwerk ermitteln. Klicken Sie auf „Start“ und geben Sie unter „Ausführen“ den Befehl „CMD“ ein. Im Anschluss öffnet sich die DOSBox. Geben Sie nun den Befehl „arp -a“ ein. Es erscheint eine Auflistung aller bereits verwendeten IP-Adressen.

Die erste Zeile gibt die IP-Adresse des verwendeten Geräts an. Die nächsten Zeilen listen alle Geräte mit IP-Adressen und MAC-Adressen. Diese dürfen Sie nicht verwenden.

Nach dem Hochladen wird die IP-Adresse im Seriellen Monitor angezeigt.

Diese IP-Adresse müssen Sie in einem Browser Ihrer Wahl eingeben.

Das Programm funktioniert wie folgt:

Zuerst wird der Port für die Ausgabe des Messwertes über HTML definiert. Anschließend wird der EthernetServer initialisiert und für den Aufruf durch den Client vorbereitet. Der Sensorwert wird anschließend ausgelesen und per „map-Befehl“ in den auszugebenden Temperaturwert umgewandelt (siehe Anleitung Nr. 10). Erfolgt ein Seitenaufruf durch den Client, wird dieser Temperaturwert über das HTML-Protokoll mit dem Befehl „server.print“ nach einem kurzen „delay“ ausgegeben. Abschließend wird die Verbindung mit dem Befehl „client.stop()“ getrennt.

// Laden der notwendigen Bibliothek
#include "Ethernet.h"

int TMP36 = A3;  // Deklaration der Variablen
int sensorwert;
int temperatur = 0;

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};  // MAC Adresse des Arduino Boards  !WICHTIG! MAC Adresse darf nur einmal im Heimnetz vorkommen

// statischeIP = false -> IP-Adresse über DHCP vergeben
// statischeIP = true -> statische IP-Adresse bestimmen
bool statischeIP = false;

// statische IP
IPAddress ip(192, 168, 1, 200);
EthernetServer server(80);  // Port Einstellung (Standard für HTML : 80)

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

  // Ethernet starten statische IP
  if (statischeIP) Ethernet.begin(mac, ip);

  // Ethernet starten DHCP
  else Ethernet.begin(mac);
  server.begin();  // Auf Clients warten
  
  // zur Kontrolle IP-Adresse im Seriellen Monitor anzeigen
  // localIP -> Adresse, die im Browser eingegeben werden muss
  Serial.print(F("IP des Ethernet-Shields: "));
  Serial.println(Ethernet.localIP());
}


void loop() 
{
  sensorwert = analogRead(TMP36);                  //Auslesen des Sensorwertes an PIN A3
  temperatur = map(sensorwert, 0, 410, -50, 150);  // Umwandeln des Sensorwertes mit Hilfe des "map" Befehls
  delay(500);

  EthernetClient client = server.available();  //Prüfen, ob Client Seite aufruft
  if (client) {                                // Seitenaufruf durch User
    // Ausgabe in HTML
    server.print("HTTP/1.0 200 OK\r\nServer: arduino\r\nContent-Type: text/html\r\n\r\n");
    server.print("<HTML><HEAD><TITLE>");
    server.print("Funduino Thermometer");
    server.print("</TITLE>");
    server.print("</HEAD><BODY>");
    server.print("<h2 align=center><font size=7><b>Funduino Thermometer </b></font></h2>");
    server.print("<center><font size=5><b>Die Temperatur betr&aumlgt </font>");
    server.print(temperatur);  // Ausgabe der Temperatur
    server.print("<font size=5> Grad Celsius. </font");

    delay(500);     // Kurzer Delay, um Daten zu senden
    client.stop();  // Verbindung mit dem Client trennen
  }
}

Funduino - Dein Onlineshop für Mikroelektronik

  • Dauerhaft bis zu 10% Rabatt für Schüler, Studenten und Lehrkräfte
  • Mehr als 3.500 Artikel sofort verfügbar!
  • Über 8 Jahre Erfahrung mit Arduino, 3D-Druck und co.
SALE