Things used in this project

Hardware components:
Ard nano
Arduino Nano R3
×1
12577 01
SparkFun Bluetooth Modem - BlueSMiRF Silver
×1
09670 01
SparkFun Dual H-Bridge motor drivers L298
×1
DC motor (generic)
×2
Gus 1719
C.H.I.P. Approved 3.7 V LiPo Battery
Really, a 4S lipo battery.
×4

Schematics

ArduinoSchematic
Connect your Arduino to the Dual Bridge motor controller and to the bluetooth module.
Dc motor schematics warbodwjjf
How it walks
How to assemble the Lego bricks and gears in order to create that silly walk. Each motor drives 4 legs.
15875347 10155030129953804 5592007884128493841 o cci6kutoag
Inner gears.
The gear in the middle is the one driving the four other gears of the left side (same thing goes on the right side). to connect it to the motor, I had to cut a bit of the piece and glue it to the motor shaft. Then, you connect the legs to the gears, asynchronously (each on a gear hole) and tadam: silly walk.
Img 20170121 144513796 yzfru3nepb

Code

Nano CodeArduino
Upload it to the Nano, it reads the Android orders incomming by bluetooth.
//ARDUINO Hiro NANO

//RXD to TXO (white)
//TXD to RXO (black)  BT adapter

// motor one
int enA = 11; //gris
int in1 = 10; // bleu
int in2 = 9; //vert
// motor two
int enB = 3; // violet
int in3 = 6; // jaune
int in4 = 5; // orange


char command;
String btdata;
int power;
int dir;
// Variables for the duration and the distance
long duration;
int distance;

void setup() {  
 
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(57600); 
  Serial.print("#ihihuuho");
  //MotorsForward();
}


void loop()
{  
  if (Serial.available() > 0)
  {
  }
  while (Serial.available() > 0)
  { command = (Serial.read());
    //Serial.println(" cmdd ");
    //Serial.println(command);

    
    //Serial.println("str: " + btdata);
    if (command == '?')
    {
      //Serial.println();
      //Serial.println("Command: " + btdata);

      delay(1);

     if (btdata.indexOf("forw") >= 0){
        MotorsForward(255);
        }
     if (btdata.indexOf("back") >= 0){
        MotorsBackward(255);
        }
      else{
        Serial.println("Command not recognized: " + btdata);
      }
      

      btdata = "";
      }
    else if (command == '/')
    {
      //Serial.println();
      //Serial.println("Direction: " + btdata);
      dir = btdata.toInt();
      btdata = "";
    }
    else if (command == '%')
    {
      //Serial.println();
      Serial.println("Power: " + btdata);
      power = btdata.toInt();
      btdata = "";
      if ( dir == 1 && power>0) {
        MotorsForward(power);
      }
      else if ( dir == 5 && power>0) {
        MotorsBackward(power);
      }
      else if ( dir == 7 && power>0) {
        MotorsSpinR(power);
      }
      else if ( dir == 3 && power>0) {
        MotorsSpinL(power);
      }
      else if ( dir == 8 && power>0) {
        MotorsFR(power);
      }
      else if ( dir == 2 && power>0) {
        MotorsFL(power);
      }
      else if ( dir == 4 && power>0) {
        MotorsBL(power);
      }
      else if ( dir == 6 && power>0) {
        MotorsBR(power);
      }
      else{
        MotorsStop();
      }
    }
    else{
      btdata = btdata + command;
    }

    
   }
   delay(500);
 }

void LedBlue()
{
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  //delay(1000);                       // wait for a second
}

void LedRed()
{
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED on (HIGH is the voltage level)
}


void MotorsBackward(int powa)
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enA, powa);
  analogWrite(enB, powa);
  
}

void MotorsForward(int powa)
{
  // Serial.println("Forward!");

  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enA, powa);
  analogWrite(enB, powa);
 
}

void MotorsSpinR(int powa)
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enA, powa);
  analogWrite(enB, powa);
  
}
void MotorsSpinL(int powa)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enA, powa);
  analogWrite(enB, powa);
  
}
void MotorsFL(int powa)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enA, powa);  
}
void MotorsFR(int powa)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, powa);  
}
void MotorsBR(int powa)
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enA, powa);  
}
void MotorsBL(int powa)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, powa);  
}

