JSON Arduino to Processing? - json

I'm having some issue with simple parsing of JSON from Arduino to Processing, here is the following code.
ARDUINO CODE
int x,y;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sendJSON();
delay(500);
}
void sendJSON(){
String json;
json = "{\"accel\":{\"x\":";
json = json + x;
json = json + ",\"y\":";
json = json + y;
json = json + "}}";
Serial.println(json);
}
PROCESSING CODE
import processing.serial.*;
Serial myPort;
JSONObject json;
int x,y;
void setup () {
size(200, 200);
myPort = new Serial(this, Serial.list()[5], 9600);
myPort.bufferUntil('\n');
}
void draw () {
}
void serialEvent (Serial myPort) {
while (myPort.available() > 0) {
String inBuffer = myPort.readString();
if (inBuffer != null) {
json = loadJSONObject(inBuffer);
JSONObject acc = json.getJSONObject("accel");
int x = acc.getInt("x");
int y = acc.getInt("y");
println(x + ", " + y);
}
}
}
On the serial monitor i'm having the right string :
{"accel":{"x":451,"y":-118}}
However on the Processing sketch i'm having the following error :
{ does not exist or could not be read
Error, disabling serialEvent() for /dev/tty.usbmodem1421
null
or sometime even :
{"":{"x":456,"y":-123}} does not exist or could not be read Error,
I would be very grateful if someone could give me some help in debugging this current issue !
Thank you very much !

I would recommend transmitting this as binary data which you can unpack on the processing side. It should solve your json problem and will be much more efficient. Something like this should work for you...
Arduino code
byte Rx_Data[4];
Tx_Data[0] = accelX >> 8 & 0xff;
Tx_Data[1] = accelX& 0xff;
Tx_Data[2] = accelY >> 8 & 0xff;
Tx_Data[3] = accelY& 0xff;
Serial.write(Data_Packet);
Processing code
byte Tx_Data[4];
if(Serial.available() == 4) {
for(int i=0;i<4;i++){
Tx_Data[i] = Serial.read();
}
}
int accelX = Tx_Data[0] << 8 | Tx_Data[1];
int accelY = Tx_Data[2] << 8 | Tx_Data[3];

Related

how to write GameObject position in the Scene to json file?

on Clicking the button, I m loading the function WriteJsonForLevel(). I have placed three GameObject with the tag name "RedCoin" and I want to write the position of the GameObject to a JSON file. I can get the position of the object, but it's all overwritten. I can only see the last GameObject position (i.e the completion of the loop)
public List<GameObject> levelObjects;
public string level;
public Vector3 pos;
// Start is called before the first frame update
void Start()
{
levelObjects = new List<GameObject>();
}
// Update is called once per frame
void Update()
{
}
public void WritejsonForAll()
{
WriteJsonForLevel();
}
public void WriteJsonForLevel()
{
/* FileStream fs = new FileStream(Application.dataPath + "/sample.json",FileMode.Create);
StreamWriter writer= new StreamWriter(fs);*/
GameObject[] coinObjRed = GameObject.FindGameObjectsWithTag("RedCoin");
putAllObjectInList(coinObjRed);
}
public void putAllObjectInList(GameObject[] p)
{
string path = Application.dataPath + "/text.json";
foreach (GameObject q in p)
{
levelObjects.Add(q);
}
for (int i = 0; i < levelObjects.Count; i++)
{
GameObject lvlObj = levelObjects[i];
Vector3 pos = lvlObj.transform.position;
string posOutput = JsonUtility.ToJson(pos);
File.WriteAllText(path,posOutput);
Debug.Log("position:" + posOutput);
}
}
}
You are using WriteAllText which will overwrite the file every time it is called. As it is overwriting each time it is in the loop, it will only write the last object to the file as every other previous write is overwritten. I would consider making a serialized class of data, assigning the data to it, converting it to a JSON string then saving that.
// stores individual locations for saving
[System.Serializable]
public class IndividualLocation
{
public IndividualLocation(Vector3 pos)
{
xPos = pos.x;
yPos = pos.y;
zPos = pos.z;
}
public float xPos;
public float yPos;
public float zPos;
}
// stores all game locations for saving
[System.Serializable]
public class AllGameLocations
{
public List<IndividualLocation> Locations = new List<IndividualLocation>();
}
public void PutAllObjectInList(in GameObject[] p)
{
string path = Application.dataPath + "/text.json";
// create a new object to write to
AllGameLocations data = new AllGameLocations();
// iterate the objects adding each to our structure
foreach(GameObject obj in p)
{
data.Locations.Add(new IndividualLocation(obj.transform.position));
}
// now that the data is filled, write out to the file
File.WriteAllText(path, JsonUtility.ToJson(AllGameLocations));
}
If you need a snippet on how to load the data properly I can add one.
Edit: Here is a load snippet
public void LoadJSONObject()
{
string path = Application.dataPath + "/text.json";
// if the file path or name does not exist
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
Debug.LogWarning("File or path does not exist! " + path);
return
}
// load in the save data as byte array
byte[] jsonDataAsBytes = null;
try
{
jsonDataAsBytes = File.ReadAllBytes(path);
Debug.Log("<color=green>Loaded all data from: </color>" + path);
}
catch (Exception e)
{
Debug.LogWarning("Failed to load data from: " + path);
Debug.LogWarning("Error: " + e.Message);
return;
}
if (jsonDataAsBytes == null)
return;
// convert the byte array to json
string jsonData;
// convert the byte array to json
jsonData = Encoding.ASCII.GetString(jsonDataAsBytes);
// convert to the specified object type
AllGameLocations returnedData;
JsonUtility.FromJsonOverwrite<AllGameLocations>(jsonData, AllGameLocations);
// use returnedData as a normal object now
float firstObjectX = returnedData.Locations[0].xPos;
}
}
Let me know if the Load works, just typed it up untested. Added some error handling as well to assure data exists and the load properly works.

