Auto Leveling Quadcopter

Hi.
I made this base to test auto leveling:

I am using NodeMCU as the controller ADXL345 accelerometer to calculate angle and two NPN transistors to control the speed of motors.

This is the code I wrote:

#include <Wire.h>
#include "Adafruit_Sensor.h"
#include "Adafruit_ADXL345_U.h"

#define LEFT_MOTOR_PIN 10
#define RIGHT_MOTOR_PIN 11

double x;

int leftMotorSpeed = 0, rightMotorSpeed = 0;

Adafruit_ADXL345_Unified accel(54321);

void setup()
{
    pinMode(LEFT_MOTOR_PIN, OUTPUT);
	pinMode(RIGHT_MOTOR_PIN, OUTPUT);

    if (!accel.begin())
        while (1);

    accel.setRange(ADXL345_RANGE_16_G);
    accel.setDataRate(ADXL345_DATARATE_25_HZ);
}

void loop()
{
    analogWrite(LEFT_MOTOR_PIN, leftMotorSpeed);
	analogWrite(RIGHT_MOTOR_PIN, rightMotorSpeed);

    sensors_event_t event;
    accel.getEvent(&event);

    x = event.acceleration.x;

    leftMotorSpeed = 255 - map(x, -10, 10, 0, 255);
    rightMotorSpeed = map(x, -10, 10, 0, 255);
}

But there is a problem. When the board starts, it goes down in one side (for example left) and then after touching the ground it reverse it to the other side. (Sorry for bad English :cold_sweat: )

I don’t know how to balance it!!

Have you tried outputting the accelerometer value and the calculated motor speeds to the serial monitor to check that it is sensible? You can do this without the motors connected to start with and just move the frame by hand.

You may want to check what the below code actually returns...

event.acceleration.x;

...because I don't think it's an angle if that's what you wanted.

Have you tested this setup with each motors on its own without input from the accelerometer, e.g. just cycling through some different set speeds? I think usually people use MOSFETs to drive brushed DC motors rather than NPNs - but this is not an area I know much about, I'm just repeating what I've seen elsewhere.

I assume that this

accel.setDataRate(ADXL345_DATARATE_25_HZ);

is the rate that your accelerometer reading is being updated? I'm not sure how well this will work for auto leveling - I suspect that it will not be responsive enough. Can you increase it? Note that the accelerometer output may be quite noisy in which case you'll have to filter it which will delay the response further. The common approach is to use gyroscopes as well since they can give a much quicker and less noisy response. The accelerometer would then be used to correct for gyro drift. You can find a lot of information about this from some googling.

Could be mistaken but probably not a good idea to have sensor board surrounded by a matal frame base.

Gravity passes through metal just fine. If it was a magnetic sensor then that may be an issue.

Be careful with your map math, it can be wonky.