SD Shield und WAN

Hallo,

ich versuche seit einigen Tagen (und Nächten) herauszubekommen, wie ich an einem Arduino (alle möglichen UNO, NANO, MEGA und Pro mini vorhanden) eine SD Karte beschreiben und danach die Daten an einen Webserver schicken kann. Also Datenlogger mit LAN und SD Speicher. Es sollen Livedaten eines Sensors im Internet per POST gesendet werden und dann die gemessenen Werte in einer LOG Datei auf der SD Karte geschrieben werden. Einzeln bekomme ich das zum laufen aber nicht gemeinsam.

Ich weiß das man das wohl mit SPI realisieren kann aber leider will SPI nicht in mein Hirn rein. Ich habe versucht einen SPI Bus zu verwenden, aber ich komme nicht ganz klar.

Hat vielleicht jemand einen Lösungsansatz ?????

Setze die SS (oder enable) pin explizit für beide Devices auf HIGH bzw LOW bevor Du sie ansprichst.

Mehr Hilfe kannst Du erwarten wenn Du uns sagst welche Hardware Du hast (Ethernetshield, SD-Modul) und Du uns den Sketch gibst.

Grüße Uwe

Hallo uwefed,

vielen Dank schon einmal für die Info.

Setze die SS (oder enable) pin explizit für beide Devices auf HIGH bzw LOW bevor Du sie ansprichst

Aber genau wie ist dies vorzunehmen? Mit diesem HIGH und LOW komme ich halt nicht klar.

Muss ich jeden Vorgang einzeln in einer Funktion unterbringen wie zum Beispiel: “schreibe_auf_sd” und
“sende_an_server” und diese dann einleitend mit digitalWrite(pin10,HIGH); und am ende der Funktion
mit digitalWrite(pin10,LOW); definieren.

Muss ich nur SPI.begin(); in der setup Funktion unterbringen oder kommt da noch etwas hinzu.

Testhardware:

  • Arduino MEGA 2560 alternativ Pro mini
  • SD-Shield mit SPI Hersteller ??? (SCK,CS, MOSI, MISO,VCC 3,3V und 5V , GND)
  • WAN ENC28J60 mit SPI (SCK,CS, MOSI, MISO,VCC 5V ,GND, RST ,WOL ,INT )

Ich habe hier mal das Sketch beigefügt:

#include <EtherCard.h>
#include <SPI.h>
#include <SD.h>

//#define REQUEST_RATE 5000

static byte mymac[] = { 0x74,0x62,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,178,91 };
static byte gwip[] = { 192,168,178,1 };
byte Ethernet::buffer[700];
static uint32_t timer;

int impState = 0;
int lastimpState = 0;
int impCounter = 0;

//SD Card Zugriff
int CS_pin = 10;
int pow_pin = 4;

char website[] PROGMEM = "strom.ainetz.de";      // URL der Webseite

// called when the client request is complete
static void my_callback (byte status, word off, word len) {
  Ethernet::buffer[off+300] = 0;
  String stringOne = ((const char*) Ethernet::buffer + off);
}

void setup () {
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);

  Serial.begin(9600);
  Serial.println("\n[getStaticIP]");
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
  Serial.println( "Failed to access Ethernet controller");

  ether.staticSetup(myip, gwip);

  while (ether.clientWaitingGw())
    ether.packetLoop(ether.packetReceive());
  Serial.println("Gateway found");
    if (!ether.dnsLookup(website))
        digitalWrite(2, LOW); 
    
  ether.printIp("SRV: ", ether.hisip);
  
//SD LIB

  Serial.begin(9600);
  Serial.println("Initialisiere SD-Karte");
  pinMode(CS_pin, OUTPUT);
  pinMode(pow_pin,OUTPUT);
  digitalWrite(pow_pin,HIGH);
  if (!SD.begin(CS_pin))
  {
  Serial.println("Kartenfehler");
  return;
  }
  Serial.println("Karte bereit");
  }

void loop () {
  ether.packetLoop(ether.packetReceive());
 
  impState = digitalRead(2);

  if (impState != lastimpState) {
    if (impState == LOW) {
      impCounter++;
      delay(20);
    }
  }
  lastimpState = impState;  
  
  if (millis() > timer) {
    timer = millis() + 60000;

char myIntAsString[3300]; 
itoa(impCounter, myIntAsString, 10);

// PHP-Datei, Client Key, Impulse
ether.browseUrl(PSTR("/logger.php?client=4849&impulse="), myIntAsString, website, my_callback);

  String dataString = myIntAsString;
  File dataFile = SD.open("log.txt",FILE_WRITE);
  if (dataFile)
  {
  dataFile.println(dataString);
  dataFile.close();
  Serial.println(dataString + " geschrieben");
  }
  else
  {
  Serial.println("kein Datenzugriff");
  }
  impCounter = 0;
  }
}

SvenA: Aber genau wie ist dies vorzunehmen? Mit diesem HIGH und LOW komme ich halt nicht klar.

Korrigiert mich, wenn es nicht richtig ist, aber ich habe das so verstanden:

Du kannst mehrere SPI-Geräte abwechselnd nacheinander verwenden, indem Du jeweils nur ein SPI-Gerät enabelst und alle anderen disabelst.

Dazu muß jedes Gerät einen eigenen Enable-Pin haben, in den Standard-Designs bei Arduino ist das Pin-4 für die SD-Karte und Pin-10 für den Ethernet-Chip.

Enabeled wird das Gerät durch Setzen des Enable-Pin auf Low, disabeled durch Setzen auf High.

Um mit dem entsprechenden Gerät zu kommunizieren setze also wie folgt:

  1. Disable Ethernet (Pin-10 High), enable SD card (Pin-4 Low) ==> Kommunikation mit SD-Karte
  2. Enable Ethernet (Pin-10 Low), disable SD card (Pin-4 High) ==> Kommunikation mit Netzwerk

