Charly F1: Auto a control remoto bluetooth con Arduino, Avr y VBasic

El Charly F1, el autito a control remoto de Charly Labs.

*Para una nueva versión de este proyecto haz click aquí

Siempre me preguntan ¿que es arduino? ¿que es un microcontrolador? ¿para que sirven?, bueno acá les dejo una pequeña demostración de lo que se puede hacer con ellos. Un auto a control remoto via bluetooth el cual fue creado como proyecto final para un curso de mi universidad.

El auto utiliza 1 servomotor y 1 motor DC los cuales son controlados por 1 microcontrolador atmega 328p y un atmega 168, los cuales a su vez reciben instrucciones via bluetooth desde un computador, gracias a una interfaz gráfica creada con visual studio 2010.

Este proyecto lo hice en el marco de un curso de microcontroladores de mi universidad, y como requisito del curso era necesario que el proyecto utilizara 2 microcontroladores, de ahí la razón de usar 2 micros. Pero se puede utilizar perfectamente 1 solo microcontrolador para realizar todo el proyecto, y conectar el modulo bluetooth HC-06 directamente al puerto serial del microcontrolador que controla los motores, en este caso el atmega328p.

Circuito Protoboard

circuito

Programar un atmega con el IDE de Arduino

Para poder programar los microcontroladores directamente desde el IDE de arduino y usando “lenguaje arduino”, fue necesario agregar como “Board” el atmega328p y el atmega168:

atmega

Para lograr esto se debe editar el archivo boards.txt ubicado en “/hardware/arduino” y agregar el siguiente código:

atmega168bb.name=ATmega168 on a breadboard (8 MHz internal clock)
atmega168bb.upload.protocol=stk500
atmega168bb.upload.maximum_size=14336
atmega168bb.upload.speed=57600
atmega168bb.bootloader.low_fuses=0xE2
atmega168bb.bootloader.high_fuses=0xDA
atmega168bb.bootloader.extended_fuses=0x05
atmega168bb.bootloader.path=arduino:atmega
atmega168bb.bootloader.file=ATmegaBOOT_168_pro_8MHz.hex
atmega168bb.bootloader.unlock_bits=0x3F
atmega168bb.bootloader.lock_bits=0x0F
atmega168bb.build.mcu=atmega168
atmega168bb.build.f_cpu=8000000L
atmega168bb.build.core=arduino:arduino
atmega168bb.build.variant=arduino:standard

atmega328bb.name=ATmega328p on a breadboard (8 MHz internal clock)
atmega328bb.upload.protocol=stk500
atmega328bb.upload.maximum_size=30720
atmega328bb.upload.speed=57600
atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05
atmega328bb.bootloader.path=arduino:atmega
atmega328bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F
atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=arduino:standard

Una vez hecho esto tenemos las configuraciones necesarias para setear los fuses de los microcontroladores de tal manera que podamos usarlos con el cristal interno. Quemamos el bootloader en cada uno de los micros con un programador AVR como el USBasp y luego de esto podremos programar los micros directamente desde el IDE de arduino y sin necesidad de cristal externo conectado al microcontrolador. Para quemar los micros recomiendo usar el USBasp ya que es compatible con el IDE de arduino y tan solo deberemos seleccionar la opción “cargar usando programador”.

Código control de motores

Este es el código en arduino que va en el micro que controla los motores, básicamente lo que hace es esperar por un caracter en el puerto serial, si este coincide con el caracter pedido por alguna de las condiciones (if), el código de la condición se ejecutará provocando un cambio en alguno de los motores, este ciclo se repite infinitamente permitiéndonos controlar el autito en diferentes direcciones.

#define S1 12                         //Pines a utilizar
#define S2 11
#define PWMdc 6
#define PWMservo 9

int valor = 0;                        // Variable que lee los datos llegado por comunicacion serial
int izq = 120;                        // Valor adecuado para girar el servo a la izquierda
int cen = 136;                        // Valor adecuado para poner el servo derecho
int der = 150;                        // Valor adecuado para girar el servo a la derecha
int cero = 0;                         // Velocidad motor DC = 0
int baja = 70;                        // Velocidad baja motor DC
int media = 150;                      // Velocidad media motor DC
int alta = 255;                       // Velocidad alta motor DC

