Il sito per chi ama smanettare con Arduino, Raspberry Pi & Co.
Vettura Automatica & Manuale 3

Vettura Automatica & Manuale 3

by

Benvenuti in questo nuovo tutorial dove andremo a creare un vettura che si guida in modo autonomo e allo stesso tempo possiamo pilotarla in manuale da remoto tramite una applicazione Android.

Puntata III: Creazione applicazione Android

In questo articolo spiegherò l’ applicazione Android per il nostro progetto (che troverete completa qui) o meglio spiegherò alcune parti.

Partiamo con il dire che questa applicazione è stata compilata per girare su supporti che hanno la versione Android 5.x.x (lollipop).

i file che a noi ci interessano sono 4:

  • AndroidManifest.xml
  • activity_main.xml
  • MainActivity.java
  • VirtualJoystick.java

i primi 2 file sono dei file di configurazione per l’ app e di creazione per l’interfaccia utente della applicazione, invece gli ultimi 2 sono i codici sorgenti, il primo e il codice della nostra app che gestisce tutta la logica della nostra applicazione, quindi il collegamento con il bluetooth e tutto quello che troviamo nella nostra interfaccia. Invece nel secondo file java troviamo la classe che ci crea il joystick virtuale su schermo. Il joystick virtuale non è una mia creazione ma è stato frutto di una ricerca su Github (Link del progetto del creatore del joystick virtuale).

Partiamo subito con descriver il codice, partendo dal bluetooth. Per integrare il blurtooth in questo progetto dobbiamo andare nel file AndroidManifest.xml e aggiungeremo queste 2 righe di codice dentro il tag manifest.

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Queste 2 tag da i permessi alla nostra app di utilizzare il bluetooth.

Successivamente passiamo nella nostra interfaccia grafica ovvero nel activity_main.xml, dove, andremo a creare un pulsante per la connessione del nostro bluetooth. Io ho usato un toggle button e lo posizionato dove mi è più comodo. una volta posizionato e assegnatogli un id passiamo alla programmazione di questo bottone, innanzitutto dobbiamo dichiarare le librerie di default per la gestione del bluetooth

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

e successivamente scriviamo il codice che ci permette di connetterci al bluetooth, in questo pezzo noi andremo solo a connetterci ma non trasferiremo ancora nessun dato.

        //evento: tap sul togglebutton per la connessione del bluetooth
        tgb.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view){
                if(tgb.isChecked())//controlla che sia attivo il toggle button
                {
                    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                    if (mBluetoothAdapter == null)//controlla se il devices è supportato
                    {
                        // IL BLUETOOTH NON E' SUPPORTATO
                        Toast.makeText(MainActivity.this, "BlueTooth non supportato", Toast.LENGTH_LONG).show();
                        tgb.setChecked(false);
                    }
                    else{
                        if (!mBluetoothAdapter.isEnabled())//controlla che sia abilitato il devices
                        {
                            //  NON E' ABILITATO IL BLUETOOTH
                            Toast.makeText(MainActivity.this, "BlueTooth non abilitato", Toast.LENGTH_LONG).show();
                            tgb.setChecked(false);
                        }
                        else{
                            //  IL BLUETOOTH E' ABILITATO
                            mmDevice=mBluetoothAdapter.getRemoteDevice("20:14:12:03:10:44");//MAC address del bluetooth di arduino
                            try{
                                mmSocket=mmDevice.createRfcommSocketToServiceRecord(uuid);
                            }
                            catch (IOException e){
                                tgb.setChecked(false);
                            }
                            try{
                                // CONNETTE IL DISPOSITIVO TRAMITE IL SOCKET mmSocket
                                mmSocket.connect();
                                outStream = mmSocket.getOutputStream();
								Toast.makeText(MainActivity.this, "ON",  Toast.LENGTH_SHORT).show();// quando arriva a questa linea significa che il bluetooth è connesso
                            }
                            catch (IOException closeException){
                                tgb.setChecked(false);
                                try{
                                    //TENTA DI CHIUDERE IL SOCKET
                                    mmSocket.close();
                                }
                                catch (IOException ceXC){
                                }
                                Toast.makeText(MainActivity.this, "connessione non rieuscita",  Toast.LENGTH_SHORT).show();
                            }
                        }   //CHIUDE l'else di isEnabled
                    }  //CHIUDE l'else di mBluetoothAdapter == null
                }  // CHIUDE if (tgb.isChecked())
                else{
                    try{
                        //TENTA DI CHIUDERE IL SOCKET
                        outStream.close();
                        mmSocket.close();
                    }
                    catch (IOException ceXC){}
                }
            } // CHIUDE public void OnClick(View view)
        });//chiude il tgb.listener

Per trasmettere i dati ci servirà una funzione a parte che è molto semplice:

 //funzione per scrivere nella output del bluetooth
