Using a joystick module with Arduino.

Hello everyone. I just made a game which a cube is moving on a platform without colliding any obstacles. I am trying to control the movement with a joystick module with an Arduino UNO. There is not any compilation errors and it runs well. After completing one level, it starts to lag and the smoothness just goes away (Just so you know, there is only one level and the same level keep reloading for now I just made this game for learning purposes). Also Arduino communication is closed after the level and I am sure it is closed because the lights o Arduino are reset every time level reloads So to sum up, it runs just fine when the Arduino is connected and runs without any issues just once. After the level is reloaded it becomes so laggy and it is impossible to control the character even using keyboard inputs.

This is movement script;

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

public class PlayerMovement : MonoBehaviour
{
    public Rigidbody rb;

    public float forwardForce = 4000f;
    public float sidewaysForce = 100f;
    public int CMD;

    public SerialPort sp = new SerialPort("COM7", 9600);

    // Start is called before the first frame update
    void Start()
    {
        sp.Open();
        sp.ReadTimeout = 1;
    }

    void FixedUpdate()
    {
        if (sp.IsOpen)
        {
            try
            {
                ReadCom();
                Move();
            }
            catch(System.Exception)
            {

            }
        }
        else
        {
            Move();
        }
    }

    // Update is called once per frame
    void Move()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime);

        if (Input.GetKey("d") || CMD == 6)
        {
            rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("a") || CMD == 4)
        {
            rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("w") || CMD == 8)
        {
            rb.AddForce(0, sidewaysForce * Time.deltaTime, 0, ForceMode.VelocityChange);
        }

        if (Input.GetKey("s") || CMD == 2)
        {
            rb.AddForce(0, -sidewaysForce * Time.deltaTime, 0, ForceMode.VelocityChange);
        }

        if (rb.position.y < -1f)
        {
            FindObjectOfType<GameManager>().EndGame();
        }
    }

    void ReadCom()
    {
        CMD = sp.ReadByte();
    }

    public void CloseCom()
    {
        sp.Close();
    }
}

This is collision script;

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


public class PlayerCollision : MonoBehaviour
{
    public PlayerMovement movement;


    void OnCollisionEnter(Collision collisionInfo)
    {
        if (collisionInfo.collider.tag == "Obstacle")
        {
            movement.enabled = false;
            FindObjectOfType<GameManager>().EndGame();
        }
    }
}

This is end game script;

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.IO.Ports;

public class GameManager : MonoBehaviour
{
    public Text scoreEdit;
    public GameObject overText;
    bool gameHasEnded = false;
    public GameObject completeLevelUI;

    public PlayerMovement movementC;


    public void CompleteLevel()
    {
        completeLevelUI.SetActive(true);
    }

    public void EndGame()
    {
        if (gameHasEnded == false)
        {
            gameHasEnded = true;
            Debug.Log("Game Over");
            Over();
            Invoke("Restart", 4f);
            movementC.CloseCom();
        }
    }

    void Restart()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    public void Over()
    {
        scoreEdit.color = Color.red;
        overText.SetActive(true);
    }
}

This is Arduino code (language: C);

const int x = A0;
const int y = A1;
const int button = 7;

int curX = 0;
int curY = 0;
int curB = 1;

void setup()
{
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(button, INPUT);
  Serial.begin(9600);
}

void loop()
{
  curX = analogRead(x);
  curY = analogRead(y);
  curB = digitalRead(button);

  if(analogRead(x) >=1000)
  {
    Serial.write(6);
    Serial.flush();
    //Serial.println(6);
    delay(10);
  }else if(analogRead(x) <= 10)
  {
    Serial.write(4);
    Serial.flush();
    //Serial.println(4);
    delay(10);
  }else if (analogRead(y) <= 10)
  {
    Serial.write(8);
    Serial.flush();
    //Serialprintln(8);
    delay(10);
  }else if (analogRead(y) >= 1000)
  {
    Serial.write(2);
    Serial.flush();
    //Serialprintln(2);
    delay(10);
  }else
  {
    Serial.write(0);
    Serial.flush();
    //Serial.println(0);
    delay(10);
  }
}

I added everything needed just in case. Many thanks for answers in advance.

I solved the issue and here is the answer;

I increased the baud rate of Arduino to 57600 (Can be 115200 also but it runs well with 57600).

Peace of code changed in Arduino script;

Serial.begin(57600);

Also, I deleted all of the delay function and added only one delay at the end of the loop function.

Peace of code changed in movement script;

public SerialPort sp = new SerialPort("COM7", 57600);

That solved the issue but I did not fully understand why it is solved because as I said, when the Arduino plugged in, it ran just fine and when the level is reloaded, it did not run as smooth as the first run. The only solution was plugging the Arduino again. But tt works fine now so the problem is solved.

something that could help is to put the script handeling the Arduino communication in Don’t destroy on load in Unity