Accessing nested JSON in Processing

I need to extract 3 values from a JSON file. I just managed to get all data but I can't separate them.
The file looks like this:
{
"motionAndDeviceRelated":{
"mOrientation":[0,0,0],
"mLocalVelocity":[0,0,0],
"mWorldVelocity":[0,0,0],
"mAngularVelocity":[0,0,0],
"mLocalAcceleration":[0,0,0],
"mWorldAcceleration":[0,0,0],
"mExtentsCentre":[0,0,0]
}
}
I need to extract in float variables data from mLocalAcceleration.
import http.requests.*;
JSONObject json;
void setup() {
size(600,600);
}
void draw() {
// actually returns something instead of throwing an error, which is progress
long t = System.currentTimeMillis();
GetRequest get = new GetRequest("http://" + "localhost:8180/crest2/v1/api?motionDeviceRelated=true&formatted=true");
get.send();
JSONObject json = parseJSONObject(get.getContent());
println(json);
println(System.currentTimeMillis() - t);
loop();
}
Here is the code that works:
`import http.requests.*;
JSONObject json;
float x;
float y;
float z;
void setup() {
size(800,800);
}
void draw() {
long t = System.currentTimeMillis();
GetRequest get = new GetRequest("http://" + "localhost:8180/crest2/v1/api?motionDeviceRelated=true&formatted=true");
get.send();
JSONObject json = parseJSONObject(get.getContent());
JSONObject motion = json.getJSONObject("motionAndDeviceRelated");
JSONArray acc = motion.getJSONArray("mWorldAcceleration");
x = acc.getFloat(0);
z = acc.getFloat(1);
y = acc.getFloat(2);
println(System.currentTimeMillis() - t);
loop();
}`

How to fix Exception in thread "main" java.lang.NullPointerException

