Oled 0,96 will nicht mehr, wenn ich eine random funktion verwende

Moin Leute,
ehrlich gesagt ist der Titel sehr irreführend, aber ich werde es erklären. Ich baue derzeit eine Bewässerungsanlage mit Hx711 scale cells. Dass mehrere HX711 probleme machen ist ja bekannt. Ich hatte gehofft, dass eine Kalibrierung der Waagen bei kompletter Last es mir erlaubt die Störspannunen rauszufiltern (falls diese für falsche werte verantwortlich sind, da ich alle drei hx711 ein 0,96 oled und ein dht21 über ein 5V Netzteil betreibe) und somit auch wenn alle drei gleichzeitig in betrieb sind richtige werte rauskommen.

Ich hatte bereits alle waagen seperat kalibriert, aber als ich dann den Rest vom Setup mit eingebracht habe, sind die Werte in den Bach gefalllen.

Alsoooo habe ich eine Funktion geschrieben, die mir bei jedem Neustart die Kalibrierung der Waagen hintereinander ausführen lässt.

Ich wüsste nicht wieso, aber wenn ich jetzt diese Funktion ausführen möchte in meiner void setup, dann wird mein Oled display aufeinmal nicht mehr erkannt und es kann nichts ausgeben.

klammer ich jedoch die Funktion wie sie ausgeführt wird aus, dann wird das Display wieder erkannt. Was übersehe ich?

Danke Leute! Freue mich schon auf Input. slight_smile:

Folgender Code:

#include "DHT.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include "HX711.h"

HX711 scale1;
HX711 scale2;
HX711 scale3;
const uint8_t dataPin1 = 5;
const uint8_t clockPin1 = 6;
const uint8_t dataPin2 = 11;
const uint8_t clockPin2 = 12;
const uint8_t dataPin3 = 9;
const uint8_t clockPin3 = 10;

const uint8_t DHTPIN = A0;
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const uint8_t PinPump1 = 2;
const uint8_t PinPump2 = 3;
const uint8_t PinPump3 = 4;

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed")); //Fehlermeldung die ich bekomme. 
    for (;;);
  }
  
  delay(2000);
  
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  pinMode(PinPump1, OUTPUT); 
  pinMode(PinPump2, OUTPUT); 
  pinMode(PinPump3, OUTPUT);                                      
  digitalWrite(PinPump1, HIGH);
  digitalWrite(PinPump2, HIGH);
  digitalWrite(PinPump3, HIGH);
  
  dht.begin();
  scale1.begin(dataPin1, clockPin1);
  scale2.begin(dataPin2, clockPin2);
  scale3.begin(dataPin3, clockPin3);

  display.setCursor(0, 20);
  display.println("Booting shit... dont put shit on!");
  display.display();
  delay(2000);
  display.clearDisplay();


// Die drei calibration funktion sind für den "Absturz" verantwortlich
// klammer ich diese jedoch aus dann wird das Display wieder erkannt



  calibration(scale1, 1);
  calibration(scale2, 2);
  calibration(scale3, 3);
}

// calibration ist die problematische Funktion 


void calibration(HX711& scale, int scaleNumber) {
  const float KNOWN_WEIGHT_GRAMS = 1000.0;  // 1kg calibration weight
  long sum = 0;
  int readings = 10;
  
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Calibrating #");
  display.println(scaleNumber);

  // First tare the scale
  display.println("Remove all weight");
  display.println("and wait...");
  display.display();
  delay(5000);

  scale.set_scale();  // Reset scale factor
  scale.tare();       // Reset to zero

  display.clearDisplay();
  display.println("Place 1kg weight");
  display.println("carefully...");
  display.display();
  
  delay(5000);
  
  display.clearDisplay();
  display.println("Reading...");
  display.println("Don't touch!");
  display.display();
  
  // Take multiple readings for stability
  for (int i = 0; i < readings; i++) {
    sum += scale.get_value();
    delay(200);
  }

  float rawAverage = sum / (float)readings;
  float scaleFactor = rawAverage / KNOWN_WEIGHT_GRAMS;  // Calculate units per gram

  scale.set_scale(scaleFactor);

  // Verify calibration
  float verifyWeight = scale.get_units(5);

  display.clearDisplay();
  display.print("Scale #");
  display.println(scaleNumber);
  display.print("Factor: ");
  display.println(scaleFactor);
  display.print("Test: ");
  display.print(verifyWeight);
  display.println("g");
  display.display();
  delay(3000);
}