void MotorsStop()
{
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}
AndroidcodeJava
This is the core of the Android application. It uses a virtual Joystick library (zerokol's JoystickView).
package com.pj.hiro.hiro_control;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.zerokol.views.JoystickView;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;


public class MainActivity extends AppCompatActivity {

    //BT
    private final String DEVICE_ADDRESS="Your BT module Mac Adress";
    private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");//Serial Port Service ID
    private BluetoothDevice device;
    private BluetoothSocket socket;
    private OutputStream outputStream;
    private InputStream inputStream;
    Button startButton, sendButton,clearButton,stopButton;
    TextView textView;
    EditText editText;
    LinearLayout joystickLayout;
    RelativeLayout bluetoothLayout;
    boolean deviceConnected=false;
    Thread thread;
    FloatingActionButton fab;
    byte buffer[];
    int bufferPosition;
    boolean stopThread;
    //___

    private TextView angleTextView;
    private TextView powerTextView;
    private TextView directionTextView;
    // Importing also other views
    private JoystickView joystick;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startButton = (Button) findViewById(R.id.buttonStart);
        sendButton = (Button) findViewById(R.id.buttonSend);
        clearButton = (Button) findViewById(R.id.buttonClear);
        stopButton = (Button) findViewById(R.id.buttonStop);
        editText = (EditText) findViewById(R.id.editText);
        textView = (TextView) findViewById(R.id.textView);
        bluetoothLayout = (RelativeLayout) findViewById(R.id.BluetoothLayout);
        joystickLayout = (LinearLayout) findViewById(R.id.JoyStickLayout);
        fab = (FloatingActionButton) findViewById(R.id.hider);
        setUiEnabled(false);



        // Set window fullscreen and remove title bar, and force landscape orientation
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);




        angleTextView = (TextView) findViewById(R.id.angleTextView);
        powerTextView = (TextView) findViewById(R.id.powerTextView);
        directionTextView = (TextView) findViewById(R.id.directionTextView);
        //Referencing also other views
        joystick = (JoystickView) findViewById(R.id.joystickView);

        joystick.setOnJoystickMoveListener(new JoystickView.OnJoystickMoveListener() {

            @Override
            public void onValueChanged(int angle, int power, int direction) {
                // TODO Auto-generated method stub
                angleTextView.setText(" " + String.valueOf(angle) + "°");
                powerTextView.setText(" " + String.valueOf(power) + "%");
                if(outputStream != null) {
                    try {
                        outputStream.write((String.valueOf(direction) + "/" + String.valueOf(Math.round(power * 2.5)) + "%").getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                switch (direction) {
                    case JoystickView.FRONT:
                        directionTextView.setText("front_lab" + " " + direction);
                        break;
                    case JoystickView.FRONT_RIGHT:
                        directionTextView.setText("front_right_lab" + " " + direction);
                        break;
                    case JoystickView.RIGHT:
                        directionTextView.setText("right_lab" + " " + direction);
                        break;
                    case JoystickView.RIGHT_BOTTOM:
                        directionTextView.setText("right_bottom_lab" + " " + direction);
                        break;
                    case JoystickView.BOTTOM:
                        directionTextView.setText("bottom_lab" + " " + direction);
                        break;
                    case JoystickView.BOTTOM_LEFT:
                        directionTextView.setText("bottom_left_lab" + " " + direction);
                        break;
                    case JoystickView.LEFT:
                        directionTextView.setText("left_lab" + " " + direction);
                        break;
                    case JoystickView.LEFT_FRONT:
                        directionTextView.setText("left_front_lab" + " " + direction);
                        break;
                    default:
                        directionTextView.setText("center_lab" + " " + direction);
                }

                int polaR = 0;
                int polaL = 0;
                int thrustR = 0;
                int thrustL = 0;

            }
        }, JoystickView.DEFAULT_LOOP_INTERVAL);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(bluetoothLayout.getVisibility()==View.GONE){
                    bluetoothLayout.setVisibility(View.VISIBLE);
                }
                else{
                    bluetoothLayout.setVisibility(View.GONE);
                }
            }
        });

        joystickLayout.setVisibility(View.GONE);


    }

    public void setUiEnabled(boolean bool)
    {
        startButton.setEnabled(!bool);
        sendButton.setEnabled(bool);
        stopButton.setEnabled(bool);
        textView.setEnabled(bool);

    }

    public boolean BTinit()
    {
        boolean found=false;
        BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Toast.makeText(getApplicationContext(),"Device doesnt Support Bluetooth",Toast.LENGTH_SHORT).show();
        }
        if(!bluetoothAdapter.isEnabled())
        {
            Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableAdapter, 0);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
        if(bondedDevices.isEmpty())
        {
            Toast.makeText(getApplicationContext(),"Please Pair the Device first",Toast.LENGTH_SHORT).show();
        }
        else
        {
            for (BluetoothDevice iterator : bondedDevices)
            {
                if(iterator.getAddress().equals(DEVICE_ADDRESS))
                {
                    device=iterator;
                    found=true;
                    break;
                }
            }
        }
        return found;
    }

    public boolean BTconnect()
    {
        boolean connected=true;
        try {
            socket = device.createRfcommSocketToServiceRecord(PORT_UUID);
            socket.connect();
        } catch (IOException e) {
            e.printStackTrace();
            connected=false;
        }
        if(connected)
        {
            try {
                outputStream=socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStream=socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }


        return connected;
    }

    public void onClickStart(View view) {
        if(BTinit())
        {
            if(BTconnect())
            {
                setUiEnabled(true);
                deviceConnected=true;
                beginListenForData();
                textView.append("\nConnection Opened!\n");
                if(joystickLayout.getVisibility()==View.GONE){
                    joystickLayout.setVisibility(View.VISIBLE);
                }
            }

        }
    }

    void beginListenForData()
    {
        final Handler handler = new Handler();
        stopThread = false;
        buffer = new byte[1024];
        Thread thread  = new Thread(new Runnable()
        {
            public void run()
            {
                while(!Thread.currentThread().isInterrupted() && !stopThread)
                {
                    try
                    {
                        int byteCount = inputStream.available();
                        if(byteCount > 0)
                        {
                            byte[] rawBytes = new byte[byteCount];
                            inputStream.read(rawBytes);
                            final String string=new String(rawBytes,"UTF-8");
                            handler.post(new Runnable() {
                                public void run()
                                {
                                    textView.append(string);
                                    Toast.makeText(getApplicationContext(), "Reçu" + string, Toast.LENGTH_SHORT).show();
                                }
                            });

                        }
                    }
                    catch (IOException ex)
                    {
                        stopThread = true;
                    }
                }
            }
        });

        thread.start();
    }

    public void onClickSend(View view) {
        String string = editText.getText().toString() + "?";
        try {
            outputStream.write(string.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        textView.append("\nSent Data:"+string+"\n");

    }

    public void onClickStop(View view) throws IOException {
        stopThread = true;
        outputStream.close();
        inputStream.close();
        socket.close();
        setUiEnabled(false);
        deviceConnected=false;
        textView.append("\nConnection Closed!\n");
        if(joystickLayout.getVisibility()==View.VISIBLE){
            joystickLayout.setVisibility(View.GONE);
        }
    }

    public void onClickClear(View view) {
        textView.setText("");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Garden sensors dashboard
Intermediate
  • 10
  • 0

Full instructions

Monitor your greenhouse or personal garden environmental variables at a glance with a Linkit enabled sensor Hub.

Smart Cap
Intermediate
  • 1,309
  • 8

Full instructions

Good vision is a precious gift but unfortunately loss of vision is becoming common now-a-days. Smart cap can help with navigation.

Make an "Air" Drum Kit with Curie Nano
Intermediate
  • 58
  • 0

Full instructions

Enjoy playing drums anytime anywhere without worrying about making noise or disturbing others - just attach Curie to your drum sticks!

Find Me
Intermediate
  • 236
  • 0

Full instructions

Tired of losing your keys, wallet and phone? Attach the Find Me to any item and use the app to locate it in seconds.

C.H.I.P.py Ruxpin ʕ•ᴥ•ʔ
Intermediate
  • 44,118
  • 68

Full instructions

Bring Teddy Ruxpin back to life, but on your own terms! Make him say whatever you want, or have him search twitter to read tweets!

Otto DIY +
Intermediate
  • 4,076
  • 38

Work in progress

"Otto DIY with steroids" + Bluetooth + APP + switch + sensors + strength +...

Otto DIY +

Team Otto builders

Add projectSign up / Login
Respect project