MIOIOBOT Coche

En este proyecto vamos a realizar un coche controlado por bluetooth desde el dispositivo Android. El entorno de programación en este caso es con Eclipse, debido a que soporta multitouch, y nos va a hacer falta para el tipo de Joystick que vamos a utilizar.

El Joystick para llevar el coche van a ser dos palancas de control como las de los tanques, de este modo, si quieres también puedes hacer un vehículo oruga, o modificar alguno que tengas por casa y adaptarle la tarjeta  mioio + shield mioiobot.

Coche
Vamos a necesitar:
Tarjeta MIOIO
Shield MIOIOBOT
Piezas MOIOIOBOB en formato STL 

004Chasis 005Soporte electrónica
002Carrocería 003Puerta izquierda
006Puerta derecha

También nesesitarás:

1 bluetooth usb

4 motores y sus ruedas

1 portapilas AAA (Preferiblemente con interruptor).

Este programa se ha desarrollado en Eclipse, puedes descargarlo directamente compilado desde aquí.

Aplicacion Eclipse

Lo que hace el programa es básicamente controlar las salidas de los motores de la tarjeta MIOIOBot. Moviendo verticálmente los sticks lo que producirá será hacer girar más rápido o más lento los motores en cada uno de los sentidos.

El programa contendrá en esta ocasión dos clases. La primera es la que contendrá nuestra IOIOActivity (Main.java), y la segunda es la que se encargará de crear los Sticks (DrawCanvas.java) que utilizaremos para mover los motores.

Aplicacion Coche Eclipse 2

El código viene a continuación.

Vamos a diseñar el activity_main.xml.

Para este ejemplo se han utilizado:

  • Dos Layouts, uno a la izquierda y otro a la derecha, que contendrán los canvas que crearemos esta vez por código para realizar el control táctil sobre los mismos.

En el archivo activity_main.xml:

 <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="@drawable/logo_mioiobot" >

 <LinearLayout
 android:id="@+id/layoutLeft"
 android:layout_width="80dp"
 android:layout_height="280dp"
 android:layout_alignParentLeft="true"
 android:layout_centerVertical="true"
 android:layout_marginLeft="5dp"
 android:background="@drawable/controller_bg"
 android:orientation="horizontal" >

 </LinearLayout>

 <LinearLayout
 android:id="@+id/layoutRight"
 android:layout_width="80dp"
 android:layout_height="280dp"
 android:layout_alignParentRight="true"
 android:layout_centerVertical="true"
 android:layout_marginRight="5dp"
 android:background="@drawable/controller_bg"
 android:orientation="horizontal" >

 </LinearLayout>

</RelativeLayout>

En el archivo DrawCanvas.java:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

public class DrawCanvas extends View{
 float y;
 int width, height;
 Bitmap bitmap;
 int offset = 10;
 Paint mPaint = new Paint();
 
 public DrawCanvas(Context context, int width, int height) {
 super(context);
 this.width = width;
 this.height = height;

 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.stick);
 bitmap = Bitmap.createScaledBitmap(bitmap, this.width - (offset * 2)
 , this.width - (offset * 2), false);
 
 
 }
 
 public void onDraw(Canvas canvas) {
 float leftx = offset;
 float topy = offset;
 float rightx = 100+offset;
 float bottomy = this.getHeight();;
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setColor(Color.RED);
 mPaint.setStyle(Paint.Style.FILL);
 RectF ovalBounds = new RectF(leftx, topy, rightx, bottomy);
 canvas.drawOval(ovalBounds, mPaint);
 
 canvas.drawBitmap(bitmap, offset, y - (width / 2) + offset, mPaint);
 }
 
 public void setPosition(float y) {
 this.y = y;
 
 if(y < (width / 2)) 
 this.y = (width / 2);
 else if(y > height - (width / 2))
 this.y = height - (width / 2);
 }
 }

En el archivo Main.java tenemos esto:

import ioio.lib.api.AnalogInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.PulseInput;
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.os.Handler;
import android.graphics.PixelFormat;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.Toast;

public class Main extends IOIOActivity {
 LinearLayout layoutLeft, layoutRight;
 DrawCanvas drawLeft, drawRight;

 float dutyLeft, dutyRight;

 Handler handler;
 
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 getWindow().setFormat(PixelFormat.RGBA_8888);
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN 
 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
 setContentView(R.layout.main);
 