private void sendMessageBluetooth(String message) {
    if (outStream == null){return;}
    byte[] msgBuffer = message.getBytes();
    try{outStream.write(msgBuffer);}
    catch (IOException e){
        Toast.makeText(MainActivity.this, "Messaggio non Inviato", Toast.LENGTH_SHORT).show();
    }
}

Queste sopra elencate sono le parti principali per gestire il bluetooth, invece per quanto riguarda il joystick virtuale è molto semplice perché la classe che abbiamo implementato tramite il progetto trovato su Github gestisce tutto il funzionamento, dalla creazione alla gestione degli eventi, ma vediamo come inserirlo nella nostra GUI e come utilizzarlo

<nerdosoft.simonegolinucci.mcac.VirtualJoystick
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/view" />

questo è il tag xml da aggiungere nel file activity_main.xml per aggiungere a schermo il nostro controllo da notare che se nella classe andrete a modificare il package il tag non funzionerà più e bisognerà modificarlo usando il nuovo package che avete utilizzato nella classe che crea questo controllo. Invece per quanto riguarda la parte di programmazione del nostro controllo basterà che lo andremo a istanziare uno oggetto di quella classe e creiamo un evento come di seguito:

        //evento: movimento del joystick
        joystick.setOnJoystickMoveListener(new VirtualJoystick.OnJoystickMoveListener() {
            @Override
            public void onValueChanged(int angle, int power, int direction) {
                angleTextView.setText(" " + String.valueOf(angle) + "°");
                powerTextView.setText(" " + String.valueOf(power) + "%");
                switch (direction) {
                    case VirtualJoystick.FRONT:
                        directionTextView.setText(R.string.front_lab);
                        sendMessageBluetooth("3");
                        break;
                    case VirtualJoystick.FRONT_RIGHT:
                        directionTextView.setText(R.string.front_right_lab);
                        sendMessageBluetooth("4");
                        break;
                    case VirtualJoystick.RIGHT:
                        directionTextView.setText(R.string.right_lab);
                        sendMessageBluetooth("5");
                        break;
                    case VirtualJoystick.RIGHT_BOTTOM:
                        directionTextView.setText(R.string.right_bottom_lab);
                        sendMessageBluetooth("6");
                        break;
                    case VirtualJoystick.BOTTOM:
                        directionTextView.setText(R.string.bottom_lab);
                        sendMessageBluetooth("7");
                        break;
                    case VirtualJoystick.BOTTOM_LEFT:
                        directionTextView.setText(R.string.bottom_left_lab);
                        sendMessageBluetooth("8");
                        break;
                    case VirtualJoystick.LEFT:
                        directionTextView.setText(R.string.left_lab);
                        sendMessageBluetooth("1");
                        break;
                    case VirtualJoystick.LEFT_FRONT:
                        directionTextView.setText(R.string.left_front_lab);
                        sendMessageBluetooth("2");
                        break;
                    default:
                        directionTextView.setText(R.string.center_lab);
                        sendMessageBluetooth("0");
                }
            }
            //funzione per scrivere nella output del bluetooth
            private void sendMessageBluetooth(String message) {
                if (outStream == null){return;}
                byte[] msgBuffer = message.getBytes();
                try{outStream.write(msgBuffer);}
                catch (IOException e){
					Toast.makeText(MainActivity.this, "Messaggio non Inviato", Toast.LENGTH_SHORT).show();
                }
            }
        }, VirtualJoystick.DEFAULT_LOOP_INTERVAL);

in questo esempio andremo a scrivere in delle textView il valore dell’ angolo, la percentuale di potenza e la direzione. Un piccolo chiarimento della potenza: la potenza è un valore assegnato in base a quanto esterno stiamo tappando rispetto al centro del controllo, quindi la potenza al centro del controller sarà dello 0%, invece all’esterno sarà del 100%. In questo esempio c’è anche la nostra funzione per spedire il valore via bluetooth, la nostra macchinina prenderà questo valore e Arduino lo elaborerà in modo tale la direzione corrisponda con quella decisa da noi sul nostro joystick.

Il DEFAULT_LOOP_INTERVAL è una costante della nostra classe che definisce l’ intervallo di aggiornamento del nostro controllo, che di default è impostata a 100 millisecondi.

Screenshot_2015-05-24-17-28-25
Interfaccia Grafica App per pilotare la nostra Macchinina

Infine la nostra applicazione risulterà come da immagine qua di fianco ma voi potrete modificarla come più vi piace tramite il progetto su GitHub che troverete nel link a inizio pagina dove vi saranno forniti i file sorgente del progetto.

Ringrazio a tutti per aver seguito le nostro puntate per creare questo progetto, in caso vi siete dimenticati qualche puntata ecco qua i link per recuperarle:

  1. Puntata I: Costruzione hardware con Arduino ;
  2. Puntata II: Creazione sketch per la macchinina.

Inoltre se non vi è chiaro qualcosa vi invito a commentare e ci vedremo in futuro con altri tutorial.

Ti è rimasta una domanda o un dubbio?

Iscriviti e chiedi nella community

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *