Aplikacja mobilna do sterowania RASPBERRY PI ZERO W przez bluetooth

0

Pilnie potrzebuję pomocy,
Zbliża się oddanie projektu i moim zadaniem było stworzenie aplikacji mobilnej do sterowania robotem z raspberry pi. Zanim zrobiłam komunikację, wizualnie aplikacja w postaci wirtualnego joystick'a działała bez zarzutów (w planach miałam wysyłać wartość "arrow" (kierunek wysunięcia drążka joystick'a), która prawidłowo wypisuje się na ekranie), jednakże gdy dodałam komunikacje bluetooth (zesparowanie urządzeń działa prawidłowo), to gdy chcę użyć joysticka, appka się crash'uje. Byłabym bardzo wdzięczna za szybką podpowiedź czy pomoc w rozwiązaniu problemu. Oba kody znajdują się w załączniku.

EDIT: Po zakomentowaniu fragmentu kodu odpowiedzialnego za wysyłanie zmiennych program nie crash'uje się

0

Może pokaż logcat będzie dużo szybciej

0

01-23 0942.996 1733-1733/com.example.user.joysyickbb8 W/System: ClassLoader referenced unknown path: /data/app/com.example.user.joysyickbb8-1/lib/arm64
01-23 0943.105 1733-1733/com.example.user.joysyickbb8 W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
01-23 0943.440 1733-1743/com.example.user.joysyickbb8 I/art: Background sticky concurrent mark sweep GC freed 11454(856KB) AllocSpace objects, 9(732KB) LOS objects, 29% free, 8MB/11MB, paused 17.213ms total 89.460ms
01-23 0943.445 1733-1733/com.example.user.joysyickbb8 I/HwCust: Constructor found for class android.widget.HwCustTextViewImpl
01-23 0943.521 1733-1733/com.example.user.joysyickbb8 I/HwCust: Constructor found for class android.widget.HwCustTextViewImpl
01-23 0943.579 1733-1733/com.example.user.joysyickbb8 I/HwSecImmHelper: mSecurityInputMethodService is null
01-23 0943.601 1733-1733/com.example.user.joysyickbb8 E/HAL: load: id=gralloc != hmi->id=gralloc
01-23 0943.717 1733-1806/com.example.user.joysyickbb8 E/HAL: load: id=gralloc != hmi->id=gralloc
01-23 0943.718 1733-1806/com.example.user.joysyickbb8 I/OpenGLRenderer: Initialized EGL, version 1.4
01-23 0943.807 1733-1806/com.example.user.joysyickbb8 W/OpenGLRenderer: load: so=/system/lib64/libhwuibp.so
dlopen failed: library "/system/lib64/libhwuibp.so" not found
01-23 0943.807 1733-1806/com.example.user.joysyickbb8 W/OpenGLRenderer: Initialize Binary Program Cache: Load Failed
01-23 0943.807 1733-1806/com.example.user.joysyickbb8 E/HAL: load: id=gralloc != hmi->id=gralloc
01-23 0943.970 1733-1733/com.example.user.joysyickbb8 I/HwSecImmHelper: mSecurityInputMethodService is null
01-23 0947.138 1733-1733/com.example.user.joysyickbb8 I/HwSecImmHelper: mSecurityInputMethodService is null
01-23 0948.283 1733-1733/com.example.user.joysyickbb8 I/HwCust: Constructor found for class android.widget.HwCustTextViewImpl
01-23 0948.292 1733-1733/com.example.user.joysyickbb8 I/Choreographer: Skipped 67 frames! The application may be doing too much work on its main thread.
01-23 0951.570 1733-1733/com.example.user.joysyickbb8 I/HwSecImmHelper: mSecurityInputMethodService is null
01-23 0955.360 1733-1733/com.example.user.joysyickbb8 E/InputEventReceiver: Exception dispatching input event.
01-23 0955.360 1733-1733/com.example.user.joysyickbb8 E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
01-23 0955.383 1733-1733/com.example.user.joysyickbb8 E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
at com.example.user.joysyickbb8.MainActivity$1.onMove(MainActivity.java:85)
at io.github.controlwear.virtual.joystick.android.JoystickView.onTouchEvent(JoystickView.java:444)
at android.view.View.dispatchTouchEvent(View.java:9390)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2461)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1777)
at android.app.Activity.dispatchTouchEvent(Activity.java:2865)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2422)
at android.view.View.dispatchPointerEvent(View.java:9610)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4436)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4302)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3889)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3855)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3981)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3863)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4038)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3889)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3855)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3863)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3836)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6135)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6109)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6070)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6251)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:192)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:330)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
01-23 0955.456 1733-1733/com.example.user.joysyickbb8 I/Process: Sending signal. PID: 1733 SIG: 9

0

Sprawdź na telefonie innym, niż Huawei, dla pewności.

0

java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
Najprawdopodobiej źle nawiązałaś połączneie Bluetooth i dostajesz jako outputStream nulla.

