(another..) question about self leveling platform

Hi, I search the Internet, this Forum and others but just can't find a guidance in which direction I best can go. I am going to convert a Van into a Campervan and as I will go and live in it ones ready I want a proper bed in it. Instead of leveling the entire van I want to level the bedframe when I am parked on a slope in any direction possible. I am thinking off:

  1. a platform on three legs, a gyroscope/acc meter/ three motor drivers, or one which can handle three lineair actuators, a suitable arduino board,
  2. with four legs and accordingly 4 motor drivers and so forth as in 1.
  3. Back to 1. but with mercury switches and three legs I suppose. To me this seems the easiest way, I am unsure however if the KY-017 will stay intact considering the vibrations, bumps and what not.

This is the first time I am posting a question, and a beginning beginner.. I placed to examples hopefully to have an idea what I am looking for. Sorry on beforehand if this topic has been discussed on several different ways. Hopefully you can give me direction, best rgds Albert


Note, the two sketches are rudimentary, it does not show any unnecessary details how I am going to build the bedframe and how I will mount the bedframe. Key is that the Van Floor will be a lot of times not leveled, either in x or Y or both and instead of leveling the entire fan, which is a costly thing I want just my bed being leveled.

The total project will be hard to find. You need to split it smaller parts. Set up the specifications for the bed frame. Build it. Note the weight. Select minear actuators strong enough. Regard safety, not cutting body parts outside the bed....
Surely a fun project but lots of stuff to figure out.

I figured one would realize that I left that part out of the question because that seemed rather obvious that the correct mounting needs to be in place..

Hi, Thanks for your answer. My question is really; all examples I see are from quadcopters and these are square. I think even with three legs the complicating factor is that the legs extend beyond the imaginary square which has consequences for the trigonometry.

If You like the different math, go for 3 legs, else go for 4 and benefit some from q-copters.

If your bed frame has ANY flex, then this will be impossible.

Hi, Funny you state this, Perhaps flexibility might be a big part of making it possible, will be unorthodox but well I will get that bedframe level, thank you.

Surplus Center in the USA has actuator bits. You can use a 9 degree of freedom IMU with the Arduino to get a degree reading on X, Y, and Z to make sure your bed is level. Mount the Arduino with the IMU on/under the bed.

Good luck. Sounds like a great project. I'll see if I can dig up some IMU code.

Found some working code I use with the Adafruit BNO08X IMU and the Arduino NANO RP2040 Connect. This should work with the UNO and the MEGA I would think:

#include <Arduino.h>
#include <WiFiNINA.h> // defines pin names and connection to built-in RGB leds
#include "Adafruit_BNO08x.h"
#include <HardwareSerial.h>
#define BNO08X_RESET -1

bool bIMURunning = false;
bool bProcessingIMU = false;
String IMU_Data = "";

Adafruit_BNO08x bno08x(BNO08X_RESET); //--20221212
sh2_SensorValue_t sensorValue;
sh2_SensorId_t reportType = SH2_GYRO_INTEGRATED_RV;

void setup() {

  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  // start with leds off
  analogWrite(LEDR, 255); //--255 is off
  analogWrite(LEDG, 255); //--255 is off
  analogWrite(LEDB, 255); //--255 is off

  Serial.begin(115200);  //--Brain comms
  Serial.setTimeout(200);
  Serial.println("Starting");
  Serial.flush();

  Serial1.begin(115200); //115200 
  Serial1.setTimeout(200);

  Serial.println("Starting IMU");
  Serial.flush();
  startIMUBNO08x(); //--put back when I can get the IMU off of I2C!
  setReports(); //--put back when I can get the IMU off of I2C!
  Serial.println("Done starting IMU");
  Serial.flush();
 
}

void loop() {
  Check_IMU_Has_Data();
  delay(9);
  
}

