Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Please Don't Ignore

Discussion in 'Scripting' started by LuK1MaN, Jul 3, 2020.

  1. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    Hello! have 2 potentiometer connected to arduino. I want to use first potmeter to move one object and second potmeter to move another object. I am new to C# and Arduino. this is my first project using those two. please give me some advices.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    There's a lot to unpack here.

    1) Write more descriptive titles in the future rather than something like "Help!" or "Please Don't Ignore".

    2) When asking questions try not to be broad. A question like yours can't really be answered in a post aside from supplying a link to a tutorial or something which you could have found yourself by googling.

    3) Demonstrate some effort on your part that you put into trying to accomplish the task and point out the areas you're having specific troubles with. This can help us come up with answers to your needs. We're not really here to hold your hand through the whole process, but really to help you get unstuck when you're stuck.

    4) Before getting into any specifics like "potentiometer with unity via arduino" maybe start with just integrated unity with an arduino to read values:

    google search:
    https://www.google.com/search?rlz=1C1SQJL_enUS858US858&sxsrf=ALeKk01l6cNL7a0qzwPqQG9-NqZh76nHUA:1593808206864&ei=TpX_XtOgNLmJytMPwqSz0As&q=unity+arduino+tutorial&oq=unity+arduino+tutorial&gs_lcp=CgZwc3ktYWIQAzIGCAAQFhAeMgYIABAWEB46BAgjECc6BQgAEJECOgUIABCDAToFCAAQsQM6AggAOgQIABBDOgcIABAUEIcCOggIABCxAxCRAjoHCAAQsQMQQ1DrqQJY8M4CYNHRAmgAcAB4AIABU4gBlwySAQIyMpgBAKABAaoBB2d3cy13aXq4AQM&sclient=psy-ab&ved=0ahUKEwjT_4mg9rHqAhW5hHIEHULSDLoQ4dUDCAw&uact=5

    here's one of the results:
    https://www.alanzucconi.com/2015/10/07/how-to-integrate-arduino-with-unity/

    Once you can start reading/writing data from the arduino. Then move to the potmeter.

    Then once you're reading the potmeter, then start looking into using that data to move objects on screen.

    Break your idea up into its constituent parts and tackle them one at a time.
     
    Ryiah likes this.
  3. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    Sorry for that(i was really tired after 27hours of working on this). I will post more info tomorrow about my codes and hardware.
     
  4. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    I have done verything you told me above. Everything works fine when i control 1 character with 1 potentiometer. Problem starts when I add second analog. C# reads only 1 analog data at the same time.
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    You should show us your code so we can suss out how you're reading from the arduino and see what you can do to read 2 values from it.
     
  6. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    This is arduino code:



    int player1 = 0;
    int player2 = 0;

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

    void loop() {
    player1 = analogRead(A0);
    player2 = analogRead(A1);

    if (player1 < 512)
    {
    Serial.write(1);
    //Serial.print(1);
    Serial.flush();
    delay(20);
    }
    else
    {
    Serial.write(2);
    //Serial.print(2);
    Serial.flush();
    delay(20);
    }

    //Serial.print(",");
    //delay(20);

    if (player2 < 512)
    {
    Serial.write(3);
    //Serial.println(3);
    Serial.flush();
    delay(20);
    }
    else
    {
    Serial.write(4);
    //Serial.println(4);
    Serial.flush();
    delay(20);
    }
    }
     
  7. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    Code (CSharp):
    1. using UnityEngine;
    2. using System.IO.Ports;
    3.  
    4. public class Move : MonoBehaviour
    5. {
    6.     public bool isPlayer1;
    7.     public bool isPlayer2;
    8.  
    9.     SerialPort sp = new SerialPort("COM4", 9600);
    10.  
    11.     void Start()
    12.     {
    13.         sp.Open();
    14.         sp.ReadTimeout = 1;
    15.     }
    16.     void Update()
    17.     {
    18.         if (isPlayer1 == true)
    19.         {
    20.             if (sp.ReadByte() == 1)
    21.             {
    22.                 Debug.Log("1");
    23.             }
    24.             else if (sp.ReadByte() == 2)
    25.             {
    26.                 Debug.Log("2");
    27.             }
    28.         }
    29.  
    30.  
    31.         if (isPlayer2 == true)
    32.         {
    33.             if (sp.ReadByte() == 3)
    34.             {
    35.                 Debug.Log("3");
    36.             }
    37.             else if (sp.ReadByte() == 4)
    38.             {
    39.                 Debug.Log("4");
    40.             }
    41.         }
    42.     }
    43. }  
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    Your Arduino is sending 2 bytes over the serial port, but your move script is reading anywhere from 1 to 4 bytes depending on the values of "isPlayer1" and "isPlayer2" and whether you are seeing your expected value at first or not . You need to consume the exact number of bytes coming from the Arduino or the data will become misaligned from what you are expecting.

    Just put two ReadByte() calls at the beginning of Update and save them to a couple of variables. Then do your comparisons against those variables. That will give you a consistent number of reads.
     
    Last edited: Jul 4, 2020
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    I would also point out that the arduino code is putting a 20ms delay after each send. Considering a framerate at 60fps is about 16.67ms, this means you're only sending 1 player every other frame (there abouts). So you're toggling back and forth frame to frame (or there abouts).

    Instead in your arduino you should only write to the Serial and delay(20) once per "loop".

    Come up with a 'format' for your byte. You could maybe have the top 4 bits be your player1, and the bottom 4 bits be your player2. Write those values into your byte, then call Serial.write with that byte. Then delay(20).
     
    PraetorBlue and Ryiah like this.
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    Also, you're going to have a general timing issue. Your arduino is just sending data willy nilly, and you're just reading it willy nilly, out of sync with one another.

    Just because you read in 'Update' and write in 'loop' doesn't mean you're reading in sequence. 'Update' is framerate dependent.

    Basically your arduino is writing every (20 + N)ms (however long your program takes to process between sends, plus 20ms). And Unity runs at god knows what depending the machine the game is played on.

    So now lets say we're on a really good machine with no framerate cap. We're getting 120+fps. This means we're getting no data back 2 out of 3 frames. But a machine that is dog slow may be running at 30fps or lower... now the arduino is sending too much data and is filling up the buffer. The buffer by default is 4096 bytes in size, after a while you'll overrun the buffer and honestly I'm not sure what .Net does with an overrun buffer... it may dump it, or it may throw an exception. Never actually tested it to see.

    What you should do is wrap your serial process in some class that deals with this timing issue.

    Usually how input system like this where it relies on a receive buffer is that you have a 'state' for the input that is updated frame by frame. The input device is sending its state (so the input does not send a "press" event, it sends IF a button/input is pressed/depressed... and if that is an analogue value it includes the value of how much it's pressed/depressed). You read the entirity of the buffer and only use the last value of the buffer to update your internal state. If NOTHING was in the buffer you just assume the state hasn't changed since the previous frame. (you could also do this on its own thread constantly updating the state, while only signaling state shifts based on framerate).

    Note, this would usually be done in its own class like an "InputDevice" class. It'd handle the reading from the arduino. Then your "Move" script would access the "InputDevice" and ask for the current state, rather than directly reading from the arduino in your "Move" script.
     
    Ryiah likes this.
  11. LuK1MaN

    LuK1MaN

    Joined:
    Feb 15, 2020
    Posts:
    6
    I think i got it now, i cant thank you enough. I'll start coding asap. Thank you very much sir.