Genau so wars gedacht, aber etwas sparsam geschrieben (auch wegen der mangelnden Informationen).

Grüße Uwe

Hallo Uwe,

ich habe den Code mal etwas mehr beschrieben, aber nicht böse sein wenn`s
jetzt mehr ist:

// Einbindung der LIBs
#include <EtherCard.h>
#include <SPI.h>
#include <SD.h>

// Einstellung der festen IP-Adresse des WAN
static byte mymac[] = { 0x74,0x62,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,178,91 };
static byte gwip[] = { 192,168,178,1 };
byte Ethernet::buffer[700];

// URL der Webseite des Loggers
char website[] PROGMEM = "strom.ainetz.de";

// Zeitformat festlegen
static uint32_t timer;

// Impuls Variablen
int impState = 0;
int lastimpState = 0;
int impCounter = 0;

//SD Card PINs
int CS_pin = 10;
int pow_pin = 4;

// Antwortet wenn der Client angemeldet ist
static void my_callback (byte status, word off, word len) {
  Ethernet::buffer[off+300] = 0;
  String stringOne = ((const char*) Ethernet::buffer + off);
  }

void setup () {
  // Signalgeber (Schalter etc.)
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);

  Serial.begin(9600);
  Serial.println("\n[IP Setup]");
  // Prüft ob Ethernet verfügbar
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
  Serial.println( "Failed to access Ethernet controller");
  // Übergebe IP und Standart Gateway
  ether.staticSetup(myip, gwip);
  // Wartet auf Gateway Antwort
  while (ether.clientWaitingGw())
    ether.packetLoop(ether.packetReceive());
  Serial.println("Gateway found");
  // Wenn Gateway keine Antwort gibt, Sensorpin 2 abschalten
  if (!ether.dnsLookup(website))
      digitalWrite(2, LOW); 
  // Ausgabe der IP des Zielservers
  ether.printIp("SRV: ", ether.hisip);
  
  // SD Prüfen
  Serial.begin(9600);  // Vielleicht zuviel
  Serial.println("Initialisiere SD-Karte");
  // Schaltet den PIN des SD Shield ein
  pinMode(CS_pin, OUTPUT);
  pinMode(pow_pin,OUTPUT);
  digitalWrite(pow_pin,HIGH);
  // Kartecheck 
  if (!SD.begin(CS_pin)) {
  Serial.println("Kartenfehler");
  return;
  }
  Serial.println("Karte bereit");
}

void loop () {
  // Hier ???
  ether.packetLoop(ether.packetReceive());

  // Lesen der Signale an PIN 2
  impState = digitalRead(2);
  // Hier soll geprüft werden ob die Signale kommen und gewartet werden
  if (impState != lastimpState) {
    if (impState == LOW) {
      impCounter++;
      delay(20);
    }
  }
  // Letzter Status wird gesetzt
  lastimpState = impState;  
  
  if (millis() > timer) {
    timer = millis() + 60000;

// Variable für den Server definieren
char myIntAsString[3300]; 

// Zahl in String umwandeln
itoa(impCounter, myIntAsString, 10);

// PHP-Datei, Client Key, Impulse
ether.browseUrl(PSTR("/logger.php?client=4849&impulse="), myIntAsString, website, my_callback);

// Variable füllen
String dataString = myIntAsString;
// Log-Datei schreiben oder Fehler
  File dataFile = SD.open("log.txt",FILE_WRITE);
  if (dataFile)
  {
    dataFile.println(dataString);
    dataFile.close();
    Serial.println(dataString + " geschrieben");
  }
  else
  {
  Serial.println("kein Datenzugriff");
  }
  // Counter zurücksetzen
  impCounter = 0;
  }
}

Und wo muss ich jetzt den SPI ansprechen bzw. definieren oder Steuern?

Mfg

SvenA

SvenA:
#include <EtherCard.h>

Au Backe!

Es ist mir völlig schleierhaft, wie man daran auch nur einen Gedanken verschwenden kann, Dein Vorhaben mit dem ENC28j60 Chip realisieren zu wollen statt mit dem offiziell von Arduino unterstützten Ethernet-Shield, wenn man nicht der absolute Netzwerk-Programmierprofi ist.

Benutze statt des ENC28j60 ein Ethernet-Shield mit W5100 Chip und die Ethernet-Library!

SvenA:
Und wo muss ich jetzt den SPI ansprechen bzw. definieren oder Steuern?

In Kombination genau so wie stand-alone.
Nur eben darf nur ein einziges Gerät zur Zeit ausgewählt sein, wenn Du mehrere SPI-Geräte zur selben Zeit angeschlossen hast. Bei Deinem Chip über den CS (“Chip Select”) Anschluss (wenn Du ein Breadboard mit ENC28j60 statt ein Shield hast).

Hallo jurs,

ich habe auch einen W5100 Shield aber der ist für mein Vorhaben einfach mal zu groß ich muss in ein Chassis mit 6 cm länge rein.

Mfg

SvenA

Die W5100 Shields gibt es auch kleiner.
zB http://www.cooking-hacks.com/index.php/wiznet-w5100-network-module-with-mag-jack-wiz811mj.html
http://yourduino.com/sunshop2/index.php?l=product_detail&p=243
Grüße Uwe

danke Uwe,

ich habe mir mal das UNO Board angeschaut, da könnte ich auch mit klar kommen. muss ich zwar in ein etwas größeres Chassis aber ich habe mir mal eben das bei "Your Durino" bestellt, da hab ich schon öfter bestellt.

Mfg SvenA

PS: Script setze ich mal nochmal neu auf, wenn das Zeug hier ist.