//--BNO08x RVC works. Now trying below for BNO reports
void Check_IMU_Has_Data() {
  if (bno08x.wasReset()) {  //--20221014 this routine will get called if the reset pin is pulled low and high again.
    Serial.print("sensor was reset");
    if (!bIMURunning) {  // <---20221014 not used yet because will not be set to false. Could use in the future.
      startIMUBNO08x();
    }
    setReports();
  }
  if (bIMURunning) {
    if (bno08x.getSensorEvent(&sensorValue)) {
      bProcessingIMU = true;
      //--20221016 out below. Moved to very bottom with other values
      switch (sensorValue.sensorId) {
        case SH2_GAME_ROTATION_VECTOR:
          float i = sensorValue.un.gameRotationVector.i * 1000;
          float j = sensorValue.un.gameRotationVector.j * 1000;
          float k = sensorValue.un.gameRotationVector.k * 1000;
          analogWrite(LEDR, map(i, -1000, 1000, 255, 0)); //--255 is off
          analogWrite(LEDG, map(j, -1000, 1000, 255, 0)); //--255 is off
          analogWrite(LEDB, map(k, -1000, 1000, 255, 0)); //--255 is off
          IMU_Data = "Game Rotation Vector - r: ";
          IMU_Data += String(sensorValue.un.gameRotationVector.real);
          IMU_Data += String(", i: ");
          IMU_Data += String(i);
          IMU_Data += String(", j: ");
          IMU_Data += String(j);
          IMU_Data += String(", k: ");
          IMU_Data += String(k);
      }
      bProcessingIMU = false;
      Serial.println(IMU_Data);
    }
  }else{
    IMU_Data = "IMU BNO08x not running. millis(): " + String(millis());
  }
}

uint8_t serial_config = 0b01010000;  // Enable RTS/CTS flow control

void startIMUBNO08x(void) {
  bIMURunning = false;
  // Try to initialize!
  Serial.println("Starting Adafruit BNO08x...");
  //if (!bno08x.begin_I2C()) {  //--put back for IMU I2C
                              //if (!bno08x.begin_AGAIN(0)) {
  Serial.println("Trying to start BNO08x in serial mode."); Serial.flush(); //digitalWrite(COMMLED, HIGH); //--take out
  Serial.flush();
 
  if (!bno08x.begin_UART(&Serial1)) {  // Requires a device with > 300 byte UART buffer!
    Serial.println("Failed to find BNO08x chip"); Serial.flush(); //digitalWrite(COMMLED, HIGH); //--take out
    bIMURunning = false;
  }else{
    Serial.println("Found BNO08x chip"); Serial.flush(); //digitalWrite(COMMLED, HIGH); //--take out
    bIMURunning = true;
    Serial.println("BNO08x Found!");
    for (int n = 0; n < bno08x.prodIds.numEntries; n++) {
      Serial.print("Part ");
      Serial.print(bno08x.prodIds.entry[n].swPartNumber);
      Serial.print(": Version :");
      Serial.print(bno08x.prodIds.entry[n].swVersionMajor);
      Serial.print(".");
      Serial.print(bno08x.prodIds.entry[n].swVersionMinor);
      Serial.print(".");
      Serial.print(bno08x.prodIds.entry[n].swVersionPatch);
      Serial.print(" Build ");
      Serial.println(String(bno08x.prodIds.entry[n].swBuildNumber));
    }
  }
}


// Here is where you define the sensor outputs you want to receive
void setReports(void) {
  if (bIMURunning) {
    Serial.println("Setting desired reports");
    //if (!bno08x.enableReport(SH2_GAME_ROTATION_VECTOR, reportIntervalUs)) {
    if (!bno08x.enableReport(SH2_GAME_ROTATION_VECTOR)) {
      Serial.println("Could not enable IMU BNO08x game rotation vector report mode");
    } else {
      Serial.println("Enabled IMU BNO08x game vector report mode");
    }
  } else {
    Serial.println("IMU not running. COuld not enabled IMU BNO08x game vector report mode");  //Setting desired reports
  }
}

inline void digitalToggle(byte pin){
  digitalWrite(pin, !digitalRead(pin));
}

1 Like

Oow This is great!!! I start working with your code, thanks for all the explanations in the code, that saves me so much figuring out.

If I look at the 4 legs version, starting from the upper right corner actuator I name it LA1 then LA3 will be left diagonally for the Y axis (on drawing nearest to the red remark campervan floor). Then LA2 and LA4 for the X axis. I believe doing it this is the best way?

The Arduino Gyroscope will be in the center of x,y, and linear to X or Y which is arbitrary I suppose?

Looking forward reading from you, much appreciated! Cheers, Albert

The actuators will have ball joints mounted under the aluminum frame corners. Then the motor sides will come in towards the center for about 50mm shy of 2" also on the same ball joints. That will prevent swaying. When I drive I will bring the bedframe to a "zero" position and mount it with quick fasteners to the Van.

1 Like

The IMU/Arduino could be mounted anywhere on the bed. They are really sensitive so will detect very slight angles. You'll see when you get it, or something like it, working and you move it around.

If you buy an Adafruit IMU, get one of these for really easy prototyping of the IMU:

I really like the BNO085 IMU because it does lots of calculations onboard to give you the angles, leaving your Arduino board free to do other things.

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