Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

En este tutorial aprenderemos a hacer un medidor de distancia Arduino y un nivel de burbuja digital. Puede ver el video siguiente o leer el tutorial escrito a continuación.

Resumen

El dispositivo incluye un sensor ultrasónico para medir distancia al objeto más cercano, un acelerómetro para medir ángulo respecto al suelo, una pantalla LCD para mostrar resultados y un PCB de diseño personalizado donde se conectan todos los componentes.

Se opera con un solo botón. Al encender, hay que seleccionar la unidad de medida.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Pulsando el botón cambiamos de unidad; manteniéndolo pulsado entramos en el primer programa: medición de distancia con capacidad de guardar las dos últimas mediciones.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Para el segundo programa, otra pulsación larga: medición de área cuadrada tomando dos distancias perpendiculares.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

El tercer programa es el nivel digital: medición de ángulo respecto al suelo.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Con el botón alternamos entre los dos ejes (Pitch o Roll).

Esquema de Circuito del Telémetro Arduino

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Tengo tutoriales detallados de cada módulo: Sensor ultrasónico, LCD, Acelerómetro MEMS.

Componentes necesarios:

PCB de Diseño Personalizado

Según el esquema diseñé PCB personalizado en EasyEDA (software gratuito online).

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Exportamos archivo Gerber para fabricación. Archivos del proyecto EasyEDA aquí.

Pedimos PCB a JLCPCB (patrocinador).

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Subimos Gerber, revisamos en visor, seleccionamos propiedades y pedimos. Primer pedido: hasta 10 PCBs por $2.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Montaje del Dispositivo

Tras unos días llegaron los PCBs. Calidad excelente, todo coincide con el diseño.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Empecé soldando pines header en PCB para conectar/desconectar fácilmente.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Soldé tres resistencias: dos para divisor de tensión de contraste LCD (1k en R1, 220 ohm en R2), tercera pull-up para botón.

Hice la carcasa con acrílico transparente de 5 mm (tenía de proyecto anterior) para ver la electrónica. Sierra circular para cortar a medida.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Hice abertura para LCD en tapa superior (4 mm para mejor ajuste): dos agujeros con taladro, sierra de calar para abrir grosso, lima para líneas finas y ajuste perfecto.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Con broca Forstner hice huecos para interruptor alimentación, botón control y sensor ultrasónico.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Ensamblé con epoxi 5 min. Para la tapa, puse dos tornillos por donde se inserta panel superior y se asegura con tuercas.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Soldé headers al LCD, y jumpers a interruptor, botón y conector batería.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

Montaje final: sensor ultrasónico en PCB y por huecos laterales; Arduino, acelerómetro, conector batería.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

En tapa superior: LCD, interruptor, botón, conectados al PCB. Por último, batería 9V en conector y aseguré tapa con tuercas.

Construya un Telémetro Arduino y Nivel Digital – Guía Paso a Paso Fácil

¡El proyecto telémetro Arduino y nivel digital está listo! Queda explicar el código.

Código Fuente: Telémetro Arduino y Nivel Digital

Al ser largo, publicaré en secciones con descripción. Al final, código completo.

Primero incluimos Wire.h (I2C acelerómetro) y LiquidCrystal.h (control LCD). Definimos LCD, dirección I2C MPU6050 (0x68), pines ultrasónico, y variables.

#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (rs, enable, d4, d5, d6, d7)
const int MPU = 0x68;
#define trigPin 8
#define echoPin 9
#define selectButton 10

int16_t AcX, AcY, AcZ;
long duration;
float distance;
int program = 0;
float d = 0, d1 = 0, d2 = 0, area = 0;
int axis = 0, angle = 0;
int unitSelect = 0;
String unit = "cm";

En setup() inicializamos I2C del acelerómetro y LCD, y modos de pin.

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); Wire.write(0);
  Wire.endTransmission(true);
  lcd.begin(16, 2);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(selectButton, INPUT_PULLUP);
}

En loop() usamos switch para cambiar entre programas.

Caso 0: Seleccionar unidad de medida

case 0:
  lcd.setCursor(0, 0);
  lcd.print("Select Unit: ");
  lcd.setCursor(13, 0);
  lcd.print(unit); lcd.print(" ");
  delay(10);
  if (digitalRead(selectButton) == 0) {
    if (unitSelect == 0) { unit = "in"; unitSelect = 1; }
    else if (unitSelect == 1) { unit = "m"; unitSelect = 2; }
    else if (unitSelect == 2) { unit = "ft"; unitSelect = 3; }
    else if (unitSelect == 3) { unit = "cm"; unitSelect = 0; }
    delay(500);
    if (digitalRead(selectButton) == 0) {
      program = 1; lcd.clear(); delay(500);
    }
  }
  break;

La variable unitSelect actúa en la función getDistance() para convertir la unidad base (cm) a la seleccionada.

