Arduino UNO Rev 4 Minima with Arduino 4 relay shield module problems

I will apologize if this post is not in the correct forum channel as this is my first post.

Here's what the overall goal I am attempting to achieve: I have a new workstation built from scratch that has a stand up desk portion which I have built. I have also placed three addressable LED strips around each part of the workstation. Now I'm getting a microcontroller and associated parts to make the stand up desk work with LEDs blinging away.

An Arduino UNO does not have the memory capacity for it to work. I tried an ESP32 and Arduino Mega, but burned out the power chip and ISC portion for those boards. :cry:

My major problem is that, most of the time, whenever the command is given for up or down it causes a overprotection of the power supply and resets it, which also causes the microcontroller to reset. Some of the times, the stop command also causes the overprotection to engage. Of course while resetting, the last command is still on the relay and still provides power to the actuator. This is a major stressor since I do not want the table to reach the highest point of the actuator (the table top is made of 2 1/2 inch [3.5cm] of hardwood with three monitors.

Here is the code which I am now using:

// libraries to be included into this project
#include <Wire.h>
// #include <Adafruit_MPU6050.h>
// #include <MPU6050.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include <Adafruit_Sensor.h>

// MPU-6050 module object
MPU6050 mpu;

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
#define OUTPUT_READABLE_YAWPITCHROLL

uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion qq;           // [w, x, y, z]         quaternion container // had to change variable since it confilicts with FastLED
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// Pin assignments for relays controlling linear actuators
// according to Arduino.cc these are the following pinouts of the relay module:
// Relay 1 = Arduino pin 4, Relay 2 = Arduino pin 7, Relay 3 = Arduino pin 8, Relay 4 = Arduino pin 12.
const int relay1Pin = 4;   // Relay controlling actuator #1 positive
const int relay2Pin = 7;   // Relay controlling actuator #1 negative
const int relay3Pin = 8;   // Relay controlling actuator #2 positive
const int relay4Pin = 12;  // Relay controlling actuator #2 negative

// Threshold values for detecting motion
const int threshold = 5; // Adjust this value according to your needs

// Variables to store sensor data
int16_t accelerometerX, accelerometerY, accelerometerZ;
int16_t gyroX, gyroY, gyroZ;

// Variables to store current and previous position
int currentPosition = 0;
int previousPosition = 0;

// Variables to control linear actuator movement
bool isMovingUp = false;
bool isMovingDown = false;

// Variable to indicate if the table is level
bool isTableLevel = false;

void setup() {
  delay(1000); // delay for powering up
  // Initialize serial communication
  Serial.begin(115200);

  // Initialize MPU-6050
  Wire.begin();
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  pinMode(INTERRUPT_PIN, INPUT);

  // verify MPU 6050 connection
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  
  // Calibrate MPU6050
  mpu.CalibrateGyro();
  Serial.println("Gyro calibrated");

  // Set relay pins as outputs
  pinMode(relay1Pin, OUTPUT);
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);

  // Set initial relay states (HIGH to deactivate all relays)
  digitalWrite(relay1Pin, HIGH);
  digitalWrite(relay2Pin, HIGH);
  digitalWrite(relay3Pin, HIGH);
  digitalWrite(relay4Pin, HIGH);

  // printout the commands list once
  Serial.println(F("\nSend 'U' for Up, 'D' for Down, 'S' for STOP"));

 // Wait for serial connection
  while (!Serial) {
    delay(10);
  }
} // end setup function