void loop() {
  display.clearDisplay();

  int w1 = scale1.is_ready() ? scale1.get_units(10) : -1;
  delay(100);
  int w2 = scale2.is_ready() ? scale2.get_units(10) : -1;
  delay(100);
  int w3 = scale3.is_ready() ? scale3.get_units(10) : -1;

  // Temperature and Humidity Display
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    display.setCursor(0, 0);
    display.setTextSize(1);
    display.println(F("Failed to read DHT!"));
    display.display();
    delay(2000);
    return;
  }

  // First Screen: Temperature and Humidity
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0, 10);
  display.print(t, 1); // Show one decimal place
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h, 1); // Show one decimal place
  display.print("%");
  display.display();
  delay(3000);

  // Second Screen: Plant Weights
  display.clearDisplay();
  display.setTextSize(1);

  // Plant 1
  display.setCursor(0, 0);
  display.print("Plant 1: ");
  display.print(w1);
  display.println("g");

  // Plant 2
  display.setCursor(0, 20);
  display.print("Plant 2: ");
  display.print(w2);
  display.println("g");

  // Plant 3
  display.setCursor(0, 40);
  display.print("Plant 3: ");
  display.print(w3);
  display.println("g");
  display.display();
  delay(2000);

  // In the pump sections, ensure all display updates are followed by display.display():
  if (w1 > 4000) {
    // Do nothing
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds

    while (w1 < 1) {
      display.setCursor(0, 10);
      display.print("Pumpe 1 läuft...");
      display.display();  // Make sure this is present
      digitalWrite(PinPump1, LOW); // Turn on pump
      delay(2000);
      w1 = scale1.get_value(10);
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump1, HIGH); // Turn off pump
  }
  display.clearDisplay();
  if (w2 > 1) {
    // Do nothing, don't turn on the pump
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds
    while (w2 < 7000) {
      display.setCursor(0, 10);
      display.print("Pumpe 2 läuft...");
      display.display(); // Loop until weight reaches 7000
      digitalWrite(PinPump2, LOW); // Turn on pump
      delay(2000);
      w2 = scale2.get_value();
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump2, HIGH); // Turn off pump
  }
  display.clearDisplay();
  if (w3 > 1) {
    // Do nothing, don't turn on the pump
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds
    while (w3 < 7000) {
      display.setCursor(0, 10);
      display.print("Pumpe 3 läuft...");
      display.display(); // Loop until weight reaches 7000
      digitalWrite(PinPump3, LOW); // Turn on pump
      delay(2000);
      w3 = scale3.get_value();
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump3, HIGH); // Turn off pump
  }
  display.clearDisplay();
}

Versuche es mal so:

#include "DHT.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include "HX711.h"

HX711 scale1;
HX711 scale2;
HX711 scale3;
const uint8_t dataPin1 = 5;
const uint8_t clockPin1 = 6;
const uint8_t dataPin2 = 11;
const uint8_t clockPin2 = 12;
const uint8_t dataPin3 = 9;
const uint8_t clockPin3 = 10;

const uint8_t DHTPIN = A0;
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const uint8_t PinPump1 = 2;
const uint8_t PinPump2 = 3;
const uint8_t PinPump3 = 4;

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  
  delay(2000);
  
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  pinMode(PinPump1, OUTPUT); // (pumpe 9)                                             1 min = 0.2L -> 600000ms = 0.2L -> 30000ms = 0.1L
  pinMode(PinPump2, OUTPUT); // (pumpe 10)                                            1 min = 0.2L
  pinMode(PinPump3, OUTPUT); // (pumpe 11)                                            1 min = 0.2L                                         
  digitalWrite(PinPump1, HIGH);
  digitalWrite(PinPump2, HIGH);
  digitalWrite(PinPump3, HIGH);
  
  dht.begin();
  scale1.begin(dataPin1, clockPin1);
  scale2.begin(dataPin2, clockPin2);
  scale3.begin(dataPin3, clockPin3);

  display.setCursor(0, 20);
  display.println("Booting shit... dont put shit on!");
  display.display();
  delay(2000);
  display.clearDisplay();

  calibration(scale1, 1);
  calibration(scale2, 2);
  calibration(scale3, 3);
}

void calibration(HX711& scale, int scaleNumber) {
  const float KNOWN_WEIGHT_GRAMS = 1000.0;  // 1kg calibration weight
  long sum = 0;
  int readings = 10;
  
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Calibrating #");
  display.println(scaleNumber);

  // First tare the scale
  display.println("Remove all weight");
  display.println("and wait...");
  display.display();
  delay(5000);

  scale.set_scale();  // Reset scale factor
  scale.tare();       // Reset to zero

  display.clearDisplay();
  display.println("Place 1kg weight");
  display.println("carefully...");
  display.display();
  
  delay(5000);
  
  display.clearDisplay();
  display.println("Reading...");
  display.println("Don't touch!");
  display.display();
  
  // Take multiple readings for stability
  for (int i = 0; i < readings; i++) {
    sum += scale.get_value();
    delay(200);
  }

  float rawAverage = sum / (float)readings;
  float scaleFactor = rawAverage / KNOWN_WEIGHT_GRAMS;  // Calculate units per gram

  scale.set_scale(scaleFactor);

  // Verify calibration
  float verifyWeight = scale.get_units(5);

  display.clearDisplay();
  display.print("Scale #");
  display.println(scaleNumber);
  display.print("Factor: ");
  display.println(scaleFactor);
  display.print("Test: ");
  display.print(verifyWeight);
  display.println("g");
  display.display();
  delay(3000);
}

