2

So I am new to Java and android development. So far I have been creating an app that is able to connect and interface with an arduino. I have a method that is able to read the data from the arduino (in bytes ) and then print the data as a string in UTF-8....However, I simply want this method to read and interpret the data, and have the interpreted data to be callable from another method, say button from android. Following is code that reads the data.

public class MainActivity extends AppCompatActivity {
    public final String Action_USB_Permission = "com.example.myapplication.USB_PERMISSION";
    UsbManager usbManager;
    UsbDevice device;
    UsbSerialDevice serial;
    UsbDeviceConnection connection;
    String data;
    String adata;
    TextView textView;
    Button tempButton

    UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
        @Override
        public void onReceivedData(byte[] arg0) {
            try {
                data = new String(arg0, "UTF-8"); //edit (removed String in "String data =" )


            } catch (UnsupportedEncodingException e) {
                e.getStackTrace();
            }
        }
    };

    // Serial codes and commands
    public void pushcmd(String command) { //command for serial
        serial.write(command.getBytes());
    }

    public void gettemp() {
        pushcmd("T\n");
        serial.read(mCallback);
        adata = data;
    }

    //This is for the app creation i think
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        usbManager = (UsbManager) getSystemService(this.USB_SERVICE);
        tempButton = (Button) findViewById(R.id.buttontemp);
    }

    public void onClickTemp(View view) { //This is the command to print data
        gettemp();
        tvAppend(textView, "\n Measured temperature \n" + adata);
    }

    private void tvAppend(TextView tv, CharSequence text) {
        final TextView ftv = tv;
        final CharSequence ftext = text;

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ftv.append(ftext);
            }
        });
    }
}

tvAppend is a method that prints the string on a textview on the screen. I got the libraries from https://github.com/felHR85/UsbSerial and it says to simply reference it with

serial.read(mcallback), I have tried the command, but I receive a "measured temperaturenull" then the measurement is printed after, which is from the onReceivedData method . Any suggestions would be greatly appreciated.Or if I'm not clear, let me know, I'll try to clear things up some more.

Edit: I added my tvAppend method, defined a textview field and a button. I am also pointing out that I don't have the whole program included, I followed the implementation from all about circuits http://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/ Thanks again for the feedback

COMMENT about edit: when the code is changed to how it is above. the adata is not displayed, only "Measured temperature".

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
robman
  • 73
  • 1
  • 1
  • 4
  • Try to remove `String` from `String data =` – OneCricketeer Jun 14 '16 at 04:16
  • Also, you seem to be missing the complete part of making a [mcve]. You are missing both the textView variable and the tvAppend method – OneCricketeer Jun 14 '16 at 04:19
  • @cricket_007 Thank you for letting me know about not being clear enough. I have also tried to remove String from the String data = – robman Jun 14 '16 at 16:21
  • You never initialized the textview? – OneCricketeer Jun 14 '16 at 16:28
  • yes I had the textview initialized. I just did not show it on the post before. – robman Jun 14 '16 at 16:33
  • Okay, just making sure. And the only reason I see that you are getting `null` in the output is that `adata` isn't having anything assigned to it. However, `adata = data;`, which trace back to `data = new String(arg0, "UTF-8");`. – OneCricketeer Jun 14 '16 at 16:35
  • okay, thank you. What do you think would be the best way to fix this? So a correction, when I change the code to how it is shown above, there isn't a null anymore, only "Measured temperature" is displayed. – robman Jun 14 '16 at 16:41
  • Okay, if null isn't shown anymore, then you are getting an empty string for `adata`. So, maybe that `arg0` value is sending no data? – OneCricketeer Jun 14 '16 at 17:05
  • This is something that I thought, but when I add the tvAppend call in the "try" case then I do get data from the arduino. – robman Jun 14 '16 at 17:23
  • Alright, so what's the problem, then? – OneCricketeer Jun 14 '16 at 17:25
  • I want the data to be callable from another method rather than just being displayed. Sorry for not being clear on it. – robman Jun 14 '16 at 17:26
  • I think you should remove the `data` variable and only use `adata`. For example, `adata = data;` is called immediately after `serial.read(mCallback);`. The callback is asynchronous, meaning you are not guaranteed a result from it immediately, so `data= new String...` may not happen before `adata = data`, so therefore, just use `adata = new String...` – OneCricketeer Jun 14 '16 at 17:28
  • Similar problem exists with `tvAppend` inside the `onClickTemp`. The `gettemp` method method won't assign `adata` before you get to `tvAppend` – OneCricketeer Jun 14 '16 at 17:29
  • @cricket_007 just making sure, I would have ' adata= new String..' after the 'serial.read(mcallback)' and not have in the try case? – robman Jun 14 '16 at 21:09

1 Answers1

0

I think you're confusing yourself with the flow of data here.

  1. You click a button on the app
  2. It calls pushcmd to the Arduino
  3. The Arduino sends some data back at some unknown point in the future
  4. You read that data and update the TextView

Now, with that logic, the code could be structured like so. (Feel free to re-organize back into your app how you want).

public void onClickTemp(View view) {
    gettemp();
    // No value of "adata" or "data" is guaranteed here
}

public void gettemp() {
    pushcmd("T\n");
    serial.read(mCallback); // asynchronous callback
    // No value of "adata" or "data" is guaranteed here, either
}

UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
    @Override
    public void onReceivedData(byte[] arg0) {
        try {
            // Here, you are guaranteed some data
            String data = new String(arg0, "UTF-8");
            tvAppend(textView, "\n Measured temperature \n" + data);
        } catch (UnsupportedEncodingException e) {
            e.getStackTrace();
        }
    }
};

Or, if you want to fold that all into one method, then

public void onClickTemp(View view) {
    pushcmd("T\n");

    serial.read(new UsbSerialInterface.UsbReadCallback() {
        @Override
        public void onReceivedData(byte[] arg0) {
            try {
                // Here, you are guaranteed some data
                String data = new String(arg0, "UTF-8");
                tvAppend(textView, "\n Measured temperature \n" + data);
            } catch (UnsupportedEncodingException e) {
                e.getStackTrace();
            }
        }
    });
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245