// Conversión unidades en getDistance()
if (unitSelect == 1) { distance = distance; unit = "cm"; }      // cm
else if (unitSelect == 2) { distance *= 0.393701; unit = "in"; } // pulgadas
else if (unitSelect == 3) { distance *= 0.01; unit = "m"; }      // metros
else if (unitSelect == 0) { distance *= 0.0328; unit = "ft"; }   // pies

Mantener botón >0,5s cambia a programa 1.

Caso 1: Programa medición distancia

case 1:
  distance = getDistance();
  lcd.setCursor(0, 0);
  lcd.print("Dist: "); lcd.print(distance); lcd.print(" ");
  lcd.setCursor(14, 0); lcd.print(unit); delay(10);
  lcd.setCursor(0, 1); lcd.print("d:"); lcd.setCursor(8, 1); lcd.print("d:"); delay(200);
  // Guardar distancia 1
  if (digitalRead(selectButton) == 0) {
    if (d == 0) { lcd.setCursor(0,1); lcd.print("d: "); lcd.setCursor(2,1); lcd.print(distance); d=1; delay(100); }
    else if (d == 1) { lcd.setCursor(8,1); lcd.print("d: "); lcd.setCursor(10,1); lcd.print(distance); d=0; delay(100); }
    delay(500);
    if (digitalRead(selectButton) == 0) { program=2; d=0; lcd.clear(); delay(500); }
  }
  break;

Función getDistance():

float getDistance() {
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2; // cm
  // Conversión unidades (ver arriba)
  return distance;
}

El sensor genera onda ultrasónica por pin trigger; pin echo mide tiempo de ida y vuelta con pulseIn(). Con velocidad del sonido y tiempo calculamos distancia. Mostramos en LCD y con botón guardamos últimas 2 mediciones.

Caso 2: Programa medición área

Tomamos dos mediciones perpendiculares y las multiplicamos para obtener área del rectángulo formado.

case 2:
  distance = getDistance();
  lcd.setCursor(0,0); lcd.print("Area: "); lcd.print(area);
  lcd.setCursor(12,0); lcd.print(unit); lcd.print("^2"); delay(200);
  if (d==0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); delay(200); }
  else if (d==1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); delay(200); }
  else if (d==2) { lcd.setCursor(6,0); lcd.print(area); delay(200); }
  if (digitalRead(selectButton)==0) {
    if (d==0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); d=1; d1=distance; delay(100); }
    else if (d==1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); d=2; d2=distance; area=d1*d2; delay(100); }
    else if (d==2) { lcd.clear(); d=0; area=0; delay(100); }
    delay(500);
    if (digitalRead(selectButton)==0) { program=3; d=0; lcd.clear(); delay(500); }
  }
  break;

Caso 3: Programa medición ángulo (Nivel digital)

Leemos datos del acelerómetro (fuerza gravedad en 3 ejes X,Y,Z). Cada eje usa 2 registros → leemos 6 registros y combinamos.

case 3:
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Registro ACCEL_XOUT_H
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Leer 6 registros
  AcX = Wire.read()<<8 | Wire.read();
  AcY = Wire.read()<<8 | Wire.read();
  AcZ = Wire.read()<<8 | Wire.read();
  if (axis == 0) {
    // Pitch (rotación eje Y)
    angle = atan(-1 * AcX / sqrt(pow(AcY,2) + pow(AcZ,2))) * 180 / PI;
    lcd.setCursor(0,0); lcd.print("Pitch");
  } else {
    // Roll (rotación eje X)
    angle = atan(-1 * AcY / sqrt(pow(AcX,2) + pow(AcZ,2))) * 180 / PI;
    lcd.setCursor(0,0); lcd.print("Roll ");
  }
  lcd.setCursor(0,1); lcd.print("Angle: "); lcd.print(abs(angle)); lcd.print(" "); lcd.setCursor(10,1); lcd.print("deg"); delay(200);
  // Cambiar eje con botón
  if (digitalRead(selectButton)==0) {
    if (axis==0) { axis=1; delay(100); }
    else if (axis==1) { axis=0; delay(100); }
    delay(500);
    if (digitalRead(selectButton)==0) { program=0; lcd.clear(); delay(500); }
  }
  break;

Con valores X,Y,Z calculamos Pitch (rotación eje Y) y Roll (rotación eje X) usando ecuaciones trigonométricas. Detalles en Freescale Semiconductor application note: Tilt Sensing Using a Three-Axis Accelerometer. Mostramos en LCD y con botón alternamos Pitch/Roll.

Código Completo

