En este proyecto vamos a realizar un robot basado en el conocido Robot-BOB pero con algunas modificaciones para adaptarlo a la mioio + shield mioiobot.
Vamos a necesitar:
Tarjeta MIOIO
Shield MIOIOBOT
Piezas MOIOIOBOB en formato STL
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
También nesesitarás:
1 bluetooth usb
4 mini servos S9
1 ultrasonidos HC-SR04
2 portapilas AAA (Aunque con 1 sería suficiente).
Este programa se ha desarrollado en Eclipse, puedes descargarlo directamente compilado desde aquí.
El código viene a continuación.
Lo que hace el programa es básicamente controlar a MIOIOBOB en las direcciones que indica la fecla, y además, haciendo uso del ultrasonidos, le indicaremos a que distancia debe de retroceder.
Con el SeekBar lo que haremos será determinar la velocidad a la que queremos que se mueva el robot.
Vamos a diseñar el activity_main.xml.
Para este ejemplo se han utilizado:
- Cuatro ImageButton, para indicar el movimiento.
- Un Progressbar, para indicar la velocidad a la que queremos que funcione.
En el archivo MainActivity.java tenemos esto:
import ioio.lib.api.AnalogInput; import ioio.lib.api.DigitalOutput; import ioio.lib.api.IOIO; import ioio.lib.api.PulseInput; import ioio.lib.api.PulseInput.PulseMode; import ioio.lib.api.PwmOutput; import ioio.lib.api.exception.ConnectionLostException; import ioio.lib.util.BaseIOIOLooper; import ioio.lib.util.IOIOLooper; import ioio.lib.util.android.IOIOActivity; import android.os.Bundle; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import android.widget.ToggleButton; import android.view.View; import android.view.View.OnClickListener; public class MIOIOBOB_Activity extends IOIOActivity { private SeekBar BarraVelocidad; private ImageButton ArribaBoton; private ImageButton IzquierdaBoton; private ImageButton DerechaBoton; private ImageButton AbajoBoton; boolean adelante =false; boolean atras =false; boolean izquierda =false; boolean derecha =false; private int echoSeconds; private int echoDistanceCm; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ArribaBoton = (ImageButton)findViewById(R.id.imageButton1); IzquierdaBoton = (ImageButton)findViewById(R.id.imageButton2); DerechaBoton = (ImageButton)findViewById(R.id.imageButton3); AbajoBoton = (ImageButton)findViewById(R.id.imageButton4); BarraVelocidad = (SeekBar)findViewById(R.id.seekBar1); ArribaBoton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { adelante = true; } }); IzquierdaBoton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { izquierda = true; } }); DerechaBoton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { derecha = true; } }); AbajoBoton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { atras= true; } }); enableUi(false); } class Looper extends BaseIOIOLooper { private AnalogInput input_; private PwmOutput pwmOutput_; private PwmOutput pwmCaderaDer; private PwmOutput pwmTobilloDer; private PwmOutput pwmCaderaIzq; private PwmOutput pwmTobilloIzq; private DigitalOutput led_; /* ultrasonic sensor */ private DigitalOutput triggerPin_; private PulseInput echoPin_; @Override public void setup() throws ConnectionLostException, InterruptedException { try { pwmCaderaDer = ioio_.openPwmOutput(34, 100); pwmTobilloDer = ioio_.openPwmOutput(35, 100); pwmCaderaIzq = ioio_.openPwmOutput(36, 100); pwmTobilloIzq = ioio_.openPwmOutput(45, 100); led_ = ioio_.openDigitalOutput(IOIO.LED_PIN, true); /* ultrasonic sensor */ echoPin_ = ioio_.openPulseInput(48, PulseMode.POSITIVE); triggerPin_ = ioio_.openDigitalOutput(47); Thread.sleep(100); enableUi(true); } catch (ConnectionLostException e) { enableUi(false); throw e; } } @Override public void loop() throws ConnectionLostException { try { final int velocidad = BarraVelocidad.getProgress(); // read HC-SR04 ultrasonic sensor triggerPin_.write(false); Thread.sleep(5); triggerPin_.write(true); Thread.sleep(1); triggerPin_.write(false); echoSeconds = (int) (echoPin_.getDuration() * 1000 * 1000); echoDistanceCm = echoSeconds / 29 / 2; if(echoDistanceCm<10){ pwmCaderaDer.setPulseWidth((int) (13.88*90)); pwmTobilloDer.setPulseWidth((int) (13.88*90)); pwmCaderaIzq.setPulseWidth((int) (13.88*90)); pwmTobilloIzq.setPulseWidth((int) (13.88*90)); Thread.sleep(velocidad); for(int a = 90;a<120;a++){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 90;a>70;a--){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 120;a>65;a--){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 70;a<115;a++){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 65;a<120;a++){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 115;a>90;a--){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 120;a>90;a--){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } } if (adelante==true){ // TODO Auto-generated method stub try { pwmCaderaDer.setPulseWidth((int) (13.88*90)); pwmTobilloDer.setPulseWidth((int) (13.88*90)); pwmCaderaIzq.setPulseWidth((int) (13.88*90)); pwmTobilloIzq.setPulseWidth((int) (13.88*90)); Thread.sleep(velocidad); for(int a = 90;a<115;a++){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int b = 90;b>65;b=b-1){ pwmTobilloDer.setPulseWidth((int) (13.88*(b))); pwmTobilloIzq.setPulseWidth((int) (13.88*(b))); Thread.sleep(velocidad); } for(int c = 115;c>65;c=c-1){ pwmCaderaDer.setPulseWidth((int) (13.88*(c))); pwmCaderaIzq.setPulseWidth((int) (13.88*(c))); Thread.sleep(velocidad); } for(int e = 65;e<115;e=e+1){ pwmTobilloDer.setPulseWidth((int) (13.88*(e*1))); pwmTobilloIzq.setPulseWidth((int) (13.88*(e*1))); Thread.sleep(velocidad); } for(int f = 65;f<90;f=f+1){ pwmCaderaDer.setPulseWidth((int) (13.88*f)); pwmCaderaIzq.setPulseWidth((int) (13.88*f)); Thread.sleep(velocidad); } for(int j = 90;j<115;j=j+1){ pwmCaderaDer.setPulseWidth((int) (13.88*(j))); pwmCaderaIzq.setPulseWidth((int) (13.88*(j))); Thread.sleep(velocidad); } for(int k = 115;k>65;k=k-1){ pwmTobilloDer.setPulseWidth((int) (13.88*(k))); pwmTobilloIzq.setPulseWidth((int) (13.88*(k))); Thread.sleep(velocidad); } for(int l = 115;l>90;l=l-1){ pwmCaderaDer.setPulseWidth((int) (13.88*l)); pwmCaderaIzq.setPulseWidth((int) (13.88*l)); Thread.sleep(velocidad); } for(int k = 65;k<90;k=k+1){ pwmTobilloDer.setPulseWidth((int) (13.88*(k))); pwmTobilloIzq.setPulseWidth((int) (13.88*(k))); Thread.sleep(velocidad); } adelante = false; } catch (ConnectionLostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(izquierda==true){ pwmCaderaDer.setPulseWidth((int) (13.88*90)); pwmTobilloDer.setPulseWidth((int) (13.88*90)); pwmCaderaIzq.setPulseWidth((int) (13.88*90)); pwmTobilloIzq.setPulseWidth((int) (13.88*90)); Thread.sleep(velocidad); for(int a = 90;a>65;a--){ pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 90;a<125;a++){ pwmTobilloDer.setPulseWidth((int) (13.88*(a))); pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 65;a<90;a++){ pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 125;a>90;a--){ pwmTobilloDer.setPulseWidth((int) (13.88*(a))); pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } izquierda=false; } if(derecha==true){ pwmCaderaDer.setPulseWidth((int) (13.88*90)); pwmTobilloDer.setPulseWidth((int) (13.88*90)); pwmCaderaIzq.setPulseWidth((int) (13.88*90)); pwmTobilloIzq.setPulseWidth((int) (13.88*90)); Thread.sleep(velocidad); for(int a = 90;a<115;a++){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 90;a>65;a--){ pwmTobilloDer.setPulseWidth((int) (13.88*(a))); pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 115;a>90;a--){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 65;a<90;a++){ pwmTobilloDer.setPulseWidth((int) (13.88*(a))); pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } derecha=false; } if(atras==true){ pwmCaderaDer.setPulseWidth((int) (13.88*90)); pwmTobilloDer.setPulseWidth((int) (13.88*90)); pwmCaderaIzq.setPulseWidth((int) (13.88*90)); pwmTobilloIzq.setPulseWidth((int) (13.88*90)); Thread.sleep(velocidad); for(int a = 90;a<120;a++){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 90;a>70;a--){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 120;a>65;a--){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 70;a<115;a++){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 65;a<120;a++){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 115;a>90;a--){ pwmCaderaDer.setPulseWidth((int) (13.88*(a))); pwmCaderaIzq.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } for(int a = 120;a>90;a--){ pwmTobilloIzq.setPulseWidth((int) (13.88*(a))); pwmTobilloDer.setPulseWidth((int) (13.88*(a))); Thread.sleep(velocidad); } atras=false; } Thread.sleep(10); } catch (InterruptedException e) { ioio_.disconnect(); } catch (ConnectionLostException e) { enableUi(false); throw e; } } } @Override protected IOIOLooper createIOIOLooper() { return new Looper(); } private void enableUi(final boolean enable) { runOnUiThread(new Runnable() { @Override public void run() { } }); } }); } }
En el archivo activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:max="100" android:progress="25" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageButton android:id="@+id/imageButton1" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/flechaarriba" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageButton android:id="@+id/imageButton2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.28" android:src="@drawable/flechaizquierda" /> <ImageButton android:id="@+id/imageButton3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.28" android:src="@drawable/flechaderecha" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageButton android:id="@+id/imageButton4" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/flechaabajo" /> </LinearLayout> </LinearLayout>