void loop() {
  display.clearDisplay();

  int w1 = scale1.is_ready() ? scale1.get_units(10) : -1;
  delay(100);
  int w2 = scale2.is_ready() ? scale2.get_units(10) : -1;
  delay(100);
  int w3 = scale3.is_ready() ? scale3.get_units(10) : -1;

  // Temperature and Humidity Display
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    display.setCursor(0, 0);
    display.setTextSize(1);
    display.println(F("Failed to read DHT!"));
    display.display();
    delay(2000);
    return;
  }

  // First Screen: Temperature and Humidity
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0, 10);
  display.print(t, 1); // Show one decimal place
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h, 1); // Show one decimal place
  display.print("%");
  display.display();
  delay(3000);

  // Second Screen: Plant Weights
  display.clearDisplay();
  display.setTextSize(1);

  // Plant 1
  display.setCursor(0, 0);
  display.print("Plant 1: ");
  display.print(w1);
  display.println("g");

  // Plant 2
  display.setCursor(0, 20);
  display.print("Plant 2: ");
  display.print(w2);
  display.println("g");

  // Plant 3
  display.setCursor(0, 40);
  display.print("Plant 3: ");
  display.print(w3);
  display.println("g");
  display.display();
  delay(2000);

  // In the pump sections, ensure all display updates are followed by display.display():
  if (w1 > 4000) {
    // Do nothing
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds

    while (w1 < 1) {
      display.setCursor(0, 10);
      display.print("Pumpe 1 läuft...");
      display.display();  // Make sure this is present
      digitalWrite(PinPump1, LOW); // Turn on pump
      delay(2000);
      w1 = scale1.get_value(10);
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump1, HIGH); // Turn off pump
  }
  display.clearDisplay();
  if (w2 > 1) {
    // Do nothing, don't turn on the pump
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds
    while (w2 < 7000) {
      display.setCursor(0, 10);
      display.print("Pumpe 2 läuft...");
      display.display(); // Loop until weight reaches 7000
      digitalWrite(PinPump2, LOW); // Turn on pump
      delay(2000);
      w2 = scale2.get_value();
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump2, HIGH); // Turn off pump
  }
  display.clearDisplay();
  if (w3 > 1) {
    // Do nothing, don't turn on the pump
  } else {
    unsigned long startTime = millis(); // Record the start time
    unsigned long timeout = 3000; // Timeout after 30 seconds
    while (w3 < 7000) {
      display.setCursor(0, 10);
      display.print("Pumpe 3 läuft...");
      display.display(); // Loop until weight reaches 7000
      digitalWrite(PinPump3, LOW); // Turn on pump
      delay(2000);
      w3 = scale3.get_value();
      display.clearDisplay(); // Read new weight after irrigation
      if (millis() - startTime > timeout) {
        display.setCursor(0, 10);
        display.print("Timeout reached! Stopping pump.");
        display.display();
        delay(2000);
        display.clearDisplay();
        break;
      }
    }
    digitalWrite(PinPump3, HIGH); // Turn off pump
  }
  display.clearDisplay();
}

Welchen µC hast du?
Wieviel freien Speicher zeigt er dir an?

Leider immer noch im Serial allocation failed..

Was hast du denn geändert? :slight_smile:

Was genau heißt das?
Wenn es eine Fehlermeldung ist, dann bitte komplett posten.

Weiterhin hast du Fehler in den Kommentaren, die auch irritieren.

kennst du

19:46:46.814 -> SSD1306 allocation failed

Das ist der Fehler im serial monitor, dass das Display nicht erkannt wird.

Die Kommentare sind verwirrend sorry. Ist ein Projekt, was schon länger auf meinem Schreibtisch liegt.

nope , aber sieht interessant aus. :slight_smile:

Dann solltest du das überarbeiten da es so für die Helfer schwer lesbar ist. Auch weil weitere und hilfreiche Kommentare fehlen. Und an welcher Stelle in Code wird der Fehler gezeigt ?

Hast du in den Einstellungen der IDE alle Fehlermeldungen aktiviert ?

Danke ich habe es soweit es geht geändert und noch ein paar Kommentare relativ weit oben eingebracht. :slight_smile:

Habe auch alle Fehlermeldungen jetzt aktiviert, danke. ^^

Ok und was wird jetzt angezeigt ?

