The bot is kept balanced through the correction provided by the wheels which goes against the direction of fall. The current orientation of the bot is monitored by the MPU6050. The orientation is constantly compared to a desired orientation through a PID loop. The bot is steady when the loop output is zero (the current orientation is equal to the desired orientation).

I used Jeff Rowberg's MPU6050 library and modified the MPU6050_DMP6.ino file provided in his Github page. For PID, I used the PID_V1 library by Brett Beauregard. The motor control using the L298N driver is made easy using the LMotorController library.