 layoutLeft = (LinearLayout)findViewById(R.id.layoutLeft);
 layoutRight = (LinearLayout)findViewById(R.id.layoutRight);
 
 }
 
 public void onPause() {
 super.onPause();
 finish();
 }
 
 public void onWindowFocusChanged(boolean hasFocus) {
 super.onWindowFocusChanged(hasFocus);
 
 drawRight = new DrawCanvas(Main.this
 , layoutRight.getWidth(), layoutRight.getHeight());
 
 drawRight.setPosition(drawRight.height / 2);
 draw(layoutRight, drawRight);
 
 drawLeft = new DrawCanvas(Main.this
 , layoutRight.getWidth(), layoutRight.getHeight());
 
 drawLeft.setPosition(drawLeft.height / 2);
 draw(layoutLeft, drawLeft);
 
 layoutRight.setOnTouchListener(new OnTouchListener() {
 float speed;
 public boolean onTouch(View arg0, MotionEvent arg1) {
 if(arg1.getAction() == MotionEvent.ACTION_DOWN 
 || arg1.getAction() == MotionEvent.ACTION_MOVE) {
 
 drawRight.setPosition(arg1.getY());
 draw(layoutRight, drawRight);
 
 speed = arg1.getY() - (drawRight.height / 2);
 
 if(speed > (drawRight.height / 2) - (drawRight.width / 2)) 
 speed = (drawRight.height / 2) - (drawRight.width / 2);
 else if(speed < -((drawRight.height / 2) - (drawRight.width / 2)))
 speed = -((drawRight.height / 2) - (drawRight.width / 2));
 
 speed = speed * 200 / (drawRight.height - drawRight.width);
 dutyRight = speed / 100;
 
 } else if(arg1.getAction() == MotionEvent.ACTION_UP) {

 speed = 0;
 dutyRight = 0;
 drawRight.setPosition(drawRight.height / 2);
 draw(layoutRight, drawRight);
 }
 
 return true;
 }
 });
 
 layoutLeft.setOnTouchListener(new OnTouchListener() {
 float speed;
 public boolean onTouch(View arg0, MotionEvent arg1) {
 if(arg1.getAction() == MotionEvent.ACTION_DOWN 
 || arg1.getAction() == MotionEvent.ACTION_MOVE) {
 
 drawLeft.setPosition(arg1.getY());
 draw(layoutLeft, drawLeft);

 speed = arg1.getY() - (drawLeft.height / 2);
 
 if(speed > (drawLeft.height / 2) - (drawLeft.width / 2)) 
 speed = (drawLeft.height / 2) - (drawLeft.width / 2);
 else if(speed < -((drawLeft.height / 2) - (drawLeft.width / 2)))
 speed = -((drawLeft.height / 2) - (drawLeft.width / 2));

 speed = speed * 200 / (drawLeft.height - drawLeft.width);
 dutyLeft = speed / 100;
 
 } else if(arg1.getAction() == MotionEvent.ACTION_UP) {

 speed = 0;
 dutyLeft = 0;
 drawLeft.setPosition(drawLeft.height / 2);
 draw(layoutLeft, drawLeft);
 }
 
 return true;
 }
 });
 }
 
 public void draw(LinearLayout layout, DrawCanvas draw) {
 try {
 layout.removeView(draw);
 } catch (Exception e) { }
 layout.addView(draw);
 }
 
 class Looper extends BaseIOIOLooper {
 
 PwmOutput PWM1, PWM2, PWM3, PWM4,PWM5,PWM6;
 private AnalogInput input_1;
 private AnalogInput input_2;
 /* ultrasonic sensor */
 private DigitalOutput triggerPin_;
 private PulseInput echoPin_;
 
 public void setup() throws ConnectionLostException {
 
 PWM1 = ioio_.openPwmOutput(38, 100);
 PWM1.setDutyCycle(0);
 PWM2 = ioio_.openPwmOutput(37, 100);
 PWM2.setDutyCycle(0);
 PWM3 = ioio_.openPwmOutput(39, 100);
 PWM3.setDutyCycle(0);
 PWM4 = ioio_.openPwmOutput(40, 100);
 PWM4.setDutyCycle(0);
 
 
 
 
 runOnUiThread(new Runnable() {
 public void run() {
 
 Toast.makeText(getApplicationContext(), 
 "Connected!", Toast.LENGTH_SHORT).show();
 } 
 });
 }
 
 public void loop() throws ConnectionLostException, InterruptedException { 
 
 //MODO MANUAL
 
 if(dutyLeft > 0) {
 PWM1.setDutyCycle(dutyLeft);
 PWM2.setDutyCycle(0);
 
 } else if(dutyLeft < 0) {
 PWM1.setDutyCycle(0);
 PWM2.setDutyCycle(Math.abs(dutyLeft));
 
 } else {
 PWM1.setDutyCycle(0);
 PWM2.setDutyCycle(0);
 
 }
 
 if(dutyRight > 0) {
 PWM3.setDutyCycle(dutyRight);
 PWM4.setDutyCycle(0);
 
 } else if(dutyRight < 0) {
 PWM3.setDutyCycle(0);
 PWM4.setDutyCycle(Math.abs(dutyRight));
 
 } else {
 PWM3.setDutyCycle(0);
 PWM4.setDutyCycle(0);
 
 }
 
 Thread.sleep(50);
 
 }
 }

 protected IOIOLooper createIOIOLooper() {
 return new Looper();
 }
 
 

}

 

Deja un comentario

Tu dirección de correo electrónico no será publicada.