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. ![]()
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??
