Deserializing JSON Script

Good evening, sorry if this is a simple fix but I am trying to deserialize my JSON string from Arduino. Line 77,78,79 is my string output:

#include <MadgwickAHRS.h>
#include <Adafruit_LSM6DS33.h>
//include <ArduinoBLE.h>
#include <ArduinoJson.h>

Madgwick filter;
unsigned long microsPerReading, microsPrevious;
float accelScale, gyroScale;
Adafruit_LSM6DS33 lsm;
float accel_x, accel_y, accel_z;
float gyro_x, gyro_y, gyro_z;

void setup()
{
  Serial.begin(115200);

  // start the IMU and filter
  lsm.begin_I2C();
  filter.begin(26);

  // Set the accelerometer range to 2G
    lsm.setAccelRange(LSM6DS_ACCEL_RANGE_2_G);
  // Set the gyroscope range to 250 degrees/second
  lsm.setGyroRange(LSM6DS_GYRO_RANGE_250_DPS);

  lsm.setAccelDataRate(LSM6DS_RATE_26_HZ);
  lsm.setGyroDataRate(LSM6DS_RATE_26_HZ);

  // initialize variables to pace updates to correct rate
  microsPerReading = 1000000 / 26;
  microsPrevious = micros();
}

void loop() {
  int aix, aiy, aiz;
  int gix, giy, giz;
  float ax, ay, az;
  float gx, gy, gz;
  float roll, pitch, heading;
  unsigned long microsNow;

  // check if it's time to read data and update the filter
  microsNow = micros();
  if (microsNow - microsPrevious >= microsPerReading) {

    // read raw data from CurieIMU
    sensors_event_t accel;
    sensors_event_t gyro;
    sensors_event_t temp;
    lsm.getEvent(&accel, &gyro, &temp);
    accel_x = accel.acceleration.x;
    accel_y = accel.acceleration.y;
    accel_z = accel.acceleration.z;
    gyro_x = gyro.gyro.x;
    gyro_y = gyro.gyro.y;
    gyro_z = gyro.gyro.z;
 
    // convert from raw data to gravity and degrees/second units
    ax = convertRawAcceleration(accel_x);
    ay = convertRawAcceleration(accel_y);
    az = convertRawAcceleration(accel_z);
    gx = convertRawGyro(gyro_x);
    gy = convertRawGyro(gyro_y);
    gz = convertRawGyro(gyro_z);

    // update the filter, which computes orientation
    filter.updateIMU(gx, gy, gz, ax, ay, az);

    // print the heading, pitch and roll
    roll = filter.getRoll();
    pitch = filter.getPitch();
    heading = filter.getYaw();
 
 
    DynamicJsonDocument output(200);
    output["rolla"] = gyro_x;
    output["pitcha"] = gyro_y;
    output["yawa"] = gyro_z;

    serializeJson(output,Serial);
    Serial.println();
 
    // increment previous time, so we keep proper pace
    microsPrevious = microsPrevious + microsPerReading;
  }
}

float convertRawAcceleration(int aRaw) {
  // since we are using 2G range
  // -2g maps to a raw value of -32768
  // +2g maps to a raw value of 32767
 
  float a = (aRaw * 2.0) / 32768.0;
  return a;
}

float convertRawGyro(int gRaw) {
  // since we are using 250 degrees/seconds range
  // -250 maps to a raw value of -32768
  // +250 maps to a raw value of 32767
 
  float g = (gRaw * 250.0) / 32768.0;
  return g;
}

My problem is that I do not know how to receive this string in unity. This code is just a cube game that i want to move with roll, pitch, yaw, values. The examples online were only deserializing strings made in the c# program itself and not from an outside serial port like Arduino. Here is my code:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
//using System.Text.Json;


public class Test2 : MonoBehaviour
{
    SerialPort serialport = new SerialPort("COM20", 115200);
    public string json;
    public string[] datas;
    float sensitivity = 1f;
 
