Tuesday, June 30, 2015

Garden Robot Update 6

Quick update.  I know these aren't as frequent as they should be, but hopefully I can cover most of the important things I have done since the last one.

First of all, after a few days, I finally figured out a nagging issue with the existing NXTBotGuard streaming solution.  It turned out that my browser was caching the image, causing it to only update on refresh.  I forced this out by adding this line to the NanoHTTP header:

res.addHeader( "Cache-Control", "no-store");

With this out of the way, the streaming solution worked fine, but I didn't (and still don't) understand it.  Apparently the developer " modified the NanoHTTPD  server to serve files directly out of the compressed assets folder that comes with your app package (apk)."  I don't get how he is doing that, so I took the simpler solution of just reading the index.html file via AssetManager:

try {
    // Open file from Asset Manager
    InputStream inputStream = getApplicationContext().getAssets().open("index.html");    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));    String line = "";    while ((line = reader.readLine()) != null) {
        answer += line;    }
    reader.close();
} catch(IOException ioe) {
    Log.w("Httpd", ioe.toString());}


return new NanoHTTPD.Response(answer);

Which works perfectly for html but doesn't seem to work for Javascript, as I discovered tonight, as my index.html file will call the javascript functions as expected when I access it locally, but not when I have it read using the above method.  Grr.  (For future personal reference, this index.html is in the "Code Snippets" folder)

So in general, I think that a quick and dirty method to get all this done would be to just host an ever-changing image from the camera using a simple html tag, and have that consistently update to simulate a video.  This should work using the above method.  Although that (should?) work, the dynamic canvas property of html5 has intrigued me so much that I am dying to use it, as well as learn more about html and javascript (which I would use to update the canvas element, and maybe some other things).

So...now, I am going to look online for any more solutions that I can understand about reading directly from the Asset Manager, or just work on my dirty method in pure html and see if it works.

Friday, June 19, 2015

Garden Robot Update 5

Success!!
This took way longer than it should (and is a much more major victory to me than it should be) but I finally got a web page to host the current numerical sensor value of a light sensor running on my NXT.  This took several days due to some stupid problems:

1.  The NXT Direct Commands documentation explains that the getInputValues command sends a return byte package of 16 bytes, but I forgot that since I am using Bluetooth, another 2 bytes are tacked on the beginning.  That caused my interpretation to be offset by 2 bytes for the longest time.  Oops.
2.  This one was even worse, but I blame it on not knowing anything about Java.  So I didn't understand how the InputStream works, and I didn't at first realize that the return values from previous direct commands were already stored in the buffer, causing me to read the wrong value.  Secondly, I didn't realize that the InputStream is reset each time I called the command (still not sure why...) So as of now, I am having it skip over the 5 bytes returned from the setInputMode command before reading the 18 byte package from the getInputValues command.

Here's what I've got...
long skipped = stream.skip(streamskip);
int bytesRead = stream.read(data,0,18);
Log.w("NxtBrick", "Bytes Read: " + Integer.toString(bytesRead));
String x = Integer.toString(((data[12] & 0xff) << 8) | (data[13] & 0xff));

Log.w("NxtBrick", "Sensor Value: " + x);
return x;

And to write to NanoHTTPD:
NxtBrick nxt = ServerActivity.getNxt();
String answer="";    try {
        //nxt.playTone('a','c');        nxt.setInputMode((byte)0x00,(byte)0x06,(byte)0x80);        answer=nxt.getInputValues((byte)0x00);    } catch (IOException e) {
        e.printStackTrace();    }
return new NanoHTTPD.Response(answer);





Sunday, June 14, 2015

Garden Robot Update 4

This happened today:












Still not sure how it works, but it's being hosted by my phone, which is cool.  I somehow ran across it randomly when wondering why none of the NanoHTTPD examples I found worked (doubtlessly because of my utter lack of Java knowledge...ugh).  But it works.