I have this error when I Run the code but no when I Compile it.
Exception in thread "main" java.lang.NullPointerException
at java.util.StringTokenizer.<init>(StringTokenizer.java:199)
at java.util.StringTokenizer.<init>(StringTokenizer.java:221)
at WillinsLaMarkusFileInputOutput.main(WillinsLaMarkusFileInputOutput.java:23)
Here is my complete code
import java.io.*;
public class WillinsLaMarkusFileInputOutput {
public static void main(String[] args) throws IOException {
/* open the files */
// Scanner sc = new Scanner(System.in);
BufferedReader r = new BufferedReader(new FileReader("input.txt"));
BufferedWriter w = new BufferedWriter(new FileWriter("output.txt"));
float[] values = new float[10];
String str = r.readLine();
int i = 0;
float sum = 0.0f, avg = 0.0f;
/* tokenize the string into floats separated by spaces */
java.util.StringTokenizer tk = new java.util.StringTokenizer(str, " ");
while (tk.hasMoreElements()) {
values[i] = Float.valueOf(tk.nextToken()).floatValue();
/* compute sum */
sum += values[i];
i++;
}
/* calculate average */
avg = sum / 10.0f;
/* write results to output.txt */
w.write("Sum: " + sum);
w.newLine();
w.write("Average: " + avg);
w.flush();
/* close the files */
r.close();
w.close();
}
}
Any suggestions on how to fix this ?
The exception goes from this line:
java.util.StringTokenizer tk = new java.util.StringTokenizer(str, " ");
So first let's read the documentation when this constructor may throw NullPointerException:
public StringTokenizer(String str, String delim)
Throws:
NullPointerException - if str is null
Fine. It means that str is null. The str is assigned in this line:
String str = r.readLine();
Now you should read the documentation when r.readLine() may return null:
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
So it signals that end of file is reached. As it's the very first attempt to read something from this file it seems that you are reading an empty file.
In general careful documentation reading may greatly help to understand why your program doesn't work.

Drawing a route between 2 locations Google Maps API Android V2

I was playing around with the Google Maps API V2 on android.
Trying to get a path between 2 locations and doing this with the JSON Parsing.
I am getting a route. and the route starts out how it should be. but then at one point it goes the wrong way.
My end destination ends up wrong. And with some other locations my app just gets terminated.
This is what i have done
Here is my makeURL method
public String makeUrl(){
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin="); //start positie
urlString.append(Double.toString(source.latitude));
urlString.append(",");
urlString.append(Double.toString(source.longitude));
urlString.append("&destination="); //eind positie
urlString.append(Double.toString(dest.latitude));
urlString.append(",");
urlString.append(Double.toString(dest.longitude));
urlString.append("&sensor=false&mode=driving");
return urlString.toString();
}
my JSON parser
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONParser() {
// TODO Auto-generated constructor stub
}
public String getJSONFromURL(String url){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch(UnsupportedEncodingException e){
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null){
sb.append(line + "\n");
//Log.e("test: ", sb.toString());
}
json = sb.toString();
is.close();
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("buffer error", "Error converting result " + e.toString());
}
return json;
}
I draw my Path with this method
public void drawPath(String result){
try{
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
Log.d("test: ", encodedString);
List<LatLng> list = decodePoly(encodedString);
LatLng last = null;
for (int i = 0; i < list.size()-1; i++) {
LatLng src = list.get(i);
LatLng dest = list.get(i+1);
last = dest;
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
Polyline line = googleMap.addPolyline(new PolylineOptions().add(
new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
.width(2)
.color(Color.BLUE));
}
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
}catch (JSONException e){
e.printStackTrace();
}
}
And I decode my JSON with
private List<LatLng> decodePoly(String encoded){
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0;
int length = encoded.length();
int latitude = 0;
int longitude = 0;
while(index < length){
int b;
int shift = 0;
int result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int destLat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
latitude += destLat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b > 0x20);
int destLong = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
longitude += destLong;
poly.add(new LatLng((latitude / 1E5),(longitude / 1E5) ));
}
return poly;
}
And then coded with an AsyncTask
Thanks in advance.
Sorry for the long wait.. i have fixed it a while ago but i hadn't put my solution on here yet.
It was basically a typo...
In my Json decoder i use 2 Do while statements with
while (b >= 0x20);
In the second Do While statement i forgot the "=".
Therefore it wasn't rendering correctly...
thanks
I believe that you are creating your LatLng objects from overview_polyline. This, according to Google documentation "contains an object holding an array of encoded points that represent an approximate (smoothed) path of the resulting directions.".
I'm pretty sure that you can get a more detailed route building your LatLng object based on legs[] and steps[] data as the official documentation states that A step is the most atomic unit of a direction's route, containing a single step describing a specific, single instruction on the journey.
Take a look at:
https://developers.google.com/maps/documentation/directions/#Routes
Tmichel,
the Michael has the correctly wave, because on legs and steps on your route plot the line out of the street.
Legs and steps, has informations around coordinates for informations to alert the user.
Polylines are the correct and precise points over the street.
Sorry my bad english