void setup()
{
  pinMode (S1, OUTPUT);               // S1 puente H
  pinMode (S2, OUTPUT);               // S2 puente H
  pinMode (PWMdc, OUTPUT);            // PWM que determina la velocidad del motor DC
  pinMode (PWMservo, OUTPUT);         // PWM que determina el angulo del Servomotor
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0){       //LECTURA SERIAL
      valor=Serial.read();
                                       //DIRECCION SERVO
        if(valor=='1'){
          analogWrite(PWMservo, izq);  // virar a la izquierda
        }
        else if(valor=='2'){
          analogWrite(PWMservo, cen);  // avanzar derecho
        }
        else if(valor=='3'){
          analogWrite(PWMservo, der);  // virar a la derecha
        }
                                       //ESTADOS MOTOR DC
        else if(valor=='4'){
          digitalWrite(S1, LOW);       // Motor hacia adelante
          digitalWrite(S2, HIGH);
        }
        else if(valor=='5'){           // Motor hacia atras
          digitalWrite(S1, HIGH);
          digitalWrite(S2, LOW);
        }
        else if(valor=='6'){           // Frenar Motor
          digitalWrite(S1, HIGH);
          digitalWrite(S2, HIGH);
        }
                                       //VELOCIDAD MOTOR DC
        else if(valor=='7'){
          analogWrite(PWMdc, baja);    //Velocidad baja
        }
        else if(valor=='8'){
          analogWrite(PWMdc, media);   //Velocidad media
        }
        else if(valor=='9'){
          analogWrite(PWMdc, alta);    //Velocidad alta
        }
        else if(valor=='0'){
          analogWrite(PWMdc, cero);    //Cero velocidad
        }

    }
  }
}

Programa de control

El programa de control lo hice en Visual Studio 2010 y básicamente lo que hace es conectarse al puerto COM del bluetooth que esta emparejado al modulo bluetooth del autito y enviar mediante comunicación serial diferentes caracteres según el botón que apretemos. Cada botón de la interfaz envía un caracter distinto el cual a su vez activa una función diferente en el microcontrolador.

f1

Descargar

El código del programa está escrito en VB.net y funciona principalmente gracias al uso de la clase SerialPort:

Imports System
Imports System.Threading
Imports System.IO.Ports
Imports System.ComponentModel

Public Class Form1
    '------------------------------------------------
    Dim myPort As Array
    Delegate Sub SetTextCallback(ByVal 1 As String)

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        myPort = IO.Ports.SerialPort.GetPortNames()
        ComboBox1.Items.AddRange(myPort)

        Button2.Enabled = False
        Button1.Enabled = False
        Button4.Enabled = False
        Label4.Text = "OFF"
        Button5.Enabled = False
        Button6.Enabled = False
        Button7.Enabled = False
        Button3.Enabled = False
        Button8.Enabled = False
        TrackBar1.Enabled = False

    End Sub
    Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.E Then
            Button2.PerformClick()
        End If
        If e.KeyCode = Keys.G Then
            Button3.PerformClick()
        End If
        If e.KeyCode = Keys.R Then
            Button5.PerformClick()
        End If
        If e.KeyCode = Keys.I Then
            Button7.PerformClick()
        End If
        If e.KeyCode = Keys.J Then
            Button6.PerformClick()
        End If
        If e.KeyCode = Keys.L Then
            Button8.PerformClick()
        End If
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        SerialPort1.PortName = ComboBox1.Text
        SerialPort1.BaudRate = ComboBox2.Text
        SerialPort1.Open()
        Button1.Enabled = False
        Button2.Enabled = True
        Button4.Enabled = True
        Label4.Text = "OK"
        Button5.Enabled = True
        Button6.Enabled = True
        Button7.Enabled = True
        Button3.Enabled = True
        Button8.Enabled = True
        TrackBar1.Enabled = True

    End Sub

    Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
        SerialPort1.Close()
        Button1.Enabled = True
        Button2.Enabled = False
        Button4.Enabled = False
        Label4.Text = "OFF"
        Button5.Enabled = False
        Button6.Enabled = False
        Button7.Enabled = False
        Button3.Enabled = False
        Button8.Enabled = False
        TrackBar1.Enabled = False
        Label11.Text = "-"
        Label12.Text = "-"
        Label13.Text = "-"
        Label14.Text = "-"
    End Sub

    Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
        Button1.Enabled = True
    End Sub
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        If TrackBar1.Value > 0 Then
            SerialPort1.Write("5")
            Label11.Text = "Encendido"
            Label12.Text = "Hacia Adelante"
        End If
    End Sub

    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        SerialPort1.Write("6")
        Label11.Text = "Apagado"
        Label12.Text = "Ninguno"
    End Sub

    Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
        If TrackBar1.Value > 0 Then
            SerialPort1.Write("4")
            Label11.Text = "Encendido"
            Label12.Text = "Hacia Atrás"
        End If
    End Sub

    Private Sub Button8_Click(sender As System.Object, e As System.EventArgs) Handles Button8.Click
        SerialPort1.Write("3")
        Label13.Text = "Encendido"
        Label14.Text = "Derecha"
    End Sub

    Private Sub Button7_Click(sender As System.Object, e As System.EventArgs) Handles Button7.Click
        SerialPort1.Write("2")
        Label13.Text = "Encendido"
        Label14.Text = "Centro"
    End Sub

    Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
        SerialPort1.Write("1")
        Label13.Text = "Encendido"
        Label14.Text = "Izquierda"
    End Sub

    Private Sub TrackBar1_Scroll_1(sender As System.Object, e As System.EventArgs) Handles TrackBar1.Scroll
        If TrackBar1.Value = 0 Then
            SerialPort1.Write("0")
            Label11.Text = "Apagado"
        End If

        If TrackBar1.Value = 1 Then
            SerialPort1.Write("7")
        End If

        If TrackBar1.Value = 2 Then
            SerialPort1.Write("8")
        End If

        If TrackBar1.Value = 3 Then
            SerialPort1.Write("9")
        End If
    End Sub