Next step is reading sensors from the NXT, where I am currently stuck.  I have delved deep into the NXT SDK where they have documentation on some really cool direct command protocols, which do not require a user-developed program running on the brick (excellent for direct remote control if the program is doing something wrong).  Unfortunately, while I am having no issue using the direct commands developed by the SmartLab NXTBotGuard project, I seem to be getting some bogus data when I call the getInputValues.  It changes whenever I reboot the program but not in the middle of it...it is weird.  I am sure it is a dumb Java issue.  For reference purposes, here's my buggy code:

public String getInputValues () throws IOException
{
    byte [] msg = new byte [5];            msg[0]=(byte)0x04;            msg[1]=(byte)0x02;            msg[2]=(byte)0x00;            msg[3]=(byte)0x07;            msg[4]=(byte)0x00;    sendMessage(msg);    Log.w("NxtBrick", String.valueOf(msg));
    if(in !=null)
    {

        String x= String.valueOf(in);        Log.w("NxtBrick", x);
       /*        String x = null;        int bytesRead;        byte[] contents = new byte[100];        while ((bytesRead = in.read(contents)) != -1)        {            x = new String(contents, 0, bytesRead);            System.out.print(x);            Log.v("NxtBrick", x);        }        */
        return x;    }
    else    {
        return "Null";    }

}

P.S.  Don't use it, it doesn't work.

Tuesday, June 9, 2015

Garden Robot Update 3

It's been a little while, but unfortunately not much has progressed.
I have contacted the developers of the MonoBrick Tunnel and haven't heard anything back yet.  This has encouraged me to go with route 2 and try to develop a custom app to handle connectivity and web serving.  It has been an interesting couple of days...

First of all, I have no clue what I am doing, so I first tried to get the NXTBotGuard project I linked earlier to work.  After downloading Android Studio, I found that I could import the Eclipse project and convert it into an Android Studio project, which is awesome.  However, running it, I ran into a lot of issues.  Firstly, the NXT brick refused to connect reliably, with the app crashing at random intervals.  Even when the Bluetooth connection succeeded and I was able to access the hosted web page, entering in the password caused the app to crash.  Reading the Logcat files, I determined that something concerning the phone's camera stream was causing it to crash, but due to my limited Java knowledge, I (still) have no clue what.

With this frustration I decided to bit the bullet and just start personal development of a custom app.  Using copious amounts of copy/paste from NXTBotGuard and a plethora of external websites, I managed to form a simple app that enabled Bluetooth, listed paired devices, scanned for devices, and displayed them in a list view for user input.  So far, it is able to connect to the NXT quite reliably, and does not crash like the NXTBotGuard app.

However, the next step is where I am (still) stuck.  NXTBotGuard makes use of a lightweight HTPP server known as NanoHTTP.  Again, I have no idea how it works, so that is my next project.

First to figure out Java's multi-threading architecture...I am so lost...

Wednesday, June 3, 2015

Garden Robot Update 2

Okay...don't be me.
So on the software side, using the MonoBrick C# Communication Library, I managed to set up a simple Windows Form interface that allowed for manual polling of the moisture and light sensor over the MonoBrick Tunnel running on an Android device.  But then I wanted to set up video streaming...

I couldn't get it to work.  I even tried downloading MonoBrick remote (which worked on a different computer and back when I was running Android 4.4.4) and it still wouldn't stream.  I speculate that upgrading to 5.0.2 has caused a lot of issues, including the "menu crashing" error.  Everything worked except for the streaming (and the fact I still couldn't access the menu).

So I tried re-installing the app.  This was the big mistake.  This removed the NXT from the "remembered device" list previously only accessible through the menu.  And now, since I can't get to the menu, there is no way I can reconnect the NXT.  Oops.

So while I wait for a response from the MonoBrick folks, I decided to screw around with other alternatives.  At this point, the second option from my previous post is looking pretty good...but there's still the Java problem.