void loop() {
  // Read accelerometer and gyro data from MPU-6050
  mpu.getMotion6(&accelerometerX, &accelerometerY, &accelerometerZ, &gyroX, &gyroY, &gyroZ);
  // Print gyro values
  Serial.print("GyroX: ");
  Serial.print(gyroX);
  Serial.print("\tGyroY: ");
  Serial.print(gyroY);
  Serial.print("\tGyroZ: ");
  Serial.println(gyroZ);
  delay(100);

  // Calculate the absolute values of accelerometer data
  int absoluteX = abs(accelerometerX);
  int absoluteY = abs(accelerometerY);
  int absoluteZ = abs(accelerometerZ);

  // Determine the position based on accelerometer data
  int newPosition = currentPosition;

  if (absoluteX > threshold) {
    // Tilt detected along the X-axis (front or back)
    if (accelerometerX < 0) {
      // Tilted forward, move the table down
      newPosition--;
    } else {
      // Tilted backward, move the table up
      newPosition++;
    }
  } // end if (absoluteX > threshold)

  if (absoluteY > threshold) {
    // Tilt detected along the Y-axis (left or right)
    if (accelerometerY < 0) {
      // Tilted to the left, move the table down
      newPosition--;
    } else {
      // Tilted to the right, move the table up
      newPosition++;
    }
  } // end if (absoluteY > threshold)

  // Update the position only if it has changed
  if (newPosition != currentPosition) {
    // Stop the previous movement
    stopMovement(); // call function stopMovement
    // Update the current position
    currentPosition = newPosition;
    // Move the table to the new position
    if (currentPosition > previousPosition) {
      // Move the table up
      moveUp(); // call function moveUp
    } else if (currentPosition < previousPosition) {
      // Move the table down
      moveDown();
    } // end if (currentPosition > previousPosition)
    // Update the previous position
    previousPosition = currentPosition;
  } // end if (newPosition != currentPosition)

  // Check if the table is level
  if (absoluteX <= threshold && absoluteY <= threshold) {
    isTableLevel = true;
  } else {
    isTableLevel = false;
  } // end if (absoluteX <= threshold && absoluteY <= threshold)

  // Check if a command is available from the Serial Monitor
  if (Serial.available()) {
    char command = Serial.read();

    // Consume any additional characters from the Serial buffer
    while (Serial.available()) {
      Serial.read();
    }

    // Debug output to display the received command
    Serial.print(F("Received Command: "));
    Serial.println(command);

    // Process the command
    switch (command) {
      case 'U':
        Serial.println(F("Moving Up"));
        moveUp();
        break;
      case 'D':
        Serial.println(F("Moving Down"));
        moveDown();
        break;
      case 'S':
        Serial.println(F("Stopping Movement"));
        stopMovement();
        break;
      default:
        Serial.println(F("Invalid Command"));
        break;
    } // end switch
  } // end if (Serial.available())

  while (!Serial.available());                 // wait for data

  #ifdef OUTPUT_READABLE_YAWPITCHROLL
      // display Euler angles in degrees
      mpu.dmpGetQuaternion(&qq, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &qq);
      mpu.dmpGetYawPitchRoll(ypr, &qq, &gravity);
      Serial.print("ypr\t");
      Serial.print(ypr[0] * 180/M_PI);
      Serial.print("\t");
      Serial.print(ypr[1] * 180/M_PI);
      Serial.print("\t");
      Serial.println(ypr[2] * 180/M_PI);
      delay(100);
  #endif

  // Delay between sensor readings
  delay(100);
} // end loop function

void moveUp() {
   // Activate the relay controlling actuator #1 positive
  digitalWrite(relay1Pin, LOW);
  // Activate the relay controlling actuator #1 negative
  digitalWrite(relay3Pin, LOW);
  // Set the movement flags
  isMovingUp = true;
  isMovingDown = false;
} // end moveUp function

void moveDown() {
  // Activate the relay controlling actuator #2 positive
  digitalWrite(relay2Pin, LOW);
  // Activate the relay controlling actuator #2 negative
  digitalWrite(relay4Pin, LOW);

  // Set the movement flags
  isMovingUp = false;
  isMovingDown = true;
} // end moveDown function

void stopMovement() {
  // Deactivate all relays
  digitalWrite(relay1Pin, HIGH);
  digitalWrite(relay2Pin, HIGH);
  digitalWrite(relay3Pin, HIGH);
  digitalWrite(relay4Pin, HIGH);

  // Clear the movement flags
  isMovingUp = false;
  isMovingDown = false;
} // end stopMovement function

// END PROGRAM

Here is a pic of my wiring diagram:

Here is another problem which causes more stress and caused me to enter this topic.
When uploaded, I am getting all four LEDS to illuminate to start with. If I connect a normal 4-relay module, I do not get any LEDs to light up at the start (which is the proper setting).
If I enter the command up or down, then it will show the proper LEDs. but as soon as I put the command to stop, then all LEDs light up.
With all LEDs lit, it causes my ground wires from the relay terminal to the power supply to burn up!!
Do I have a faulty Arduino relay shield??

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