0

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context="com.example.user.joysyickbb8.MainActivity">

    <io.github.controlwear.virtual.joystick.android.JoystickView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/joystickView"
        app:JV_borderWidth="4dp"
        app:JV_fixedCenter="false"
        app:JV_buttonColor="#FF8C00"
        app:JV_borderColor="#FF8C00"
        app:JV_backgroundColor="#FFFFFF"
        app:JV_buttonSizeRatio="20%"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="kąt"
        android:id="@+id/tv_angle"
        />
        
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="siła"
        android:id="@+id/tv_strength"
        android:layout_alignParentEnd="true"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="kierunek"
        android:id="@+id/id_arrow"
        android:layout_centerHorizontal="true"/>

    <Button
        android:id="@+id/id_bt_connect"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id_arrow"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="46dp"
        android:text="Button" />


</RelativeLayout>

MainActivity.java

package com.example.user.joysyickbb8;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

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

import io.github.controlwear.virtual.joystick.android.JoystickView;

public class MainActivity extends AppCompatActivity {

    private final String DEVICE_ADDRESS = "B8:27:BB:26:7D:77";
    private final UUID  PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");

    private BluetoothDevice device;
    private BluetoothSocket socket;
    private OutputStream outputStream;

    Button bluetooth_connect_btn;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final JoystickView joystickView= (JoystickView)  findViewById(R.id.joystickView);
        final TextView tv_angle= (TextView) findViewById(R.id.tv_angle);
        final TextView tv_strength= (TextView) findViewById(R.id.tv_strength);

        final TextView id_arrow = (TextView) findViewById(R.id.id_arrow);
         bluetooth_connect_btn=(Button) findViewById(R.id.id_bt_connect);

        joystickView.setOnMoveListener(new JoystickView.OnMoveListener() {
            @Override
            public void onMove(int angle, int strength){

                Object arrow;

                tv_angle.setText("kąt: " + angle);
                tv_strength.setText("siła: " + strength + "%");

                if (strength == 0)
                {
                    arrow = "x";
                    id_arrow.setText("kierunek: " + arrow);
                    try
                    {
                        outputStream.write(arrow.toString().getBytes());
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }

                }
                else if ((angle>315 || angle<=45) & strength !=0) {

                    arrow = "d";
                    id_arrow.setText("kierunek: " + arrow);
                   try
                    {
                        outputStream.write(arrow.toString().getBytes());
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                else if (angle > 45 & angle <=135 & strength !=0){
                    arrow = "w";
                    id_arrow.setText("kierunek: " + arrow);
                    try
                    {
                        outputStream.write(arrow.toString().getBytes());
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
                else if  (angle > 135 & angle <= 225 & strength !=0){
                    arrow = "a";
                    id_arrow.setText("kierunek: " + arrow);
                   try
                    {
                        outputStream.write(arrow.toString().getBytes());
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
                else if (angle > 225 & angle<=315 & strength !=0){
                    arrow = "s";
                    id_arrow.setText("kierunek: " + arrow);
                    try
                    {
                        outputStream.write(arrow.toString().getBytes());
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        });

        bluetooth_connect_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(BTinit()){
                    BTconnect();
                }
            }
        });
    }

    public boolean BTinit()
    {
        boolean found =false;
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null)
        {
            Toast.makeText(getApplicationContext(),"Urządzenie nie wspiera 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(),"Sparuj urządzenia",Toast.LENGTH_SHORT).show();
        }
        else
        {
            for (BluetoothDevice interator:bondedDevices)
            {
                if (interator.getAddress().equals(DEVICE_ADDRESS))
                {
                    device = interator;
                    found = true;
                    break;
                }
            }
        }
        return found;
    }

    public  boolean BTconnect()
    {
        boolean connected = true;

        try
        {
            socket = device.createRfcommSocketToServiceRecord(PORT_UUID);
            socket.connect();
            Toast.makeText(getApplicationContext(),"Połączono z bluetooth",Toast.LENGTH_SHORT).show();
        }
        catch(IOException e)
        {
            e.printStackTrace();
            connected=false;
        }

        if (connected)
        {
            try
            {
                outputStream = socket.getOutputStream();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return connected;
    }
@Override
    protected void onStart()
    {
           super.onStart();
    }
}

0

Powinnaś tutaj skorzystać z wątków. Nie wiesz tak naprawdę ile potrwa łączenie z raspberry. Problem tutaj jest taki, że próbujesz sterować nie mając podłączonego urządzenia do telefonu. Socket ma taką metodę isConnected(). Ona Ci powie czy już możesz dostać obiekt outputStream. Dopiero wtedy powinnaś pozwolić joystickowi na sterowanie.

0

@Azurka: zrób to tak:

if (socket.isConnected()){
setMoveListener();
} else {
waitForConnection();
}
0

Czy jest możliwość aby to był błąd z joystickiem? bo użyłam innego kodu który działa i wstawiłam joystick i także nie wysyła.

1 użytkowników online, w tym zalogowanych: 0, gości: 1