[Erledigt] Konflikt zwischen Ethernet-Shield und I²C-Display

Hallo,

ich benötige nochmals Eure Hilfe!
Mir ist es nun gelungen, dass ich nun jede Sekunde messe und aus diesen Werten ein 5Min-Mittel bilde. Meine "Menü-Steuerung" mit Encoder funktioniert auch prima. Das Ethernet-Shield arbeitet auch ganz gut. Nur leider funktioniert nicht alles zusammen.... Dazu aber gleich mehr!

Meine Hardware:

Folgende Libary nutze ich für das Display (die Änderungen, wie unten beschrieben, habe ich getätigt): http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/

Das Senden der Daten alle 5min an meinen Webserver funktioniert mit diesem Code einwandfrei. Wie man sehen kann, ist alles Notwendige für das LCD-Display auskommentiert – deshalb auch keine Ausgabe am Display:

(Ein paar unwichtige Zeilen habe ich entfernt!)

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
 
RTC_Millis rtc;
//LiquidCrystal_I2C lcd (0x27, 16, 2);
byte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED};
char server[] = "www.meinserver.de";
IPAddress ip(192,168,2,100);
EthernetClient client;
long avgCount = 0;
int oldSecond = -5;
int counter = 0;
int Anzahl_Sensoren = 16;
volatile int n,m;

void setup () {
    Serial.begin(9600);
    rtc.begin(DateTime(__DATE__, __TIME__));
    //lcd.init();
    Ethernet.begin(mac, ip);
    
    // Set sensor pins
    pinMode(2, INPUT);
    attachInterrupt(0, count, RISING);
    pinMode(7, OUTPUT);
    pinMode(5, INPUT);
    delay(1000);
}

void loop () {
    
    // ******* clock ds1307 *******
    DateTime now = rtc.now();
    int hour = now.hour();
    int minute = now.minute();
    int second = now.second();
    
    
    // ******* sensor configuration *******
    // ANALOG
    String channel_1 = "AIN1";
    String sensor_1 = "---";
 
    String channel_2 = "AIN2";
    String sensor_2 = "---";
   
    // DIGITAL
    String channel_11 = "D1";
    String sensor_11 = "---";
  
    String channel_12 = "D2";
    String sensor_12 = "Windge";
  
    String channel_13 = "D3";
    String sensor_13 = "---";
  
    String channel_14 = "D4"; 
    String sensor_14 = "---";
  
    String channel_15 = "D5";
    String sensor_15 = "Schnee";
 
 
    //  ******* measure routine *******
    if (oldSecond != second){
    // Windspeed
    m=n; 
    current_13 = 0.04783446 * m + 0.15649663; 
    if (current_13 < 0.16){ 
      current_13 = 0;
    }
    n=0;
  
    // Snowheight
    digitalWrite(7, LOW);                   
    delayMicroseconds(2);
    digitalWrite(7, HIGH);          
    delayMicroseconds(10);                    
    digitalWrite(7, LOW); 
    current_16 = ((pulseIn(5, HIGH) / 2.9) / 2);
  
    // calculate average
    avgCount++;
    average_1 = (current_1 + average_1 * avgCount) / (avgCount + 1);
    average_13 = (current_13 + average_13 * avgCount) / (avgCount + 1);
    average_16 = (current_16 + average_16 * avgCount) / (avgCount + 1);
    Serial.print(avgCount);
    Serial.print("  ");
    Serial.print(minute);
    Serial.print(":");
    Serial.println(second);
    
    oldSecond = second;
    }  
    // ******* webclient to send data to the webserver *******
    if (avgCount >= 301 || minute == 0 || minute == 5 || minute == 10 || minute == 15 || minute == 20 || minute == 25 || minute == 30 || minute == 35 || minute == 40 || minute == 45 || minute == 50 || minute == 55){
     if (second == 0){
      if (client.connect(server, 80)){
        Serial.println("connected");
        client.print("GET /pushDataInMySQL.php?");
        client.print("Windge=");
        client.print(average[12]);
        client.print("&Schnee=");
        client.print(average[15]);
        client.println("&id=************** HTTP/1.1");
        client.println("Host: www.meinserver.de");
        client.println("Connection: close");
        client.println();
        client.stop();
        delay(100);
      }
      avgCount = 0;
      // set average to current
      average_1 = current_1;
      average_13 = current_13;
      average_16 = current_16;
     }
    }
    
    // ******* display something on the lcd ******* 
    /*lcd.setCursor(0, 0);
    if (hour <= 9) { lcd.print("0"); }
    lcd.print(hour);
    lcd.print(":");
    if (minute <= 9) { lcd.print("0"); }
    lcd.print(minute);*/  
}
void count()
{
    n++;
}

