Hoy veremos cómo realizar un pequeño proyecto de electrónica basado en un carrito arduino controlado mediante una App android que se conecta vía bluetooth a nuestra placa para gestionar los movimientos del vehículo, excelente proyecto de pasatiempo para los amantes de la electrónica.
Hace algunas semanas realice un pequeño proyecto que desde hace mucho tenia ganas de hacer.
Se trata de un pequeño carrito arduino que podamos controlar vía remota mediante una app que también programemos.
Este proyecto nació de varios proyectos de carritos arduino que vi en instagram y me pareció genial intentar hacer similar.

Suscríbete a nuestra lista de correo y recíbe los últimos contenidos directamente en tu bandeja de correo electrónico, puedes elegir únicamente de que categoria del blog quieres recibir contenido.
SuscríbemeAdemás al ser desarrollador de apps móviles pues decidí integrar esta parte mediante una app android que controle las direcciones del vehículo.
El app se conectará vía remota mediante bluetooth a un modulo de esta misma tecnología montado en el carrito.
¿Estas listo para ver cómo crear un carrito arduino controlado por Bluetooth mediante una App?
La lista de componentes
Para este proyecto necesitaremos los siguientes componentes:
- Placa arduino uno
- 2 pilas recargables 3.7v 18650
- 1 portapilas 18650
- Bluetooth HC-06
- Chasis de carro
- 4 motores de engranaje
- 4 llantas
- 1 módulo puente H L298
- Protoboard
- Cables de conexión
- App android (veremos el código fuente más adelante)
Esta es mi elección de componentes si deseas remplazar alguno o utilizar otro y tienes los conocimientos para hacerlo adelante!
Así lucirán nuestros componentes ya montados en nuestro proyecto:
El diagrama de conexiones
[Pendiente de subir]En cuanto pueda actualizo la entrada con el diagrama.
Por cierto, ¿Sabes que ya hemos realizado tutoriales de arduino en el blog?
El código arduino
char orden; int VELOCIDAD = 255; // Motor A int ENA = 10; int IN1 = 9; int IN2 = 8; // Motor B int ENB = 5; int IN3 = 7; int IN4 = 6; void setup() { Serial.begin(9600); pinMode (ENA, OUTPUT); pinMode (ENB, OUTPUT); pinMode (IN1, OUTPUT); pinMode (IN2, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN4, OUTPUT); } // Funciones void Adelante () { //Direccion motor A analogWrite (ENA, VELOCIDAD); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); //Direccion motor B analogWrite (ENB, VELOCIDAD); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } void Atras () { //Direccion motor A analogWrite (ENA, VELOCIDAD); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); //Direccion motor B analogWrite (ENB, VELOCIDAD); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); } void AtrasIzquierda () { //Direccion motor A analogWrite (ENA, VELOCIDAD); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); //Direccion motor B analogWrite (ENB, VELOCIDAD/2); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); } void AtrasDerecha () { //Direccion motor A analogWrite (ENA, VELOCIDAD/2); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); //Direccion motor B analogWrite (ENB, VELOCIDAD); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); } void Derecha () { //Direccion motor A analogWrite (ENA, 0); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); //Direccion motor B analogWrite (ENB, VELOCIDAD); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } void AdelanteDerecha () { //Direccion motor A analogWrite (ENA, VELOCIDAD/2); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); //Direccion motor B analogWrite (ENB, VELOCIDAD); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } void Izquierda () { //Direccion motor A analogWrite (ENA, VELOCIDAD); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); //Direccion motor B analogWrite (ENB, 0); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); } void AdelanteIzquierda () { //Direccion motor A analogWrite (ENA, VELOCIDAD); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); //Direccion motor B analogWrite (ENB, VELOCIDAD/2); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } void Parar () { //Direccion motor A analogWrite (ENA, 0); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); //Direccion motor B analogWrite (ENB, 0); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); } void loop() { if (Serial.available()) { orden = Serial.read(); if(orden=='w') { Adelante(); } else if(orden=='x') { Atras(); } else if(orden=='z') { AtrasIzquierda(); } else if(orden=='c') { AtrasDerecha(); } else if(orden=='d') { Derecha(); } else if(orden=='a') { Izquierda(); } else if(orden=='q') { AdelanteIzquierda(); } else if(orden=='e') { AdelanteDerecha(); } else if(orden=='s'){ Parar(); } } delay(10); }
En este código lo único que hacemos es gestionar la lógica de las direcciones mediante funciones que deciden cuales motores girar y hacia cual dirección para mover nuestro carrito hacia delante, atrás, izquierda y derecha.
Creamos una serie de comandos básicos:
- w: delante
- x: atrás
- a: izquierda
- d: derecha
- s: detener
Y más combinaciones..
Estos comandos o letras las mandaremos desde nuestra aplicación móvil android con bluetooth más adelante.
El app android y su código
Construiremos una interfaz como la siguiente:
Una vez más eres libre de cambiar cualquier cosa que no te guste en la pantalla.
Como puedes ver hemos dejado un área para la cámara que integraremos más adelante en nuestro carrito arduino.
Layout xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@color/blanco" xmlns:android="http://schemas.android.com/apk/res/android"> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" > <ImageView android:id="@+id/img_camara" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:background="@color/blanco" android:src="@drawable/logo"/> <Button android:id="@+id/btn_bluetooth" android:layout_below="@id/img_camara" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/azul" android:textColor="@color/blanco" android:layout_marginBottom="20dp" android:text="Bluetooth"/> <RelativeLayout android:id="@+id/panelBotones" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/btn_bluetooth" > <Button android:id="@+id/btn_adelante" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Adelante" /> <LinearLayout android:id="@+id/panelBotonesCentrales" android:layout_below="@id/btn_adelante" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/btn_izquierda" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btn_adelante" android:layout_weight="1" android:text="Izquierda" /> <Button android:id="@+id/btn_derecha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btn_adelante" android:layout_toRightOf="@id/btn_izquierda" android:layout_weight="1" android:text="Derecha" /> </LinearLayout> <Button android:id="@+id/btn_atras" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/panelBotonesCentrales" android:text="Atrás" /> </RelativeLayout> <TextView android:id="@+id/txt_statusBluetooth" android:layout_below="@id/panelBotones" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:text="Sin enlazar.."/> </RelativeLayout> </RelativeLayout>
Ahora que tenemos nuestra vista lo siguiente es programar la funcionalidad, veamos cómo luce nuestro código Java.
Java
View view; String tag = "NAVEGACION"; FragmentManager fragmentManager; Button btn_bluetooth; Button btn_adelante; Button btn_izquierda; Button btn_derecha; Button btn_atras; TextView txt_statusBluetooth; private OutputStream outputStream; private InputStream inStream; private ImageView wheel; private double mCurrAngle = 0; private double mPrevAngle = 0; ImageView bask; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.navegacion_fragment, container, false); fragmentManager = getFragmentManager(); btn_bluetooth = (Button)view.findViewById(R.id.btn_bluetooth); txt_statusBluetooth = (TextView)view.findViewById(R.id.txt_statusBluetooth); btn_adelante = (Button) view.findViewById(R.id.btn_adelante); btn_izquierda = (Button) view.findViewById(R.id.btn_izquierda); btn_derecha = (Button) view.findViewById(R.id.btn_derecha); btn_atras = (Button) view.findViewById(R.id.btn_atras); btn_adelante.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { try{ write("w"); }catch(Exception err){ } } else if (event.getAction() == MotionEvent.ACTION_UP) { try{ write("s"); }catch(Exception err){ } } return true; } }); btn_izquierda.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { try{ write("a"); }catch(Exception err){ } } else if (event.getAction() == MotionEvent.ACTION_UP) { try{ write("s"); }catch(Exception err){ } } return true; } }); btn_derecha.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { try{ write("d"); }catch(Exception err){ } } else if (event.getAction() == MotionEvent.ACTION_UP) { try{ write("s"); }catch(Exception err){ } } return true; } }); btn_atras.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { try{ write("x"); }catch(Exception err){ } } else if (event.getAction() == MotionEvent.ACTION_UP) { try{ write("s"); }catch(Exception err){ } } return true; } }); btn_bluetooth.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { BluetoothAdapter blueAdapter = BluetoothAdapter.getDefaultAdapter(); if (blueAdapter != null) { if (blueAdapter.isEnabled()) { Set<BluetoothDevice> bondedDevices = blueAdapter.getBondedDevices(); if(bondedDevices.size() > 0) { Object[] devices = (Object []) bondedDevices.toArray(); BluetoothDevice device = (BluetoothDevice) devices[0]; ParcelUuid[] uuids = device.getUuids(); BluetoothSocket socket; try { socket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid()); socket.connect(); outputStream = socket.getOutputStream(); inStream = socket.getInputStream(); txt_statusBluetooth.setText("Rover enlazado.."); } catch (IOException e) { e.printStackTrace(); } }else{ txt_statusBluetooth.setText("No hay dispositivos bluetooth.."); } Log.e("error", "No appropriate paired devices."); } else { Log.e("error", "Bluetooth is disabled."); txt_statusBluetooth.setText("Bluetooth no activo.."); } } } }); return view; } /* Bluetooth */ public void write(String s) throws IOException { outputStream.write(s.getBytes()); } public void run() { final int BUFFER_SIZE = 1024; byte[] buffer = new byte[BUFFER_SIZE]; int bytes = 0; int b = BUFFER_SIZE; while (true) { try { bytes = inStream.read(buffer, bytes, BUFFER_SIZE - bytes); } catch (IOException e) { e.printStackTrace(); } } } /* Bluetooth */
Aquí lo que hacemos es configurar nuestra conexión bluetooth y escuchar cada evento de nuestros botones de dirección para mandar el comando correspondiente de los que esperamos en nuestro código arduino anteriormente.
Espero y hasta aquí vaya todo bien de lo contrario déjame un comentario abajo y con gusto te apoyo en cualquier duda.
Carrito arduino controlado por bluetooth en acción
Espero y este post sobre cómo hacer un carrito arduino controlado por Bluetooth mediante una App android te sea de utilidad para hacer el tuyo o algo similar en electrónica, recuerda que cualquier duda relacionada al tema de hoy puedes dejar un comentario abajo y con gusto trataré de resolverla.
Hasta luego!