/* DIY Digital Range Measurer and Spirit Level
   by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
const int MPU = 0x68;
#define trigPin 8
#define echoPin 9
#define selectButton 10
int16_t AcX, AcY, AcZ;
long duration;
float distance;
int program = 0;
float d = 0, d1 = 0, d2 = 0, area = 0;
int axis = 0, angle = 0;
int unitSelect = 0;
String unit = "cm";

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true);
  lcd.begin(16, 2);
  pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(selectButton, INPUT_PULLUP);
}

void loop() {
  switch (program) {
    case 0:
      lcd.setCursor(0,0); lcd.print("Select Unit: "); lcd.setCursor(13,0); lcd.print(unit); lcd.print(" "); delay(10);
      if (digitalRead(selectButton)==0) {
        if (unitSelect==0) { unit="in"; unitSelect=1; }
        else if (unitSelect==1) { unit="m"; unitSelect=2; }
        else if (unitSelect==2) { unit="ft"; unitSelect=3; }
        else if (unitSelect==3) { unit="cm"; unitSelect=0; }
        delay(500);
        if (digitalRead(selectButton)==0) { program=1; lcd.clear(); delay(500); }
      }
      break;
    case 1:
      distance = getDistance();
      lcd.setCursor(0,0); lcd.print("Dist: "); lcd.print(distance); lcd.print(" "); lcd.setCursor(14,0); lcd.print(unit); delay(10);
      lcd.setCursor(0,1); lcd.print("d:"); lcd.setCursor(8,1); lcd.print("d:"); delay(200);
      if (digitalRead(selectButton)==0) {
        if (d==0) { lcd.setCursor(0,1); lcd.print("d: "); lcd.setCursor(2,1); lcd.print(distance); d=1; delay(100); }
        else if (d==1) { lcd.setCursor(8,1); lcd.print("d: "); lcd.setCursor(10,1); lcd.print(distance); d=0; delay(100); }
        delay(500);
        if (digitalRead(selectButton)==0) { program=2; d=0; lcd.clear(); delay(500); }
      }
      break;
    case 2:
      distance = getDistance();
      lcd.setCursor(0,0); lcd.print("Area: "); lcd.print(area); lcd.setCursor(12,0); lcd.print(unit); lcd.print("^2"); delay(200);
      if (d==0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); delay(200); }
      else if (d==1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); delay(200); }
      else if (d==2) { lcd.setCursor(6,0); lcd.print(area); delay(200); }
      if (digitalRead(selectButton)==0) {
        if (d==0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); d=1; d1=distance; delay(100); }
        else if (d==1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); d=2; d2=distance; area=d1*d2; delay(100); }
        else if (d==2) { lcd.clear(); d=0; area=0; delay(100); }
        delay(500);
        if (digitalRead(selectButton)==0) { program=3; d=0; lcd.clear(); delay(500); }
      }
      break;
    case 3:
      Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false);
      Wire.requestFrom(MPU,6,true);
      AcX = Wire.read()<<8 | Wire.read();
      AcY = Wire.read()<<8 | Wire.read();
      AcZ = Wire.read()<<8 | Wire.read();
      if (axis==0) { angle = atan(-1*AcX/sqrt(pow(AcY,2)+pow(AcZ,2)))*180/PI; lcd.setCursor(0,0); lcd.print("Pitch"); }
      else { angle = atan(-1*AcY/sqrt(pow(AcX,2)+pow(AcZ,2)))*180/PI; lcd.setCursor(0,0); lcd.print("Roll "); }
      lcd.setCursor(0,1); lcd.print("Angle: "); lcd.print(abs(angle)); lcd.print(" "); lcd.setCursor(10,1); lcd.print("deg"); delay(200);
      if (digitalRead(selectButton)==0) {
        if (axis==0) { axis=1; delay(100); }
        else if (axis==1) { axis=0; delay(100); }
        delay(500);
        if (digitalRead(selectButton)==0) { program=0; lcd.clear(); delay(500); }
      }
      break;
  }
}

float getDistance() {
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  if (unitSelect==1) { distance=distance; unit="cm"; }
  else if (unitSelect==2) { distance*=0.393701; unit="in"; }
  else if (unitSelect==3) { distance*=0.01; unit="m"; }
  else if (unitSelect==0) { distance*=0.0328; unit="ft"; }
  return distance;
}

¡Eso es todo! Espero que hayan disfrutado este proyecto Arduino y aprendido algo nuevo. Pregunten en los comentarios.

Proceso de manufactura

  1. Central DCC Digital para Ferrocarril Modelo con Arduino y App Android Gratuita
  2. Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
  3. Crea Animaciones y Juegos en LCD 16×2 con Arduino UNO
  4. Detector de frecuencia de audio con Arduino – Mide los picos de sonido más intensos
  5. Construye tu Propio Tamagotchi con Arduino: Mascota Digital DIY
  6. Tres en raya con Arduino, matriz LED MAX7219 y carcasa de cartón
  7. Construye un voltímetro DIY con Arduino y pantalla Nokia 5110 – Guía paso a paso
  8. Construye un Temporizador Regresivo Fiable con Arduino y Pantalla de 7 Segmentos SparkFun
  9. Control Arduino UNO desde Python 3 – Envío de Comandos y Demo LED
  10. Construye una Radio FM Compacta con Arduino Nano y RDA5807M
  11. Monitor de nivel de sumidero DIY con Arduino Nano, MPXV5010DP y pantalla OLED