Leveling a table with arduino car

I have an idea, I'd like to make a table that could be leveled by a car around one axis. Actually it would be very similar to a balancing robot.
I already build both the table and car but now I am stuck with the leveling part of my project.

I though it is working like the balancing robot, but in my project I should detect when the table started to tilt, because it always starts from 5 or -5 degree, and when the car reaches the deadlock then the table tilts. So the only difference between my project and balancing robot is that in my project the car should move in reverse when the car that balance reaches the deadlock.

My question would be that how could I detect that moment when the car reached the deadlock? I have already tried to compare the last angle with the corrent angle but it has not really worked because my gyroscope gives the angle values very fast.

Here is my code that I wrote already:

#include <Arduino.h>
#include <PID_v1.h>
#include <espnow.h>
#include <ESP8266WiFi.h>
#include <Ticker.h>

#define FORWARD         1                       
#define BACKWARD        2                       
#define STOP            3                       

void motor_stop();
void motor_forward();
void motor_backward();
void print_debuginformation();

double Angle_to_send, Angle; 
int roundedAngle, lastAngle;

boolean run = false; 

//Motor A,L
const int A_motor_PWM = 16;//D0
const int A_motor_forwardpin = 13;//D7
const int A_motor_backwardpin = 15;//D8

//Motor B,R
const int B_motor_PWM = 12;//D6
const int B_motor_forwardpin = 5;//D1
const int B_motor_backwardpin = 0;//D3

int direction;

//ESP-NOW 
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&Angle_to_send, incomingData, sizeof(Angle_to_send));
  //Serial.print("Fogadott "); Serial.println(Angle_to_send);
}

//PID
//double kp =5.3, ki = 0.1, kd = 0.25; //kp=5.3 ki=0.1 kd=0.25 
//PID deltaPWM_PID(&error, &deltaPWM, &desired, kp, ki, kd, DIRECT);
double input_1 = 0, setpoint_1 = 0, output_1 = 0, output;
double kp_1 = 5, ki_1 = 0, kd_1 = 0.5;
PID angle_PID(&input_1, &output_1, &setpoint_1, kp_1, ki_1, kd_1, DIRECT);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA); //ESP-NOW, Wi-Fi Station

  pinMode(A_motor_forwardpin,OUTPUT);
  pinMode(A_motor_backwardpin,OUTPUT);
  pinMode(A_motor_PWM,OUTPUT);

  pinMode(B_motor_forwardpin,OUTPUT);
  pinMode(B_motor_backwardpin,OUTPUT);
  pinMode(B_motor_PWM,OUTPUT);
  motor_stop();

  //PID
  angle_PID.SetMode(AUTOMATIC);
  angle_PID.SetOutputLimits(480, 800);
  angle_PID.SetSampleTime(10);

  //ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {
  Angle = Angle_to_send;
  roundedAngle = Angle_to_send;

  lastAngle = roundedAngle;

  if(Angle > 0) {Angle *= -1;}
  input_1 = Angle;
  angle_PID.Compute();
  print_debuginformation();

  if(Angle_to_send > -20 && Angle_to_send < 20){

    if(Angle_to_send > 0){
     motor_forward(); 
     direction = FORWARD;

     if (roundedAngle < lastAngle){
     motor_backward(); 
     direction = BACKWARD;
     } 
    }

    else if(Angle_to_send < 0){
     motor_backward(); 
     direction = BACKWARD;

     if (roundedAngle > lastAngle){
     motor_forward(); 
     direction = FORWARD;
     }
    }
    else{
      motor_stop(); 
      direction = STOP;
    }
  }
  else{
    motor_stop(); 
    direction = STOP;
  }
}


void motor_forward(){
   analogWrite(A_motor_PWM, 0.98*output_1);  
   analogWrite(B_motor_PWM, output_1);
   
   digitalWrite(A_motor_forwardpin, HIGH); 
   digitalWrite(A_motor_backwardpin, LOW);
   digitalWrite(B_motor_forwardpin, HIGH);
   digitalWrite(B_motor_backwardpin, LOW);
  
   run = true;
}

void motor_backward(){
   analogWrite(A_motor_PWM, 0.98*output_1); 
   analogWrite(B_motor_PWM, output_1);

   digitalWrite(A_motor_forwardpin, LOW); 
   digitalWrite(A_motor_backwardpin, HIGH);
   digitalWrite(B_motor_forwardpin, LOW);
   digitalWrite(B_motor_backwardpin, HIGH);
  
   run = true;
}

void motor_stop(){
  digitalWrite(A_motor_forwardpin, HIGH);
  digitalWrite(A_motor_backwardpin, HIGH);
  digitalWrite(B_motor_forwardpin, HIGH);
  digitalWrite(B_motor_backwardpin, HIGH);
  digitalWrite(A_motor_PWM, HIGH);
  digitalWrite(B_motor_PWM, HIGH); 

  run = false;
}

void print_debuginformation(){
Serial.print("PIDinput");Serial.print(input_1);Serial.print(" -->");
Serial.print(" PIDoutput: ");Serial.print(output_1);Serial.print("******");
Serial.print(" Fogadott ");Serial.print(Angle_to_send);Serial.print(" Irány: ");Serial.print(direction);
Serial.print(" 1=F 2=B 3=S    ");Serial.print(roundedAngle);Serial.println(lastAngle);
}

Thanks in advance!

sketch.png

I think a picture may be in order. I feel completely confused by your description. How does a car balance a table? What is this deadlock? That word has a meaning but makes no sense in your sentence with that meaning.

Please DO NOT keep starting new threads on the same topic.

Delta_G:
I think a picture may be in order. I feel completely confused by your description. How does a car balance a table? What is this deadlock? That word has a meaning but makes no sense in your sentence with that meaning.

I have posted a quick sketch about it. The red spot is the car on the top of the table that can go forward and backward. When the car is on the left side the gyroscope gives 5deg when on the other gives -5deg.
Deadlock is that position of the car on the table where the table is starting to tilt.

@pestiofficial

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.

Don't use a rate gyroscope. That only tells you how fast you are turning. Use an accelerometer. That will tell you when the beam is level.

Here's the OP's picture:

sketch.png

I've got two questions...

  1. What holds it to 5 degrees? Why is it never 2 degrees? Why is it never more than 5 degrees?

  2. What purpose is the car? Just set it in the middle and the table is balanced. The car wouldn't ever need to move.

No stable equilibrium is possible for the diagrammed gizmo. It is a vertical pendulum with loose parts.

Delta_G:
I've got two questions...

  1. What holds it to 5 degrees? Why is it never 2 degrees? Why is it never more than 5 degrees?

  2. What purpose is the car? Just set it in the middle and the table is balanced. The car wouldn't ever need to move.

  1. Obviously it can be different from 5 and -5 but it cant be more than 5 or less than -5 because it is limited by the ground.

  2. It is a final year school project, I wanted to build an unusual balance robot. The goal of this project would be that if you put the car somewhere on the table then the car could balance that.

Then you have picked quite a challenge!

I'm just going to leave this here...

Very nice idea to use a resistive touch panel to detect the ball location!

jremington:
Very nice idea to use a resistive touch panel to detect the ball location!

I thought so too.

What I want to know is how many hours went into getting the PIDs tuned so perfectly.

Speaking of PID, that's what the OP will need. It's not enough to just detect the tilt and move the other way. That will never work. You have to work out how fast to move and when to start slowing down.

I'd say offhand the mechanical motorised gyros we used to use in model helicopters tail rotor servo(maybe even the newer electronic versions) should be able to handle that.
After all, model chopper stability is like trying to balance a matchstick on ones finger.

jremington:
No stable equilibrium is possible for the diagrammed gizmo. It is a vertical pendulum with loose parts.

Couldn't the OP get dynamic equilibrium using the motion of the car to correct any errors?

Isn't that much same as a self-balancing two-wheeled robot (e.g. a segway)

...R

Of course a dynamic equilibrium is possible.

Delta_G:
You have to work out how fast to move and when to start slowing down.

I realised that this task will be complicated for me. So my plan has changed. What if my robot car starts from around 0 degree and then the car just tries balancing the platform. It sounds me a little bit easier.
If I would use PID regulation the setpoint would be 0 degree. If the platform tilts left the error is positive then go forward. If tilts right the error is negative then go reverse. PID s output would be the PWM signal for motors.
I would like to ask your opinion about it. Would balancing work in this way?

I would set the Output range to +/- 255. Use the sign to set the Direction and the magnitude for PWM.

johnwasser:
I would set the Output range to +/- 255. Use the sign to set the Direction and the magnitude for PWM.

Ok, thanks!
I set it up and tried to make it balancing but I noticed the table is very sensitive so when the car step over/under the 0degree then the table instantly tilts to side. Maybe my car should be very fast...
What do you think, is it ever will be able balancing?

I was thinking about to apply a shock-absorber, but that would be a little bit cheating I guess.