Wenn nun alles Notwendige für das Display nicht mehr auskommentiert ist bleibt das Programm nachdem Senden von den Daten einfach stehen. Heißt es erfolgt keine Ausgabe am Serialmonitor (siehe Bild) mehr und die Uhrzeit am Display aktualisiert sich nicht mehr. Mit einem anderen Sketch ist es auch schon vorgekommen, dass er nach dem Senden einfach einen Reset gemacht hatte. Nun bin ich aber mit meinem Latein am Ende, mit meinem bisschen Spanisch jetzt auch. :wink:

Im Internet gibt’s aber haufenweiße Leute, bei denen genau diese Konstellation zwischen Ethernet-Shield und I²C-Display sehr gut funktioniert.

Ausgabe(n) am Serialmonitor:

Danke schonmal für Eure Hilfe!!
webworker

PS: Am Sktech muss noch viel verbessert werden!

Das Problem wird der I2C Bus sein, den dein Dataloggin Shield sowie dein Display nutzen dies. Kann mir vorstellen, dass dir die ~4,7k Widerstände zwischen VCC und SDA /SCL fehlen.

Hallo,

danke für Deine schnelle Antwort.
Nein, die Pull-Ups sind vorhanden. Aber am Display und an der RTC.
Da ich aber ja die aktuelle Uhrzeit am Display ausgeben kann, denke ich, dass das
nicht das Problem sein wird. Ich werde aber nach mal die Pull-Ups an einem Gerät rausnehmen.

webworker

Ich tippe auf RAM overflow. Du benutzt zuviel RAM einerseits durch die Benutztung von Strings und anderseits durch die Nichtbenutztung von F() makro in allen .print von Texten.
statt:
Serial.println("connected");
solltest Du
Serial.println(F("connected"));
versuchen.

Alternativ zur Kontrolle könntest Du auch falls vorhanden mit einem Arduino MEGA versuchen.

Grüße Uwe

Du könntest du dir deinen Ram Verbrauch auch anzeigen lassen.
http://playground.arduino.cc/Code/AvailableMemory

Erst mal ohne LCD Funktionen laufen lassen um zu sehen wieviel du schon verbaucht hast.

Ist zwar nicht das Kernproblem, aber das hier :

 if (avgCount >= 301 || minute == 0 || minute == 5 || minute == 10 || minute == 15 || minute == 20 || minute == 25 || minute == 30 || minute == 35 || minute == 40 || minute == 45 || minute == 50 || minute == 55)

Geht einfacher so, wenn ich mich nicht irre,

 if (avgCount >= 301 || minute % 5 == 0)

Hallo,

jetzt funktioniert das Ganze so, wie ich es mir vorgestellt hatte.
Ich habe einfach die vielen Strings rausgeschmissen, die unnötig lange If-Abfrage umgebaut und die Ausgaben mit dem Makro F() versehen.

if (minute % 5 == 0)

Macht ja nichts anderes als teilt die Minuten durch 5 und schaut ob es einen Restwert gibt? Wenn es einen Restwert gibt kommt dir Zahl nicht aus der 5er-Reihe.

Ich möchte mich nochmals für Eure super und schnelle Hilfe bedanken!!

webworker

Bitte