Car MIOIOBOT

In this project we will make a car controlled by bluetooth from the Android device. The programming environment in this case is with Eclipse, because it supports multitouch, and we will need it for the type of Joystick that we are going to use.

The Joystick to carry the car will be two control levers like the tanks, so if you want you can also make a vehicle caterpillar, or modify one you have around the house and adapt the card mioio + shield mioiobot.

 

Coche
Vamos a necesitar:
PCB MIOIO
Shield MIOIOBOT
MOIOIOBOB parts in format STL 

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

You will also need:

1 bluetooth usb
4 engines and their wheels
1 AAA battery holder (preferably with switch).
This program has been developed in Eclipse, you can download it directly compiled from here.

 

Aplicacion Eclipse

What the program does is basically control the outputs of the motors of the MIOIOBot card. By vertically moving the sticks what will produce will be to turn the motors faster or slower in each of the senses.

The program will contain two classes. The first is the one that will contain our IOIOActivity (Main.java), and the second is the one that will be in charge of creating the Sticks (DrawCanvas.java) that we will use to move the motors.

 

Aplicacion Coche Eclipse 2

The code comes next.

Let's design the activity_main.xml.

For this example we have used:

  • Two Layouts, one to the left and one to the right, which will contain the canvas that we will create this time by code to perform the tactile control over them.

In the activity_main.xml file:

 <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>

In the DrawCanvas.java file:

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);
 }
 }

In the Main.java file we have this:

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();
 }
 
 

}

 

Leave a Reply

Your email address will not be published.