Tatsächlich gar nichts, bzw. wo sehe ich denn die Fehlermeldungen? Auch im Output, oder wo anders?

Was genau klammerst du aus?

Wo genau kam denn die Fehlermeldung aus Post #3 her ?

Also wenn der von dir genannte Fehler durch die Funktion "calibration" verursacht wird, dann solltest du dies Funktion Stückchenweise aufbauen oder mit reichlich seriellen Ausgaben versehen, um festzustellen, an welcher Stelle das Problem auftritt.
So kannst du deinen Sketch debuggen.
Zuvor solltest du aber noch die Frage nach Controllertyp und Speicherbelegung von @wwerner beantworten.
Evtl. ist darin ja auch dein Problem versteckt.

Tut mir leid ich hatte deine untere Nachricht gar nicht gesehen. :slight_smile:

Ich glaube ich weiß leider nicht, was du damit meinst, welchen mikro Coloumb ich habe. Falls du einen Kondensator meinst, weiß ich nicht welchen du meinst. ^^

Ich habe 36% freien Speicherplatz noch.

Das ist der Output vom Terminal:

Der Sketch verwendet 20756 Bytes (64%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 917 Bytes (44%) des dynamischen Speichers, 1131 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

 display.println("Booting sqzirrls... dont put stuff on!");
  display.display();
  delay(2000);
  display.clearDisplay();


// Die drei calibration funktion sind für den "Absturz" verantwortlich
// klammer ich diese jedoch aus dann wird das Display wieder erkannt



  calibration(scale1, 1);
  calibration(scale2, 2);
  calibration(scale3, 3);

Ich meinte die drei calibration Funktionen am Ende der void setup Func.

Dass werde ich aufjedenfall tun, danke!

Der Controllertyp ist also ich habe einen Arduino Uno von Kuman.

Schreib mal als zweite Zeile unter Dein Serial.begin(115200):
delay(500);

Hey Leute, also ich habe die calibration func jetzt einmal Befehl für Befehl zerlegt und das Problem rührt aus der Definiton der Variablen:

void calibration(HX711&scale, int scaleNumber) {
...
}

Füge ich das als Funktion ein mit dem Befehl dass er mit

float value = scale.get_value();

sich jedensmal vom Display dann verabschiedet. Selbes gilt sogar, wenn ich gar keine display befehle in der FUnktion selber ausführe wie hier:

oid calibration(HX711&scale, int scaleNumber) {
  const float KNOWN_WEIGHT_GRAMS = 1000.0;  // 1kg calibration weight 
  
  
  // display.setCursor(0, 20);
  Serial.print("Calibrating #");
  Serial.println(scaleNumber);

  // First tare the scale
  Serial.println("Remove all weight");
  Serial.println("and wait...");
  // display.display();
  delay(5000);

  scale.set_scale();  // Reset scale factor
  scale.tare();       // Reset to zero

  // display.clearDisplay();
  Serial.println("Place 1kg weight");
  Serial.println("carefully...");
  // display.display();
  
  delay(5000);
  
  // display.clearDisplay();
  Serial.println("Reading...");
  Serial.println("Don't touch!");
  // display.display();
  
  // Take multiple readings for stability

  float raw = scale.get_value(10);

 
  float scaleFactor = raw / KNOWN_WEIGHT_GRAMS;  // Calculate units per gram

  scale.set_scale(scaleFactor);

  // Verify calibration
  float verifyWeight = scale.get_units(5);

  // display.clearDisplay();
  Serial.print("Scale #");
  Serial.println(scaleNumber);
  Serial.print("Factor: ");
  Serial.println(scaleFactor);
  Serial.print("Test: ");
  Serial.print(verifyWeight);
  Serial.println("g");
  // display.display();
  delay(3000);
}


Guten Morgen Leude,

Also ich habe die calibration func jetzt einmal aufgelöst und in die Setup func hard gecoded. Das Ergebnis ist, dass er sich selbst dann auch noch aufhängt. Also vermute ich einen Speicherfehler, ich probiere jetzt nochmal andere Pins aus und melde mich dann nochmal.

Soo habe es jetzt folgendermaßen gelöst. Es war einfach zu viel für den Zwischenspeicher an Strings und Varibalen. Wusste nicht, dass das was der Compiler anzeigt, was an freien Speicher noch da ist nicht alles ist. Habe es gelöst in dem ich alle hard gecoded display.print Befehle in den Flashdrive geschickt habe. Damit hat dann alles super funktioniert.

Hatte dann noch das Problem dass die Werte der Waagen sehr stark am schwanken waren, aber jetzt ist das auch geklärt, weil ich das Display separat an die 3.3V vom Arduino vernetzt habe und nicht mehr über die selbe Stromversorgung wie die Waagen.

Vielen Dank für eure Hilfe leute! Habe viel gelernt :slight_smile: