目次
Structure
It is very difficult to measure height because a child cannot sit still for a long time.
So we found a high-precision sensor at a low price, so we created a height measuring instrument that does not take up space and time.
目次
Distance sensor VL53L0X
It is a sensor of the resolution 1mm in a great wide range!The library for Arduino is below.
https://github.com/pololu/vl53l0x-arduino
6 axis motion sensor MPU6050
3-axis gyroscope and 3-axis accelerometer can sensing posture information.This time, we use horizontal x-axis and y-axis acceleration to measure the level of the measuring instrument.But it’s a mess!The library for Arduino is located below (using mpu6050 and I2cdev).
https://github.com/jrowberg/i2cdevlib/tree/master/Arduino
LCD display
https://www.arduino.cc/en/Tutorial/HelloWorld
Microcontroller Arduino Nano compatible
I use a cheap compatible product:-)
The distance sensor VL53L0X is placed in the bottom of a box. The sensor can measure distances of up to 2m with 1 mm resolution.
Place the microcomputer Arduino Nano and 6-axis motion sensor MPU6050 in the box, the power supply was used a 9V battery.
MPU6050 is used to measure x-axis and y-axis of acceleration for detect the horizontal direction. The LED (Neopixel) is green , when measure is horizontal. When non-horizontal is light red.
Distances are displayed on the LCD display .
Turn on the power switch, the measure operates in the normal mode. In Normal Mode, The measurement distance is always displayed on LCD. The LED is green, when measure is horizontal. When non-horizontal is light red.
While you hold down the Meas. Button (tact switch) it will be the Measurement Mode. Put measure on head. Turn the Measurement Mode. When the distance in a horizontal state is detected, LED is blue light and measurement value is held.
距離センサVL53L0Xで長女ちゃん身長測定 pic.twitter.com/1tMOndvOgy
— HomeMadeGarbage (@H0meMadeGarbage) 2016年9月16日
Press the measurement button again to return to normal mode.
The distance sensor vl53l0x is used in Long_range mode and high_accuracy mode.
The distance is adjusted to the unit in CM and the sensor position is corrected (1mm).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
#include "I2Cdev.h" #include "MPU6050.h" #include <Adafruit_NeoPixel.h> #include <VL53L0X.h> #include <LiquidCrystal.h> // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif int mode = 0; MPU6050 accelgyro; // class default I2C address is 0x68 int16_t ax, ay, az; int diffAccel = 100; #define PIN 8 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800); //LiquidCrystal lcd(RS[4], E[6], DB4[11], DB5[12], DB6[13], DB7[14]); LiquidCrystal lcd(12, 11, 5, 4, 3, 2); char s[16]; VL53L0X sensor; float height; // Uncomment this line to use long range mode. This // increases the sensitivity of the sensor and extends its // potential range, but increases the likelihood of getting // an inaccurate reading because of reflections from objects // other than the intended target. It works best in dark // conditions. #define LONG_RANGE // Uncomment ONE of these two lines to get // - higher speed at the cost of lower accuracy OR // - higher accuracy at the cost of lower speed //#define HIGH_SPEED #define HIGH_ACCURACY void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(38400); pinMode(9, INPUT_PULLUP); pixels.begin(); pixels.setBrightness(50); pixels.setPixelColor(0, pixels.Color(0,0,0)); pixels.show(); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("x"); lcd.setCursor(9, 0); lcd.print("y"); lcd.setCursor(0, 1); lcd.print("Height:"); sensor.init(); sensor.setTimeout(500); #if defined LONG_RANGE // lower the return signal rate limit (default is 0.25 MCPS) sensor.setSignalRateLimit(0.1); // increase laser pulse periods (defaults are 14 and 10 PCLKs) sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18); sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14); #endif #if defined HIGH_SPEED // reduce timing budget to 20 ms (default is about 33 ms) sensor.setMeasurementTimingBudget(20000); #elif defined HIGH_ACCURACY // increase timing budget to 200 ms sensor.setMeasurementTimingBudget(200000); #endif // initialize device Serial.println("Initializing I2C devices..."); accelgyro.initialize(); // verify connection Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); if(accelgyro.testConnection()){ pixels.setPixelColor(0, pixels.Color(255,0,0)); pixels.show(); } // use the code below to change accel/gyro offset values accelgyro.setXAccelOffset(40); //0 accelgyro.setYAccelOffset(-985); //0 accelgyro.setZAccelOffset(968); //16384 } void loop() { //Measurement Mode while(digitalRead(9) == 0 && mode == 0){ // read raw accel accelgyro.getAcceleration(&ax, &ay, &az); lcd.setCursor(1, 0); lcd.print(dtostrf(ax,6,0,s)); lcd.setCursor(10, 0); lcd.print(dtostrf(ay,6,0,s)); if(abs(ax) < diffAccel && abs(ay) < diffAccel){ pixels.setPixelColor(0, pixels.Color(0,255,0)); pixels.show(); if (sensor.timeoutOccurred() == 0) { //Distance measurement height = sensor.readRangeSingleMillimeters()/10.0 + 0.1; lcd.setCursor(8, 1); if(height <= 220.0){ lcd.print(dtostrf(height,5,1,s)); pixels.setPixelColor(0, pixels.Color(0,0,255)); pixels.show(); mode = 1; } } }else{ pixels.setPixelColor(0, pixels.Color(255,0,0)); pixels.show(); } } //Mode Reset if(digitalRead(9) == 1 && mode == 1){ mode = 2; delay(100); } if(digitalRead(9) == 0 && mode == 2){ mode = 0; delay(100); } //Normal Mode if(digitalRead(9) == 1 && mode == 0){ // read raw accel accelgyro.getAcceleration(&ax, &ay, &az); lcd.setCursor(1, 0); lcd.print(dtostrf(ax,6,0,s)); lcd.setCursor(10, 0); lcd.print(dtostrf(ay,6,0,s)); if(abs(ax) < diffAccel && abs(ay) < diffAccel){ pixels.setPixelColor(0, pixels.Color(0,255,0)); pixels.show(); }else{ pixels.setPixelColor(0, pixels.Color(255,0,0)); pixels.show(); } if (sensor.timeoutOccurred() == 0) { //Distance measurement height = sensor.readRangeSingleMillimeters()/10.0 + 0.1; Serial.print(height); Serial.print("\t"); lcd.setCursor(8, 1); if(height <= 220.0){ lcd.print(dtostrf(height,5,1,s)); } } } } |
Because it can measure at relatively high speed and the accuracy is high, I can measure it easily even in the height of the eldest son who is restless in this ♪