Components and supplies
4S lipo battery
DC motor (generic)
Dual H-Bridge motor drivers L298
SparkFun Bluetooth Modem - BlueSMiRF Silver
Arduino Nano R3
Project description
Code
Androidcode
java
This is the core of the Android application. It uses a virtual Joystick library (zerokol's JoystickView).
1package com.pj.hiro.hiro_control; 2 3import android.bluetooth.BluetoothAdapter; 4import android.bluetooth.BluetoothDevice; 5import android.bluetooth.BluetoothSocket; 6import android.content.Intent; 7import android.content.pm.ActivityInfo; 8import android.os.Bundle; 9import android.os.Handler; 10import android.widget.Button; 11import android.widget.EditText; 12import android.widget.LinearLayout; 13import android.widget.RelativeLayout; 14import android.widget.TextView; 15import android.support.design.widget.FloatingActionButton; 16import android.support.design.widget.Snackbar; 17import android.support.v7.app.AppCompatActivity; 18import android.support.v7.widget.Toolbar; 19import android.view.View; 20import android.view.Menu; 21import android.view.MenuItem; 22import android.widget.Toast; 23 24import com.zerokol.views.JoystickView; 25 26import java.io.IOException; 27import java.io.InputStream; 28import java.io.OutputStream; 29import java.util.Set; 30import java.util.UUID; 31 32 33public class MainActivity extends AppCompatActivity { 34 35 //BT 36 private final String DEVICE_ADDRESS="Your BT module Mac Adress"; 37 private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");//Serial Port Service ID 38 private BluetoothDevice device; 39 private BluetoothSocket socket; 40 private OutputStream outputStream; 41 private InputStream inputStream; 42 Button startButton, sendButton,clearButton,stopButton; 43 TextView textView; 44 EditText editText; 45 LinearLayout joystickLayout; 46 RelativeLayout bluetoothLayout; 47 boolean deviceConnected=false; 48 Thread thread; 49 FloatingActionButton fab; 50 byte buffer[]; 51 int bufferPosition; 52 boolean stopThread; 53 //___ 54 55 private TextView angleTextView; 56 private TextView powerTextView; 57 private TextView directionTextView; 58 // Importing also other views 59 private JoystickView joystick; 60 61 @Override 62 protected void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 setContentView(R.layout.activity_main); 65 startButton = (Button) findViewById(R.id.buttonStart); 66 sendButton = (Button) findViewById(R.id.buttonSend); 67 clearButton = (Button) findViewById(R.id.buttonClear); 68 stopButton = (Button) findViewById(R.id.buttonStop); 69 editText = (EditText) findViewById(R.id.editText); 70 textView = (TextView) findViewById(R.id.textView); 71 bluetoothLayout = (RelativeLayout) findViewById(R.id.BluetoothLayout); 72 joystickLayout = (LinearLayout) findViewById(R.id.JoyStickLayout); 73 fab = (FloatingActionButton) findViewById(R.id.hider); 74 setUiEnabled(false); 75 76 77 78 // Set window fullscreen and remove title bar, and force landscape orientation 79 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 80 81 82 83 84 angleTextView = (TextView) findViewById(R.id.angleTextView); 85 powerTextView = (TextView) findViewById(R.id.powerTextView); 86 directionTextView = (TextView) findViewById(R.id.directionTextView); 87 //Referencing also other views 88 joystick = (JoystickView) findViewById(R.id.joystickView); 89 90 joystick.setOnJoystickMoveListener(new JoystickView.OnJoystickMoveListener() { 91 92 @Override 93 public void onValueChanged(int angle, int power, int direction) { 94 // TODO Auto-generated method stub 95 angleTextView.setText(" " + String.valueOf(angle) + "°"); 96 powerTextView.setText(" " + String.valueOf(power) + "%"); 97 if(outputStream != null) { 98 try { 99 outputStream.write((String.valueOf(direction) + "/" + String.valueOf(Math.round(power * 2.5)) + "%").getBytes()); 100 } catch (IOException e) { 101 e.printStackTrace(); 102 } 103 } 104 switch (direction) { 105 case JoystickView.FRONT: 106 directionTextView.setText("front_lab" + " " + direction); 107 break; 108 case JoystickView.FRONT_RIGHT: 109 directionTextView.setText("front_right_lab" + " " + direction); 110 break; 111 case JoystickView.RIGHT: 112 directionTextView.setText("right_lab" + " " + direction); 113 break; 114 case JoystickView.RIGHT_BOTTOM: 115 directionTextView.setText("right_bottom_lab" + " " + direction); 116 break; 117 case JoystickView.BOTTOM: 118 directionTextView.setText("bottom_lab" + " " + direction); 119 break; 120 case JoystickView.BOTTOM_LEFT: 121 directionTextView.setText("bottom_left_lab" + " " + direction); 122 break; 123 case JoystickView.LEFT: 124 directionTextView.setText("left_lab" + " " + direction); 125 break; 126 case JoystickView.LEFT_FRONT: 127 directionTextView.setText("left_front_lab" + " " + direction); 128 break; 129 default: 130 directionTextView.setText("center_lab" + " " + direction); 131 } 132 133 int polaR = 0; 134 int polaL = 0; 135 int thrustR = 0; 136 int thrustL = 0; 137 138 } 139 }, JoystickView.DEFAULT_LOOP_INTERVAL); 140 141 fab.setOnClickListener(new View.OnClickListener() { 142 @Override 143 public void onClick(View view) { 144 if(bluetoothLayout.getVisibility()==View.GONE){ 145 bluetoothLayout.setVisibility(View.VISIBLE); 146 } 147 else{ 148 bluetoothLayout.setVisibility(View.GONE); 149 } 150 } 151 }); 152 153 joystickLayout.setVisibility(View.GONE); 154 155 156 } 157 158 public void setUiEnabled(boolean bool) 159 { 160 startButton.setEnabled(!bool); 161 sendButton.setEnabled(bool); 162 stopButton.setEnabled(bool); 163 textView.setEnabled(bool); 164 165 } 166 167 public boolean BTinit() 168 { 169 boolean found=false; 170 BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter(); 171 if (bluetoothAdapter == null) { 172 Toast.makeText(getApplicationContext(),"Device doesnt Support Bluetooth",Toast.LENGTH_SHORT).show(); 173 } 174 if(!bluetoothAdapter.isEnabled()) 175 { 176 Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 177 startActivityForResult(enableAdapter, 0); 178 try { 179 Thread.sleep(1000); 180 } catch (InterruptedException e) { 181 e.printStackTrace(); 182 } 183 } 184 Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); 185 if(bondedDevices.isEmpty()) 186 { 187 Toast.makeText(getApplicationContext(),"Please Pair the Device first",Toast.LENGTH_SHORT).show(); 188 } 189 else 190 { 191 for (BluetoothDevice iterator : bondedDevices) 192 { 193 if(iterator.getAddress().equals(DEVICE_ADDRESS)) 194 { 195 device=iterator; 196 found=true; 197 break; 198 } 199 } 200 } 201 return found; 202 } 203 204 public boolean BTconnect() 205 { 206 boolean connected=true; 207 try { 208 socket = device.createRfcommSocketToServiceRecord(PORT_UUID); 209 socket.connect(); 210 } catch (IOException e) { 211 e.printStackTrace(); 212 connected=false; 213 } 214 if(connected) 215 { 216 try { 217 outputStream=socket.getOutputStream(); 218 } catch (IOException e) { 219 e.printStackTrace(); 220 } 221 try { 222 inputStream=socket.getInputStream(); 223 } catch (IOException e) { 224 e.printStackTrace(); 225 } 226 227 } 228 229 230 return connected; 231 } 232 233 public void onClickStart(View view) { 234 if(BTinit()) 235 { 236 if(BTconnect()) 237 { 238 setUiEnabled(true); 239 deviceConnected=true; 240 beginListenForData(); 241 textView.append("\ 242Connection Opened!\ 243"); 244 if(joystickLayout.getVisibility()==View.GONE){ 245 joystickLayout.setVisibility(View.VISIBLE); 246 } 247 } 248 249 } 250 } 251 252 void beginListenForData() 253 { 254 final Handler handler = new Handler(); 255 stopThread = false; 256 buffer = new byte[1024]; 257 Thread thread = new Thread(new Runnable() 258 { 259 public void run() 260 { 261 while(!Thread.currentThread().isInterrupted() && !stopThread) 262 { 263 try 264 { 265 int byteCount = inputStream.available(); 266 if(byteCount > 0) 267 { 268 byte[] rawBytes = new byte[byteCount]; 269 inputStream.read(rawBytes); 270 final String string=new String(rawBytes,"UTF-8"); 271 handler.post(new Runnable() { 272 public void run() 273 { 274 textView.append(string); 275 Toast.makeText(getApplicationContext(), "Reçu" + string, Toast.LENGTH_SHORT).show(); 276 } 277 }); 278 279 } 280 } 281 catch (IOException ex) 282 { 283 stopThread = true; 284 } 285 } 286 } 287 }); 288 289 thread.start(); 290 } 291 292 public void onClickSend(View view) { 293 String string = editText.getText().toString() + "?"; 294 try { 295 outputStream.write(string.getBytes()); 296 } catch (IOException e) { 297 e.printStackTrace(); 298 } 299 textView.append("\ 300Sent Data:"+string+"\ 301"); 302 303 } 304 305 public void onClickStop(View view) throws IOException { 306 stopThread = true; 307 outputStream.close(); 308 inputStream.close(); 309 socket.close(); 310 setUiEnabled(false); 311 deviceConnected=false; 312 textView.append("\ 313Connection Closed!\ 314"); 315 if(joystickLayout.getVisibility()==View.VISIBLE){ 316 joystickLayout.setVisibility(View.GONE); 317 } 318 } 319 320 public void onClickClear(View view) { 321 textView.setText(""); 322 } 323 324 @Override 325 public boolean onCreateOptionsMenu(Menu menu) { 326 // Inflate the menu; this adds items to the action bar if it is present. 327 getMenuInflater().inflate(R.menu.menu_main, menu); 328 return true; 329 } 330 331 @Override 332 public boolean onOptionsItemSelected(MenuItem item) { 333 // Handle action bar item clicks here. The action bar will 334 // automatically handle clicks on the Home/Up button, so long 335 // as you specify a parent activity in AndroidManifest.xml. 336 int id = item.getItemId(); 337 338 //noinspection SimplifiableIfStatement 339 if (id == R.id.action_settings) { 340 return true; 341 } 342 343 return super.onOptionsItemSelected(item); 344 } 345 346 /** 347 * A native method that is implemented by the 'native-lib' native library, 348 * which is packaged with this application. 349 */ 350 public native String stringFromJNI(); 351 352 // Used to load the 'native-lib' library on application startup. 353 static { 354 System.loadLibrary("native-lib"); 355 } 356} 357
Nano Code
arduino
Upload it to the Nano, it reads the Android orders incomming by bluetooth.
1//ARDUINO Hiro NANO 2 3//RXD to TXO (white) 4//TXD to RXO (black) BT adapter 5 6// motor one 7int enA = 11; //gris 8int in1 = 10; // bleu 9int in2 = 9; //vert 10// motor two 11int enB = 3; // violet 12int in3 = 6; // jaune 13int in4 = 5; // orange 14 15 16char command; 17String btdata; 18int power; 19int dir; 20// Variables for the duration and the distance 21long duration; 22int distance; 23 24void setup() { 25 26 pinMode(enA, OUTPUT); 27 pinMode(enB, OUTPUT); 28 pinMode(in1, OUTPUT); 29 pinMode(in2, OUTPUT); 30 pinMode(in3, OUTPUT); 31 pinMode(in4, OUTPUT); 32 pinMode(LED_BUILTIN, OUTPUT); 33 34 Serial.begin(57600); 35 Serial.print("#ihihuuho"); 36 //MotorsForward(); 37} 38 39 40void loop() 41{ 42 if (Serial.available() > 0) 43 { 44 } 45 while (Serial.available() > 0) 46 { command = (Serial.read()); 47 //Serial.println(" cmdd "); 48 //Serial.println(command); 49 50 51 //Serial.println("str: " + btdata); 52 if (command == '?') 53 { 54 //Serial.println(); 55 //Serial.println("Command: " + btdata); 56 57 delay(1); 58 59 if (btdata.indexOf("forw") >= 0){ 60 MotorsForward(255); 61 } 62 if (btdata.indexOf("back") >= 0){ 63 MotorsBackward(255); 64 } 65 else{ 66 Serial.println("Command not recognized: " + btdata); 67 } 68 69 70 btdata = ""; 71 } 72 else if (command == '/') 73 { 74 //Serial.println(); 75 //Serial.println("Direction: " + btdata); 76 dir = btdata.toInt(); 77 btdata = ""; 78 } 79 else if (command == '%') 80 { 81 //Serial.println(); 82 Serial.println("Power: " + btdata); 83 power = btdata.toInt(); 84 btdata = ""; 85 if ( dir == 1 && power>0) { 86 MotorsForward(power); 87 } 88 else if ( dir == 5 && power>0) { 89 MotorsBackward(power); 90 } 91 else if ( dir == 7 && power>0) { 92 MotorsSpinR(power); 93 } 94 else if ( dir == 3 && power>0) { 95 MotorsSpinL(power); 96 } 97 else if ( dir == 8 && power>0) { 98 MotorsFR(power); 99 } 100 else if ( dir == 2 && power>0) { 101 MotorsFL(power); 102 } 103 else if ( dir == 4 && power>0) { 104 MotorsBL(power); 105 } 106 else if ( dir == 6 && power>0) { 107 MotorsBR(power); 108 } 109 else{ 110 MotorsStop(); 111 } 112 } 113 else{ 114 btdata = btdata + command; 115 } 116 117 118 } 119 delay(500); 120 } 121 122void LedBlue() 123{ 124 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) 125 //delay(1000); // wait for a second 126} 127 128void LedRed() 129{ 130 digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level) 131} 132 133 134void MotorsBackward(int powa) 135{ 136 digitalWrite(in1, HIGH); 137 digitalWrite(in2, LOW); 138 digitalWrite(in3, HIGH); 139 digitalWrite(in4, LOW); 140 analogWrite(enA, powa); 141 analogWrite(enB, powa); 142 143} 144 145void MotorsForward(int powa) 146{ 147 // Serial.println("Forward!"); 148 149 digitalWrite(in1, LOW); 150 digitalWrite(in2, HIGH); 151 digitalWrite(in3, LOW); 152 digitalWrite(in4, HIGH); 153 analogWrite(enA, powa); 154 analogWrite(enB, powa); 155 156} 157 158void MotorsSpinR(int powa) 159{ 160 digitalWrite(in1, HIGH); 161 digitalWrite(in2, LOW); 162 digitalWrite(in3, LOW); 163 digitalWrite(in4, HIGH); 164 analogWrite(enA, powa); 165 analogWrite(enB, powa); 166 167} 168void MotorsSpinL(int powa) 169{ 170 digitalWrite(in1, LOW); 171 digitalWrite(in2, HIGH); 172 digitalWrite(in3, HIGH); 173 digitalWrite(in4, LOW); 174 analogWrite(enA, powa); 175 analogWrite(enB, powa); 176 177} 178void MotorsFL(int powa) 179{ 180 digitalWrite(in1, LOW); 181 digitalWrite(in2, HIGH); 182 digitalWrite(in3, LOW); 183 digitalWrite(in4, LOW); 184 analogWrite(enA, powa); 185} 186void MotorsFR(int powa) 187{ 188 digitalWrite(in1, LOW); 189 digitalWrite(in2, LOW); 190 digitalWrite(in3, LOW); 191 digitalWrite(in4, HIGH); 192 analogWrite(enB, powa); 193} 194void MotorsBR(int powa) 195{ 196 digitalWrite(in1, HIGH); 197 digitalWrite(in2, LOW); 198 digitalWrite(in3, LOW); 199 digitalWrite(in4, LOW); 200 analogWrite(enA, powa); 201} 202void MotorsBL(int powa) 203{ 204 digitalWrite(in1, LOW); 205 digitalWrite(in2, LOW); 206 digitalWrite(in3, HIGH); 207 digitalWrite(in4, LOW); 208 analogWrite(enB, powa); 209} 210 211void MotorsStop() 212{ 213 // now turn off motors 214 digitalWrite(in1, LOW); 215 digitalWrite(in2, LOW); 216 digitalWrite(in3, LOW); 217 digitalWrite(in4, LOW); 218} 219 220 221
Androidcode
java
This is the core of the Android application. It uses a virtual Joystick library (zerokol's JoystickView).
1package com.pj.hiro.hiro_control; 2 3import android.bluetooth.BluetoothAdapter; 4import 5 android.bluetooth.BluetoothDevice; 6import android.bluetooth.BluetoothSocket; 7import 8 android.content.Intent; 9import android.content.pm.ActivityInfo; 10import android.os.Bundle; 11import 12 android.os.Handler; 13import android.widget.Button; 14import android.widget.EditText; 15import 16 android.widget.LinearLayout; 17import android.widget.RelativeLayout; 18import 19 android.widget.TextView; 20import android.support.design.widget.FloatingActionButton; 21import 22 android.support.design.widget.Snackbar; 23import android.support.v7.app.AppCompatActivity; 24import 25 android.support.v7.widget.Toolbar; 26import android.view.View; 27import android.view.Menu; 28import 29 android.view.MenuItem; 30import android.widget.Toast; 31 32import com.zerokol.views.JoystickView; 33 34import 35 java.io.IOException; 36import java.io.InputStream; 37import java.io.OutputStream; 38import 39 java.util.Set; 40import java.util.UUID; 41 42 43public class MainActivity extends 44 AppCompatActivity { 45 46 //BT 47 private final String DEVICE_ADDRESS="Your 48 BT module Mac Adress"; 49 private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");//Serial 50 Port Service ID 51 private BluetoothDevice device; 52 private BluetoothSocket 53 socket; 54 private OutputStream outputStream; 55 private InputStream inputStream; 56 57 Button startButton, sendButton,clearButton,stopButton; 58 TextView textView; 59 60 EditText editText; 61 LinearLayout joystickLayout; 62 RelativeLayout 63 bluetoothLayout; 64 boolean deviceConnected=false; 65 Thread thread; 66 67 FloatingActionButton fab; 68 byte buffer[]; 69 int bufferPosition; 70 71 boolean stopThread; 72 //___ 73 74 private TextView angleTextView; 75 76 private TextView powerTextView; 77 private TextView directionTextView; 78 79 // Importing also other views 80 private JoystickView joystick; 81 82 83 @Override 84 protected void onCreate(Bundle savedInstanceState) { 85 super.onCreate(savedInstanceState); 86 87 setContentView(R.layout.activity_main); 88 startButton = (Button) 89 findViewById(R.id.buttonStart); 90 sendButton = (Button) findViewById(R.id.buttonSend); 91 92 clearButton = (Button) findViewById(R.id.buttonClear); 93 stopButton 94 = (Button) findViewById(R.id.buttonStop); 95 editText = (EditText) findViewById(R.id.editText); 96 97 textView = (TextView) findViewById(R.id.textView); 98 bluetoothLayout 99 = (RelativeLayout) findViewById(R.id.BluetoothLayout); 100 joystickLayout 101 = (LinearLayout) findViewById(R.id.JoyStickLayout); 102 fab = (FloatingActionButton) 103 findViewById(R.id.hider); 104 setUiEnabled(false); 105 106 107 108 // 109 Set window fullscreen and remove title bar, and force landscape orientation 110 111 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 112 113 114 115 116 117 angleTextView = (TextView) findViewById(R.id.angleTextView); 118 powerTextView 119 = (TextView) findViewById(R.id.powerTextView); 120 directionTextView = (TextView) 121 findViewById(R.id.directionTextView); 122 //Referencing also other views 123 124 joystick = (JoystickView) findViewById(R.id.joystickView); 125 126 joystick.setOnJoystickMoveListener(new 127 JoystickView.OnJoystickMoveListener() { 128 129 @Override 130 public 131 void onValueChanged(int angle, int power, int direction) { 132 // 133 TODO Auto-generated method stub 134 angleTextView.setText(" " + 135 String.valueOf(angle) + "°"); 136 powerTextView.setText(" " + 137 String.valueOf(power) + "%"); 138 if(outputStream != null) { 139 140 try { 141 outputStream.write((String.valueOf(direction) 142 + "/" + String.valueOf(Math.round(power * 2.5)) + "%").getBytes()); 143 } 144 catch (IOException e) { 145 e.printStackTrace(); 146 } 147 148 } 149 switch (direction) { 150 case 151 JoystickView.FRONT: 152 directionTextView.setText("front_lab" 153 + " " + direction); 154 break; 155 case 156 JoystickView.FRONT_RIGHT: 157 directionTextView.setText("front_right_lab" 158 + " " + direction); 159 break; 160 case 161 JoystickView.RIGHT: 162 directionTextView.setText("right_lab" 163 + " " + direction); 164 break; 165 case 166 JoystickView.RIGHT_BOTTOM: 167 directionTextView.setText("right_bottom_lab" 168 + " " + direction); 169 break; 170 case 171 JoystickView.BOTTOM: 172 directionTextView.setText("bottom_lab" 173 + " " + direction); 174 break; 175 case 176 JoystickView.BOTTOM_LEFT: 177 directionTextView.setText("bottom_left_lab" 178 + " " + direction); 179 break; 180 case 181 JoystickView.LEFT: 182 directionTextView.setText("left_lab" 183 + " " + direction); 184 break; 185 case 186 JoystickView.LEFT_FRONT: 187 directionTextView.setText("left_front_lab" 188 + " " + direction); 189 break; 190 default: 191 192 directionTextView.setText("center_lab" + " " + direction); 193 194 } 195 196 int polaR = 0; 197 int polaL 198 = 0; 199 int thrustR = 0; 200 int thrustL = 0; 201 202 203 } 204 }, JoystickView.DEFAULT_LOOP_INTERVAL); 205 206 fab.setOnClickListener(new 207 View.OnClickListener() { 208 @Override 209 public void onClick(View 210 view) { 211 if(bluetoothLayout.getVisibility()==View.GONE){ 212 bluetoothLayout.setVisibility(View.VISIBLE); 213 214 } 215 else{ 216 bluetoothLayout.setVisibility(View.GONE); 217 218 } 219 } 220 }); 221 222 joystickLayout.setVisibility(View.GONE); 223 224 225 226 } 227 228 public void setUiEnabled(boolean bool) 229 { 230 startButton.setEnabled(!bool); 231 232 sendButton.setEnabled(bool); 233 stopButton.setEnabled(bool); 234 235 textView.setEnabled(bool); 236 237 } 238 239 public boolean BTinit() 240 241 { 242 boolean found=false; 243 BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter(); 244 245 if (bluetoothAdapter == null) { 246 Toast.makeText(getApplicationContext(),"Device 247 doesnt Support Bluetooth",Toast.LENGTH_SHORT).show(); 248 } 249 if(!bluetoothAdapter.isEnabled()) 250 251 { 252 Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 253 254 startActivityForResult(enableAdapter, 0); 255 try { 256 Thread.sleep(1000); 257 258 } catch (InterruptedException e) { 259 e.printStackTrace(); 260 261 } 262 } 263 Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); 264 265 if(bondedDevices.isEmpty()) 266 { 267 Toast.makeText(getApplicationContext(),"Please 268 Pair the Device first",Toast.LENGTH_SHORT).show(); 269 } 270 else 271 272 { 273 for (BluetoothDevice iterator : bondedDevices) 274 { 275 276 if(iterator.getAddress().equals(DEVICE_ADDRESS)) 277 { 278 279 device=iterator; 280 found=true; 281 break; 282 283 } 284 } 285 } 286 return found; 287 } 288 289 290 public boolean BTconnect() 291 { 292 boolean connected=true; 293 try 294 { 295 socket = device.createRfcommSocketToServiceRecord(PORT_UUID); 296 297 socket.connect(); 298 } catch (IOException e) { 299 e.printStackTrace(); 300 301 connected=false; 302 } 303 if(connected) 304 { 305 306 try { 307 outputStream=socket.getOutputStream(); 308 309 } catch (IOException e) { 310 e.printStackTrace(); 311 312 } 313 try { 314 inputStream=socket.getInputStream(); 315 316 } catch (IOException e) { 317 e.printStackTrace(); 318 319 } 320 321 } 322 323 324 return connected; 325 } 326 327 328 public void onClickStart(View view) { 329 if(BTinit()) 330 { 331 332 if(BTconnect()) 333 { 334 setUiEnabled(true); 335 336 deviceConnected=true; 337 beginListenForData(); 338 339 textView.append("\ 340Connection Opened!\ 341"); 342 if(joystickLayout.getVisibility()==View.GONE){ 343 344 joystickLayout.setVisibility(View.VISIBLE); 345 } 346 347 } 348 349 } 350 } 351 352 void beginListenForData() 353 354 { 355 final Handler handler = new Handler(); 356 stopThread = 357 false; 358 buffer = new byte[1024]; 359 Thread thread = new Thread(new 360 Runnable() 361 { 362 public void run() 363 { 364 while(!Thread.currentThread().isInterrupted() 365 && !stopThread) 366 { 367 try 368 { 369 370 int byteCount = inputStream.available(); 371 if(byteCount 372 > 0) 373 { 374 byte[] rawBytes 375 = new byte[byteCount]; 376 inputStream.read(rawBytes); 377 378 final String string=new String(rawBytes,"UTF-8"); 379 380 handler.post(new Runnable() { 381 public 382 void run() 383 { 384 textView.append(string); 385 386 Toast.makeText(getApplicationContext(), "Reçu" 387 + string, Toast.LENGTH_SHORT).show(); 388 } 389 }); 390 391 392 } 393 } 394 catch 395 (IOException ex) 396 { 397 stopThread 398 = true; 399 } 400 } 401 } 402 }); 403 404 405 thread.start(); 406 } 407 408 public void onClickSend(View view) { 409 410 String string = editText.getText().toString() + "?"; 411 try { 412 413 outputStream.write(string.getBytes()); 414 } catch (IOException 415 e) { 416 e.printStackTrace(); 417 } 418 textView.append("\ 419Sent 420 Data:"+string+"\ 421"); 422 423 } 424 425 public void onClickStop(View view) 426 throws IOException { 427 stopThread = true; 428 outputStream.close(); 429 430 inputStream.close(); 431 socket.close(); 432 setUiEnabled(false); 433 434 deviceConnected=false; 435 textView.append("\ 436Connection Closed!\ 437"); 438 439 if(joystickLayout.getVisibility()==View.VISIBLE){ 440 joystickLayout.setVisibility(View.GONE); 441 442 } 443 } 444 445 public void onClickClear(View view) { 446 textView.setText(""); 447 448 } 449 450 @Override 451 public boolean onCreateOptionsMenu(Menu menu) 452 { 453 // Inflate the menu; this adds items to the action bar if it is present. 454 455 getMenuInflater().inflate(R.menu.menu_main, menu); 456 return true; 457 458 } 459 460 @Override 461 public boolean onOptionsItemSelected(MenuItem 462 item) { 463 // Handle action bar item clicks here. The action bar will 464 465 // automatically handle clicks on the Home/Up button, so long 466 // 467 as you specify a parent activity in AndroidManifest.xml. 468 int id = item.getItemId(); 469 470 471 //noinspection SimplifiableIfStatement 472 if (id == R.id.action_settings) 473 { 474 return true; 475 } 476 477 return super.onOptionsItemSelected(item); 478 479 } 480 481 /** 482 * A native method that is implemented by the 'native-lib' 483 native library, 484 * which is packaged with this application. 485 */ 486 487 public native String stringFromJNI(); 488 489 // Used to load the 'native-lib' 490 library on application startup. 491 static { 492 System.loadLibrary("native-lib"); 493 494 } 495} 496
Nano Code
arduino
Upload it to the Nano, it reads the Android orders incomming by bluetooth.
1//ARDUINO Hiro NANO 2 3//RXD to TXO (white) 4//TXD to RXO (black) BT adapter 5 6// motor one 7int enA = 11; //gris 8int in1 = 10; // bleu 9int in2 = 9; //vert 10// motor two 11int enB = 3; // violet 12int in3 = 6; // jaune 13int in4 = 5; // orange 14 15 16char command; 17String btdata; 18int power; 19int dir; 20// Variables for the duration and the distance 21long duration; 22int distance; 23 24void setup() { 25 26 pinMode(enA, OUTPUT); 27 pinMode(enB, OUTPUT); 28 pinMode(in1, OUTPUT); 29 pinMode(in2, OUTPUT); 30 pinMode(in3, OUTPUT); 31 pinMode(in4, OUTPUT); 32 pinMode(LED_BUILTIN, OUTPUT); 33 34 Serial.begin(57600); 35 Serial.print("#ihihuuho"); 36 //MotorsForward(); 37} 38 39 40void loop() 41{ 42 if (Serial.available() > 0) 43 { 44 } 45 while (Serial.available() > 0) 46 { command = (Serial.read()); 47 //Serial.println(" cmdd "); 48 //Serial.println(command); 49 50 51 //Serial.println("str: " + btdata); 52 if (command == '?') 53 { 54 //Serial.println(); 55 //Serial.println("Command: " + btdata); 56 57 delay(1); 58 59 if (btdata.indexOf("forw") >= 0){ 60 MotorsForward(255); 61 } 62 if (btdata.indexOf("back") >= 0){ 63 MotorsBackward(255); 64 } 65 else{ 66 Serial.println("Command not recognized: " + btdata); 67 } 68 69 70 btdata = ""; 71 } 72 else if (command == '/') 73 { 74 //Serial.println(); 75 //Serial.println("Direction: " + btdata); 76 dir = btdata.toInt(); 77 btdata = ""; 78 } 79 else if (command == '%') 80 { 81 //Serial.println(); 82 Serial.println("Power: " + btdata); 83 power = btdata.toInt(); 84 btdata = ""; 85 if ( dir == 1 && power>0) { 86 MotorsForward(power); 87 } 88 else if ( dir == 5 && power>0) { 89 MotorsBackward(power); 90 } 91 else if ( dir == 7 && power>0) { 92 MotorsSpinR(power); 93 } 94 else if ( dir == 3 && power>0) { 95 MotorsSpinL(power); 96 } 97 else if ( dir == 8 && power>0) { 98 MotorsFR(power); 99 } 100 else if ( dir == 2 && power>0) { 101 MotorsFL(power); 102 } 103 else if ( dir == 4 && power>0) { 104 MotorsBL(power); 105 } 106 else if ( dir == 6 && power>0) { 107 MotorsBR(power); 108 } 109 else{ 110 MotorsStop(); 111 } 112 } 113 else{ 114 btdata = btdata + command; 115 } 116 117 118 } 119 delay(500); 120 } 121 122void LedBlue() 123{ 124 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) 125 //delay(1000); // wait for a second 126} 127 128void LedRed() 129{ 130 digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level) 131} 132 133 134void MotorsBackward(int powa) 135{ 136 digitalWrite(in1, HIGH); 137 digitalWrite(in2, LOW); 138 digitalWrite(in3, HIGH); 139 digitalWrite(in4, LOW); 140 analogWrite(enA, powa); 141 analogWrite(enB, powa); 142 143} 144 145void MotorsForward(int powa) 146{ 147 // Serial.println("Forward!"); 148 149 digitalWrite(in1, LOW); 150 digitalWrite(in2, HIGH); 151 digitalWrite(in3, LOW); 152 digitalWrite(in4, HIGH); 153 analogWrite(enA, powa); 154 analogWrite(enB, powa); 155 156} 157 158void MotorsSpinR(int powa) 159{ 160 digitalWrite(in1, HIGH); 161 digitalWrite(in2, LOW); 162 digitalWrite(in3, LOW); 163 digitalWrite(in4, HIGH); 164 analogWrite(enA, powa); 165 analogWrite(enB, powa); 166 167} 168void MotorsSpinL(int powa) 169{ 170 digitalWrite(in1, LOW); 171 digitalWrite(in2, HIGH); 172 digitalWrite(in3, HIGH); 173 digitalWrite(in4, LOW); 174 analogWrite(enA, powa); 175 analogWrite(enB, powa); 176 177} 178void MotorsFL(int powa) 179{ 180 digitalWrite(in1, LOW); 181 digitalWrite(in2, HIGH); 182 digitalWrite(in3, LOW); 183 digitalWrite(in4, LOW); 184 analogWrite(enA, powa); 185} 186void MotorsFR(int powa) 187{ 188 digitalWrite(in1, LOW); 189 digitalWrite(in2, LOW); 190 digitalWrite(in3, LOW); 191 digitalWrite(in4, HIGH); 192 analogWrite(enB, powa); 193} 194void MotorsBR(int powa) 195{ 196 digitalWrite(in1, HIGH); 197 digitalWrite(in2, LOW); 198 digitalWrite(in3, LOW); 199 digitalWrite(in4, LOW); 200 analogWrite(enA, powa); 201} 202void MotorsBL(int powa) 203{ 204 digitalWrite(in1, LOW); 205 digitalWrite(in2, LOW); 206 digitalWrite(in3, HIGH); 207 digitalWrite(in4, LOW); 208 analogWrite(enB, powa); 209} 210 211void MotorsStop() 212{ 213 // now turn off motors 214 digitalWrite(in1, LOW); 215 digitalWrite(in2, LOW); 216 digitalWrite(in3, LOW); 217 digitalWrite(in4, LOW); 218} 219 220 221
Downloadable files
ArduinoSchematic
Connect your Arduino to the Dual Bridge motor controller and to the bluetooth module.
ArduinoSchematic
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.
Inner gears.
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.
Inner gears.
How it walks
How to assemble the Lego bricks and gears in order to create that silly walk. Each motor drives 4 legs.
How it walks
ArduinoSchematic
Connect your Arduino to the Dual Bridge motor controller and to the bluetooth module.
ArduinoSchematic
Comments
Only logged in users can leave comments