Hello World! ![]()
About a week ago, my buddy asked me to make him some kind of PLUG&PLAY safety "Overspeed Governor" kind of circuitry, for his elevator (he runs an elevator business). This elevator is not meant to be used for humans, just to lift heavy machinery, however he just wanted to add some additional safety features.
His idea was for me to make like a little plug & play box, that works like a relay switch, but it lets 12v through only if the Z acceleration exceeds a certain treshold. Lets say 1000. Then they would take this 12v SIGNAL output, to activate the breaks.
We have a + 12V input (which supplies the arduino, through the buck converter, and also supplies the SIGNAL, when run through the relay), from their PSU, a GND, again from their PSU, and the previously mentioned SIGNAL output.
List of my components:
-
GY-521 + MPU6050 (gyro and accelerometer - i know it's a bit overkill)
-
RELC-1CH-5V-UNI Relay Board
-
Arduino Nano (A4,A5 are the SCL and SDL pins for i2c)
-
DSN-1504-3A Buck regulator
-
0,75 mm copper speaker wires (rated 6 amps max)
The arduino's Micro USB connection will stay exposed, so they can update the new code, when they want to calibrate the treshold value, at which the elevator is considered to be free falling.
#include "Wire.h" // This library allows you to communicate with I2C devices.
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data
bool panicMode = false;
int speed_treshold = 1000;
char tmp_str[7]; // temporary variable used in convert function
char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
sprintf(tmp_str, "%6d", i);
return tmp_str;
}
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
// Setting up Relay pin
pinMode(2, OUTPUT);
}
void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
// "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
// print out data
Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
// the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]
Serial.print(" | tmp = "); Serial.print(temperature/340.00+36.53);
Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
Serial.print(" | gZ = "); Serial.print(convert_int16_to_str(gyro_z));
Serial.println();
// delay
delay(100);
// check acceleration
if(panicMode == false){
if (accelerometer_z >= speed_treshold){
digital_write(2, HIGH);
panicMode = true;
Serial.println("PANIC MODE HAS BEEN ACTIVATED!");
Serial.println("RESET DEVICE TO DEACTIVATE!");
}
}
}
What my question is, would this configuration work for his needs, will it last, or is there something i should consider changing about my circuitry or code?
Thank you in advance!
Edit 1: Added links to components' datasheets!