End Class

Fotos Autito terminado

IMG_2318

IMG_2320

Licencia Creative Commons

Charly F1 está distribuido bajo una Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional.

  • Luis Poveda

    Podrias hacer de una manera mas entendible el circuito del protoboard

  • Renato

    Hola, excelente, pero deberías explicar como hiciste, como hacer y como funciona la mecánica de la dirección y el motor..

  • Wilson

    Hoye yo tengo una duda como puedo cagar una bateria y a la vez usar la bateria sin recivir el boltaje del cargador.no soy estudiante ninada pero tengo la curiocidad
    Gracias si me respondes

    • Con diodos rectificadores entre la fuente y la batería y entre la batería y lo que quieres alimentar. Pero si no son schottky tendrás mucha caída de voltaje en los diodos.

  • Solar Reflex

    Una pregunta no son necesarias las liberias de SoftwareSerial.h para la comunicacion con el bluetooth? ademas como declaraste el TxD y el RxD?

    Por cierto excelente proyecto

    • Aldo E. Herrerías

      No es necesaria la libreria softwareserial.h cuando conectadas los cables del bluetooth a los pines 0(Rx) y 1(Tx) de tu arduino, ya que estan hechos para dicha función y no es necesario declararlos, pero bien ya que si tu quisieras conectar tu bluetooth en pines diferentes a estos 2 primeros entonces si tendrias que utilizar la libreria softwareserial.h, y bueno por lo que veo me parece que es el HC-06. Saludos

  • juan carlos

    quiero 2 controla dores

  • Andres Moreno

    hola que buen proyecto, quisiera saber ¿cuál es el rango máximo de alcance? y, ¿si yo construyo 2 carritos iguales, las señales q transmites se interfieren, provocando q ninguno de los carros se mueva?

  • Vladimir Cortez

    oie y si quiero comunicarme con el bluetouch de mi smartphone, es posible… eso estaria super….

  • Jhon Deco Valenzuela Elguera

    hola amigo. quisiera que hagas un video en donde explicas paso paso como haces el autito. te le agradeceria mucho. 😀

  • frankizz

    Hola amigo excelente, disculpa cress que puedas subir el codigo del atmega 168, es que quiero unir 2 atmegas tal como lo haces en el tutorial, gracias. Esta chido tu autito

  • Miguel Angel

    podrias hacer un tutorial sobre como controlar la direccion del carrito :3

  • david

    quiero saber como hacer desde ceroooo!!!

  • Cristian Moriano

    Hola.. muy interesante todo, sera me puedes hacer el favor de facilitar el circuito.te agradezco.

  • Andres Castro

    me puedes regalar el circuito

Subir