In this project we are going to make a robot based on the well-known Robot-BOB but with some modifications to adapt it to the mioio + shield mioiobot ..
Vamos a necesitar:
PCB MIOIO
Shield MIOIOBOT
MOIOIOBOB parts in format STL
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
You will also need:
1 bluetooth usb
4 mini servos S9
1 Ultrasonic HC-SR04
2 AAA battery holder (Although 1 would suffice)
This program has been developed in Eclipse, you can download it directly compiled from here.
The code comes next.
What the program does is basically control MIOIOBOB in the directions indicated by the fecla, and also, making use of the ultrasound, we will indicate to what distance it must go back.
With the SeekBar we will determine the speed at which we want the robot to move.
Let's design the activity_main.xml.
For this example we have used:
- Four ImageButton, to indicate movement.
- A Progressbar, to indicate the speed at which we want it to work.
In the MainActivity.java file we have this:
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>