ESP32 board with HX711, OLED display, HZ 8563 rtc, DHT11, touch sensor and 4 servos

So the problem im encountering is that when i touch the touch sensor to move the servos, OLED display resets, by resets i mean it blacks out and then turns back on.
Heres the code, pls help

#include <I2C_BM8563.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <HX711.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

#define SENSOR_PIN 16
int lastState = LOW;
int currentState;

int servoPin1 = 12;
int servoPin2 = 14;
int servoPin3 = 27;
int servoPin4 = 32;

unsigned long servoMoveTime = 0;

#define BM8563_I2C_SDA 21
#define BM8563_I2C_SCL 22

#define SCREEN_WIDTH 128 // Width of OLED display
#define SCREEN_HEIGHT 64 // Height of OLED display

// 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);

unsigned long previousMillis = 0;  // stores the last time the display was updated

// Declaration for load cell pins
const int LOADCELL_DOUT_PIN = 25;
const int LOADCELL_SCK_PIN = 26;

HX711 scale;
// Calibration factor
#define CALIBRATION_FACTOR 22378.1 // Calibration factor to ensure accurate weighing

// Variables for temperature and humidity
float t;
float h;

#define DHTPIN 19     // Digital pin connected to the DHT sensor
#define DHTTYPE    DHT11

I2C_BM8563 rtc(I2C_BM8563_DEFAULT_ADDRESS, Wire1);

DHT dht(DHTPIN, DHTTYPE);

bool servosMoving = false;
unsigned long servoEndTime = 0;

void setup() {
  delay(50);
  pinMode(SENSOR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), sensorStateChanged, CHANGE);
  currentState = digitalRead(SENSOR_PIN);
  servo1.attach(servoPin1);
  servo2.attach(servoPin2);
  servo3.attach(servoPin3);
  servo4.attach(servoPin4);
  resetServos();
  Wire.begin();
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(CALIBRATION_FACTOR);
  scale.tare();
  Serial.begin(115200);
  Wire1.begin(BM8563_I2C_SDA, BM8563_I2C_SCL);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Start OLED display
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.display();

  dht.begin();
  rtc.begin(); // Start RTC (SDA - 12, SCL - 14)
}

void loop() {
  if (servosMoving) {
    if (millis() >= servoEndTime) {
      resetServos();
      servosMoving = false; // Reset the servosMoving flag
    }
  }

  // Update the display
  updateDisplay();

  I2C_BM8563_DateTypeDef dateStruct;
  rtc.getDate(&dateStruct);
}

void updateDisplay() {
  // Check if it's time to update the display
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 1000) { // Update the display every 1000 milliseconds
    previousMillis = currentMillis;

    display.clearDisplay();
    // Set RTC
    I2C_BM8563_DateTypeDef dateStruct;
    I2C_BM8563_TimeTypeDef timeStruct;
    rtc.getDate(&dateStruct);
    rtc.getTime(&timeStruct);

    float weight = scale.get_units(5); // Read the weight
    t = dht.readTemperature(); // Read temperature
    h = dht.readHumidity(); // Read humidity

    display.setCursor(0, 0);
    display.printf("%02d/%02d/%02d %02d:%02d:%02d\n", // Format for displaying date and time (16/3/2023 9:00:30)
                   dateStruct.date,
                   dateStruct.month,
                   dateStruct.year,
                   timeStruct.hours,
                   timeStruct.minutes,
                   timeStruct.seconds);
    display.setCursor(0, 10);
    display.println("Temp: " + String(t) + " C");
    display.setCursor(0, 20);
    display.println("Hum: " + String(h) + " %");
    display.setCursor(0, 30);
    display.println("Weight: ");
    display.setCursor(0, 40);
    display.setTextSize(2);
    display.println(String(weight) + " kg");
    display.setTextSize(1);
    display.display();
  }
}

void sensorStateChanged() {
  currentState = digitalRead(SENSOR_PIN);

  if (lastState == LOW && currentState == HIGH && !servosMoving) {
    moveServos(0, 90); // Move servos to 90 degrees
    servosMoving = true; // Set the servosMoving flag
    servoEndTime = millis() + 5000; // Calculate the time when the servos should stop moving
  }

  lastState = currentState;
}

void moveServos(int startPos, int endPos) {
  int increment = (endPos > startPos) ? 1 : -1; // Determine the increment value

  for (int i = startPos; i != endPos + increment; i += increment) {
    servo1.write(i);
    servo2.write(i);
    servo3.write(i);
    servo4.write(i);
    delay(15);
  }
}

void resetServos() {
  moveServos(90, 0); // Move servos back to 0 degrees
}

I think it is that blue wire close that purple thing. Post an annotated schematic showing exactly how you wired it, include all connections, grounds, power supplies, etc. Also post links to technical information on each of the parts/modules you are using. There are many different versions of just about everything you listed.

Add a line to setup() like this:

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Start OLED display
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("*** setup() ***"); // <--- add this line here
  display.display();

Ok, so now I know that pressing on the touch sensor resets the whole display because after I touch it setup appears, so how do i fix that so it doesnt reset the whole code

I thought that might be the problem, hence my suggestion.

Servos, like all motors, pumps etc, will draw a large current for a fraction of a second when they start moving. This will typically be around 5x their normal current. My guess would be that because you are starting up 4 servos simultaneously, your power supply arrangements cannot cope with the sudden demand. As a result, the voltage drops significantly and that causes the esp to reset.

But I am using an external power supply for servos, so it shouldnt make a problem or am i wrong?

Something is causing a problem.

Try disconnecting the servos. If you are right and there is a code problem, disconnecting the servos should make no difference.

Yea, it is working normally when i disconnect servos, but that doesnt make sense to me because im using a seperate power supply

Your code crashed on Wokwi, so I re-organized instantiate and begin statements ...

So it's probably a hardware problem, probably not software. Back to post #2

But i dont get it why is that happening when i have a 24V power supply

probably both.

Software:

  1. Using a depreciated constructor ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

From here ...

  // DEPRECATED CONSTRUCTORS - for back compatibility, avoid in new projects
  Adafruit_SSD1306(int8_t mosi_pin, int8_t sclk_pin, int8_t dc_pin,
                   int8_t rst_pin, int8_t cs_pin);
  Adafruit_SSD1306(int8_t dc_pin, int8_t rst_pin, int8_t cs_pin);
  Adafruit_SSD1306(int8_t rst_pin = -1);

  1. Haven't installed nor using the required unified library for the DHT sensor. Check this tutorial.

  2. Suggest making these global as per examples ...

    I2C_BM8563_DateTypeDef dateStruct;
    I2C_BM8563_TimeTypeDef timeStruct;

No, and neither do we, because we have nothing to go on.... yet.....

DHT sensor works fine, as for 3rd point, what do you mean making it global? I am kinda new to this.

Those typedef declarations can be found within several of your functions. I would suggest removing them from those functions and declare them just once above the setup() function.

However, I think the main issue is the first point...

The depreciated constructor's last parameter is OLED_RESET

I would use a newer constructor (see their examples).

Note: I haven't used this library.

Depreciated constructors arent the problem

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.