|
Braccio comandato |
|
Il braccio robot proposto da Daniele Giangravè è costruito con pezzi di legno rivestiti di carta colorata,
ed è dotato da 3 servomotori tipo HS-485HS
sono prodotti dalla HITEC. Questo braccio robotico ideato per avere un mezzo che possa muovere oggetti di vario tipo come per esempio metri ottici per effettuare misure o una telecamera che riprenda nella direzione desiderata senza che ci sia un addetto che fisicamente la sposti. Il tutto è mosso dal cellulare attraverso un applicazione per smartphone android creata con java per android che sfrutta la tecnologia bluetooth e touchscreen del cellulare rispettivamente per assegnare le coordinate ai motori trascinando il dito sullo schermo e per configurare il dispositivo con la scheda che gestisce il robot col vantaggio dunque di non avere l’intralcio dei fili da collegare. La scheda utilizzata è la IOIO OTG per Android, che è in grado di interfacciarsi con lo smarthphone attraverso l’applicazione “Robot” che all’interno contiene comandi per muovere ogni singolo asse di uno step aumentando così la precisione di movimento nel qual caso si voglia sostituire il puntatore laser con un metro ultrasuoni permettendo di effettuare misure molto precise. La scheda accenderà il led blu quando entrerà in collegamento con il cellulare.
|
Lo
IOIO-OTG (pronunciato "yo-yo-O-T-G") è una scheda di sviluppo
progettata da SeeedStudio e Sparkfun Electronics per aggiungere un
hardware con avanzate capacità I/O alle applicazione Android o PC Possiede un microcontrollore PIC che si
comporta come un ponte tra le app sul dispositivo PC o android alle
periferiche di basso livello come GPIO, PWM, ADC, I2C, SPI e UART. |
Documenti: |
I servocomandi
HS-485HS sono prodotti dalla HITEC e sono dei
servocomando standard, con
ingranaggi in carbonite, cuscinetto a sfere metallico, molto potente,
preciso ed economico
|
|
Listato dell'applicazine
import android.bluetooth.BluetoothAdapter; import android.content.Intent; import android.graphics.Point; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import ioio.lib.api.DigitalOutput; import ioio.lib.api.DigitalOutput.Spec.Mode; import ioio.lib.api.PwmOutput; import ioio.lib.api.exception.ConnectionLostException; import ioio.lib.api.exception.IncompatibilityException;
import
ioio.lib.util. import android.view.Display; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import android.widget.Toast;
public
class
MainActivity
extends
SensorEventListener { private static final int info = Menu.FIRST; BluetoothAdapter blue; Intent accendi; int limZ = 500; Button bt0; Button btX; Button btY; Button btZ; int width; int height; Button bt_laser;
ImageView img2; SeekBar sk1;
private SensorManager mSensorManager; float volt = 0; int x, y = 0; int posY = 1500, posX, posZ = 1000;
TextView tx6; boolean acceso = false; boolean laser_stat = false; boolean connesso = false; boolean mess_comparso = false;
int xyz = 0;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
tx6 = (TextView) findViewById(R.id.textView6);
bt0 = (Button) findViewById(R.id.bt_0); btX = (Button) findViewById(R.id.bt_X); btY = (Button) findViewById(R.id.bt_Y); btZ = (Button) findViewById(R.id.bt_Z); sk1 = (SeekBar) findViewById(R.id.seekBar1); bt_laser = (Button) findViewById(R.id.bt_laser); img2 = (ImageView) findViewById(R.id.imageView2);
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); width = size.x; height = size.y;
blue = BluetoothAdapter.getDefaultAdapter();
if (!blue.isEnabled()) { accendi = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivity(accendi);
}
if (blue.isEnabled()) Toast.makeText(MainActivity.this, "Bluetooth acceso", Toast.LENGTH_LONG).show();
sk1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
int progress = 0;
@Override public void onProgressChanged(SeekBar seekBar, int progresValue, boolean fromUser) { if (xyz == 0) { posX = progresValue;
} if (xyz == 1) {
if (progresValue <= 1350) {
if (posZ <= limZ + 100) posZ += 30; else posY = progresValue; } else posY = progresValue;
if (posY >= 2000) posY = 2000;
} if (xyz == 2) {
if (posY <= 1150) { if (progresValue >= limZ) posZ = progresValue; } else posZ = progresValue;
}
}
public void onStartTrackingTouch(SeekBar seekBar) { }
@Override public void onStopTrackingTouch(SeekBar seekBar) {
}
}); btX.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
xyz = 0; bt0.setBackgroundResource(R.drawable.blu2_settings); tx6.setText("X"); } });
btY.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
xyz = 1; bt0.setBackgroundResource(R.drawable.verde2_settings);
tx6.setText("Y"); } });
btZ.setOnClickListener(new OnClickListener() {
public void onClick(View v) { xyz = 2; bt0.setBackgroundResource(R.drawable.giallo_normal);
xyz = 2; tx6.setText("Z");
}
});
bt0.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (xyz == 0) posX = 10; if (xyz == 1) posY = 10; if (xyz == 2) posZ = 10;
} });
bt_laser.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (laser_stat == false) laser_stat = true; else laser_stat = false; if (laser_stat == true) bt_laser.setBackgroundResource(R.drawable.acceso_settings); else bt_laser.setBackgroundResource(R.drawable.arancione_settings);
} }); }
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
x = (int) event.values[1]; y = (int) event.values[2];
if (posY <= 1250) if (posY > 900) if (posZ <= limZ) while (posZ < limZ + 100) posZ += 30;
if (posY <= 1470) if (posY >= 1150) if (posZ <= 300) posZ += 50;
if (connesso == true) { img2.setImageResource(R.drawable.verde); if (mess_comparso == false) { Toast.makeText(MainActivity.this, "Scheda connessa", Toast.LENGTH_LONG).show(); mess_comparso = true; } } else img2.setImageResource(R.drawable.rosso); }
}
public boolean onTouchEvent(MotionEvent event) {
y = (int) event.getY(); x = (int) event.getX();
if ((height >= 880) && (height <= 960)) { posX = (int) (x * (2100 / width) * 640 / 540); if (y < 250) y = 0; else {
posY = (int) (((y - 250) * (2000 / (height - 250))) * 960 / height); }
if (posY < 0) posY = 0; } else {
posX = (int) (x * (2100 / width)); if (y < 150) y = 0; else { posY = (int) (((y - 150) * (2000 / (height - 150))) * 480 / height); }
if (posY < 0) posY = 0; }
if (posX >= 2000) posX = 2000; if (posY >= 2000) posY = 2000;
return true;
}
class
IOIOThread
extends
private PwmOutput servoX; private PwmOutput servoY; private PwmOutput servoZ; private PwmOutput led; private DigitalOutput laser;
public void setup() throws ConnectionLostException { try { ioio_.waitForConnect(); } catch (IncompatibilityException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try {
acceso = true; servoX = ioio_.openPwmOutput(new DigitalOutput.Spec(35, Mode.OPEN_DRAIN), 50); servoY = ioio_.openPwmOutput(new DigitalOutput.Spec(40, Mode.OPEN_DRAIN), 50); servoZ = ioio_.openPwmOutput(new DigitalOutput.Spec(45, Mode.OPEN_DRAIN), 50);
led = ioio_.openPwmOutput(39, 1000); laser = ioio_.openDigitalOutput(43);
} catch (ConnectionLostException e) {
throw e; }
}
public void loop() throws ConnectionLostException { try { connesso = true; servoX.setPulseWidth(posX); if (posY > 550) servoY.setPulseWidth(posY); servoZ.setPulseWidth(2500 - posZ);
led.setPulseWidth(800); laser.write(laser_stat); sleep(10); } catch (InterruptedException e) { ioio_.disconnect(); img2.setImageResource(R.drawable.rosso); acceso = false; } catch (ConnectionLostException e) { throw e; }
} }
@Override
protected
return new IOIOThread(); }
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub }
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, info, Menu.NONE, R.string.informazioni);
return true;
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId(); if (id == info) { Intent in = new Intent(MainActivity.this, Informazioni_class.class); startActivity(in); } return super.onOptionsItemSelected(item); } } |
Elenco revisioni | |
17/05/2015 |
Emissione preliminare |