How can I convert the decimal representation of an IP address into binary?

Does anyone knows how to convert decimal notation of an IP address into binary form in Java? Please let me know...
An IP address written as a.b.c.d can be converted to a 32-bit integer value
using shift and bit-wise inclusive OR operators as,
(a << 24) | (b << 16) | (c << 8) | d
To be safe, each of a,b,c,d has valid range 0-255 -- you can check that in your conversion.
You can further validate the IP address using this regex example.
You can use the java.net.InetAddress class. Two methods you should look at are getByName and getAddress. Here is a simple code example
import java.net.InetAddress;
import java.net.UnknownHostException;
/* ... */
String ip = "192.168.1.1";
InetAddress address = null;
try {
address = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
//Your String wasn't a valid IP Address or host name
}
byte [] binaryIP = address.getAddress();
Gathering your suggestions and some other sources, I found usefull to convert an InetAdress to an array of bit, as well as BitSet, which can help to compute and(), or(), xor() out of your binary representation.
Following sample shows how to convert ip to binary and binary to ip.
Enjoy!
public class IpConverter {
public static void main(String[] args) {
String source = "192.168.1.1";
InetAddress ip = null;
try {
ip = InetAddress.getByName(source);
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
System.out.println( "source : " + ip);
// To bit sequence ------------
byte[] binaryIP = ip.getAddress();
BitSet[] bitsets = new BitSet[binaryIP.length];
int k = 0;
System.out.print("to binary: ");
for (byte b : binaryIP) {
bitsets[k] = byteToBitSet(b);
System.out.print( toString( bitsets[k] ) + ".");
k++;
}
System.out.println();
// Back to InetAdress ---------
byte[] binaryIP2 = new byte[4];
k = 0;
for (BitSet b : bitsets) {
binaryIP2[k] = bitSetToByte(b);
k++;
}
InetAddress ip2 = null;
try {
ip2 = InetAddress.getByAddress(binaryIP2);
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
System.out.println( "flipped back to : " + ip2);
}
public static BitSet byteToBitSet(byte b) {
BitSet bits = new BitSet(8);
for (int i = 0; i < 8; i++) {
bits.set(i, ((b & (1 << i)) != 0) );
}
return bits;
}
public static byte bitSetToByte(BitSet bits) {
int value = 0;
for (int i = 0; i < 8; i++) {
if (bits.get(i) == true) {
value = value | (1 << i);
}
}
return (byte) value;
}
public static byte bitsToByte(boolean[] bits) {
int value = 0;
for (int i = 0; i < 8; i++) {
if (bits[i] == true) {
value = value | (1 << i);
}
}
return (byte) value;
}
public static boolean[] byteToBits(byte b) {
boolean[] bits = new boolean[8];
for (int i = 0; i < bits.length; i++) {
bits[i] = ((b & (1 << i)) != 0);
}
return bits;
}
public static String toString(BitSet bits){
String out = "";
for (int i = 0; i < 8; i++) {
out += bits.get(i)?"1":"0";
}
return out;
}
}
The open-source IPAddress Java library can do this for you. It can parse various IP address formats, including either IPv4 or IPv6, and has methods to produce various string formats, including one for binary. Disclaimer: I am the project manager of the IPAddress library.
This code will do it:
static void convert(String str) {
IPAddressString string = new IPAddressString(str);
IPAddress addr = string.getAddress();
System.out.println(addr + " in binary is " + addr.toBinaryString());
}
Example:
convert("1.2.3.4");
convert("a:b:c:d:e:f:a:b");
The output is:
1.2.3.4 in binary is 00000001000000100000001100000100
a:b:c:d:e:f:a:b in binary is 00000000000010100000000000001011000000000000110000000000000011010000000000001110000000000000111100000000000010100000000000001011