    void Start()
    {
        serialport.Open();
        serialport.DtrEnable = true;
    }

    void Update()
    {
     
        //Console.WriteLine("Hello");
     
        json = serialport.ReadLine();
        //string[] datas = receivedstring.Split(',');
        Console.WriteLine(json);
        //string jsona = JsonSerializer.Deserialize<json>(jsonString);
        Console.WriteLine($"Person's name: {json.rolla}");

        //Vector3 input = new Vector3(float.Parse(datas[1]), 0, float.Parse(datas[2]));
        //float hall = float.Parse(datas[0])/360;
        //float pitch = float.Parse(datas[1])/360;
        // float roll = float.Parse(datas[2])/360;

        //Vector3 input = new Vector3(0, 0, pitch);
        //float hall = float.Parse(receivedstring)/300;
        //Vector3 input = new Vector3(hall, 0,0);

        //Vector3 direction = input.normalized;
        //Vector3 velocity = direction * sensitivity;
        //Vector3 moveAmount = velocity * Time.deltaTime;
        //transform.Translate(input);

    }
}

In short, how can I write code that receives JSON? My current code can see the string but Idk how to “parse” it. The commented lines are from when I was parsing them individually.

public class Angles
{
    public float rolla = 0.0f;
    public float pitcha = 0.0f;
    public float yawa = 0.0f;
}

Angles angles = JsonUtility.FromJSON<Angles>(json);

JsonUtility is an easy and builtin solution that handles a lot of needs, but it does have some significant shortfalls with complex data (especially collections, such as Dictionaries, which are very commonly used in JSON). If you find yourself needing more, check out Newtonsoft’s JSON which is available as a Unity package and is conceptually compatible with JsonUtility (e.g. you can find and replace JsonUtility code without restructuring it).

Thank you for the replies! Will tries these solutions out today :slight_smile:

I’m still kind of new to Unity, would I put this inside void update()?

Wherever you’re currently receiving and parsing the text is where the FromJson line goes. The class definition should generally go outside of your MonoBehaviour class block (and certainly outside of any functions).

Here is my code right now. No errors which is good but now I want to parse my Json string so that I can start using the individual values. Example: Line 46 of my attempt to parse individual data.

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;


[Serializable]
public class Output
{
    public float rolla = 0.0f;
    public float pitcha = 0.0f;
    public float yawa = 0.0f;
}


public class Test2 : MonoBehaviour
{
    SerialPort serialport = new SerialPort("COM20", 115200);
    public string json;
    public string[] datas;
    float sensitivity = 1f;
  
  
    void Start()
    {
        serialport.Open();
        serialport.DtrEnable = true;
    }

    void Update()
    {

        //Console.WriteLine("Hello");

        json = serialport.ReadLine();
        //string[] datas = receivedstring.Split(',');
        Console.WriteLine(json);
        //string jsona = JsonSerializer.Deserialize<json>(jsonString);
        //Console.WriteLine($"Person's name: {json.rolla}");

        Output output = JsonUtility.FromJson<Output>(json);

        Console.WriteLine("rolla");
        //Vector3 input = new Vector3(float.Parse(datas[1]), 0, float.Parse(datas[2]));
        //float hall = float.Parse(datas[0])/360;
        //float pitch = float.Parse(datas[1])/360;
        // float roll = float.Parse(datas[2])/360;

        //Vector3 input = new Vector3(0, 0, pitch);
        //float hall = float.Parse(receivedstring)/300;
        //Vector3 input = new Vector3(hall, 0,0);

        //Vector3 direction = input.normalized;
        //Vector3 velocity = direction * sensitivity;
        //Vector3 moveAmount = velocity * Time.deltaTime;
        //transform.Translate(input);

    }
  
}

The parsing has already happened in line 44, and the “output” object contains the parsed data. So you can do something at this point like:

Console.WriteLine($"rolla is {output.rolla}");
1 Like

Perfect!! Thank you sooo much for the help! All my values can now be called where I need them. :slight_smile: