1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Download Package Now!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant here. Do not following these rules will lead to permanent exclusion from this website: Read the forum rules.

Question Understanding Arduino Interfaces

Discussion in 'DIY Motion Simulator Building Q&A / FAQ' started by Apocrathia, Dec 11, 2018.

  1. Apocrathia

    Apocrathia New Member

    Joined:
    Oct 8, 2018
    Messages:
    6
    Balance:
    52Coins
    Ratings:
    +0 / 0 / -0
    I'm trying to soak up as much information as I can right now, but I'm trying to put together a prototype 6DOF platform before I scale up. I would like to use an Arduino for the controller, but there are a couple of different codes available here. I'm thinking about trying to consolidate into a single firmware that I can post to GitHub for a little bit better centralization. Here's what I'm trying to understand:
    • Input message formats from SimTools (Serial & UDP)
    • 6DOF kinematics (can probably adapt from another firmware)
    • Output message formats (PWM to Sabertooth or SMC)
    Perhaps someone could point me in the direction of the appropriate documentation for understanding how each of these aspects of the interface is implemented.

    I am most likely going to go with a set Sabertooth 2x32 drivers on some worm geared DC motors. My current prototype is simply using the Futaba S3003 servos (using this design). I would like to build a custom firmware that would allow me to set the input and output formats, so that I can use the same codebase for both my prototype and full scale build.

    The current list of firmware choices (found here) are all over the place. I would really like to try to establish a uniform project that can support multiple input and output formats, as well as different kinematics (2DOF-6DOF). We've got a lot of the code already, it's just a matter of cleaning it up. Does anything like this already exist and I'm just missing something?
  2. T R Para

    T R Para i make stuff up Gold Contributor

    Joined:
    Oct 18, 2018
    Messages:
    89
    Occupation:
    Retired
    Location:
    Cincinnati, Oh
    Balance:
    427Coins
    Ratings:
    +50 / 1 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino
    Spoken like a true newbie..
    I can say that because I am also a newbie.
    I felt the same way. It seemed like the information was scattered everywhere.
    One link leading to another,to another to another until I was so lost I just hit control alt delete..
    The fact is the website is very well organized.
    The people here are very smart.
    Its all here.
    The problem is this is a very complex project.
    And everyone has to start at the same point .. the beginning..
    It just takes a lot of time.
    Then it takes a lot of money.
    Then lots more time.
    I would recommend building a simple 2dof rig, full size, something you can sit in.
    You will learn a ton. And appreciate how much effort people have gone through to put this site together and keep it running.

    Its pretty awesome.hug:
    • Agree Agree x 2
    • Optimistic Optimistic x 1
  3. Apocrathia

    Apocrathia New Member

    Joined:
    Oct 8, 2018
    Messages:
    6
    Balance:
    52Coins
    Ratings:
    +0 / 0 / -0
    Can you explain the organization at all? Because it does seem to be very scattered. No two projects are alike, and it leaves a lot of room for interpretation, with little explanation in some cases. A lot of this is similar to how 3D printers are designed, but I was able to get my first couple of printers built because of the centralized projects like Sailfish and Marlin. Nothing like that exists within this community that I have found (which is what I would like to start). The 3D printer community has also pretty ubiquitously decided use GCODE as the message format for communicating with the printers (aside from some oddballs that use binary formats like the MakerBots). However, I haven't been able to find anything like this that describes the message formats used by SimTools. I'm probably just looking in the wrong places. I'm not here trying to ask for everything to be handed to me, just a pointer in the right direction. The SimTools documentation doesn't really have this spelled out anywhere, and consists of 8 pages on a Wordpress site that were made 5 years ago. I'd have to reverse engineer somebody else's project, which is kind of silly, since this community has been going since around 2006.

    Although you say it's very well organized, it's moot if the organizational schema is not established. It's just scattered.

    I do software engineering for a living, and I'd love to be able to contribute to the community here. However, it's kinda hard when information is all over the place. If it's not and there is some sort of grand organization, can somebody please cue me in on the organizational schema, because it's not very straightforward. The FAQ is literally the best resource I have found so far, and it's a curated list of threads.

    I really appreciate what the community here has done, and there are clearly a ton of very bright hackers here. However, even you've agreed that it's scattered.

    I apologize for my frustration.
  4. pmvcda

    pmvcda aka FlyPT

    Joined:
    Nov 3, 2010
    Messages:
    187
    Location:
    Portugal
    Balance:
    1,163Coins
    Ratings:
    +232 / 1 / -0
    My Motion Simulator:
    6DOF
    In part I agree with you, it's hard to begin, but when you get the picture, you see all the possibilities.

    There are no message formats really, that's up to you to define them, the best way they suit your hardware.

    Well after reading some posts and understanding the difficulties some get with this, here's some explaining on how it works.
    Be careful, this is a fast forward explanation, and it might have some errors.
    Also, I wrote this for anybody, so don't feel offended, since you are a software engineer.

    #1
    A game plugin captures info from a game makes some treatment to that data and send's it to simtools

    #2
    Simtools receives that data.
    That data can be 9 values:
    Sway -> Usually that's here that the plugin put's the captured value for sway
    Surge -> Like above
    Heave
    Yaw
    Roll
    Pitch
    Extra 1 -> Some extra data the plugin sends (in car games, used many times for traction loss)
    Extra 2
    Extra 3

    #3
    Now with those 9 values, we can add/filter/compose them in different percentages to generate one or more axis output.
    Axis output are the movements produced by the motors/actuators connected to simtools.
    Simtools gives us the possibilitie to use up to 12 axes:
    Axis1a up to Axis6a
    Axis1b up to Axis6b
    So on the limit you can use 12 motors.

    #4
    Now simtools uses one interface to send the controls to the motors
    Imagine an hexapod. That's 6 motors to control.
    We are going to use 6 Axis, one for each motor.
    But we want to use Arduino boards to control the motors, and they can only control two motors each.
    No problem, simtools gives you 6 interfaces.
    You could use 6 Arduinos, but in this case, 3 make the job.
    So we define 3 interfaces.
    Now, you have many types of interfaces available, but for Arduino, you have to use serial.

    Before anything, we have to specify the connection to Arduino.
    Set the ComPort, bits per second, data bits, parity and stop bits.
    That's the basic for serial communication (look for info on the web).
    You have to understand how it works to use this.
    Put in a simple way, all this data, has to be the same on simtools and the Arduino board, or they can't communicate.

    Now we have to say how are we going to send info.
    Bit range is the "resolution" we want to use. We can send 8 bits, but that's just 255 values.
    Or 12 bits and we get 4096 values.
    That option depends on the type of construction you have for your rig.
    Imagine a 1 m actuator with 255 steps. That's to low. Now with 16 bits, you have 65536 steps. A huge resolution.

    The type of output is the way we send the data. It can be Binary, Decimal or Hex.
    If you choose decimal and want to send a value of 2436, simtools makes a string with that value "2436" and sends it through serial.
    If you choose binary (and more than 8 bits and less than 17), simtools sends two bytes only. Because they are enough to represent that number.
    See the difference? In decimal you have to send 4 bytes for this value, while in binary, 2 are enough.
    Hex, will generate an hexadecimal string. It's lees than decimal in size, but still more than binary.
    I personally prefer binary, although I think there are some problems with this in Simtools.

    Besides how, we have to say what we want to send to each Arduino.
    And that's the output.
    Before all, you can say at witch frequency you want to send that info in the output rate.
    Now what to send? The Axis!
    So if I want the first Arduino interface to send Axis 1 and 2, I can put the string "<Axis1a><Axis2>".
    The string sent to Arduino will have the values of each axis replacing those definitions.
    For example, in this case, if Axis1a=20 and Axis2a=556, the generated string would be "20556" if decimal is selected.
    Here's a problem, how to know where one value ends and the other starts?
    Well, we have to put a mark. For example: "A<Axis1a>B<Axis2a>"
    And the sent string would be "A20B556"
    Now it's easy to code the Arduino to get the info.
    Like I said before, I prefer the binary output. There I would need only 4 bytes to send those values, while in decimal I need in this case 7 bytes.
    If we want it fast and with less lag, we should use the solution that passes less info.
    Binary has a problem, where we have to send some bytes thet never happen to specify the start of info, and know if the next two bytes are for Axis1a or Axis1b.
    For example, if we are using 12 bits output, simtools uses 16 bits (8 bits multiples), so if we send tow 255 bytes, they are enough to specify the start, since they will never happen as a value of the axis.

    But. Be careful, because I had problems with the binary output.

    #5
    Now we sent the data to the Arduino boards.
    That data is usually the position we want the actuator to be.
    We have to code something in the arduino, like:
    -Get info from simtools
    -See where the actuator is
    -Send to the controller the speed and direction we want him to move to reach that desired position.

    That's where PID and other things enter. They can be implemented in hardware, or you could have to code them.
    It depends on what hardware you are using, and for that, you have to get info from the seller.
    But one thing is certain, you need to get the info from simtools.
    Here's some example code to get info with binary and values with 10 bits:

    Code:
    // ==================================
    // SimTools2 configuration should be:
    // ==================================
    // Interface settings:
    // Interface Type: Serial
    // ComPort: The one used by your Arduino
    // BitsPerSec: 57600 (You can change the define to use another speed)
    // Data Bits: 8
    // Parity: None
    // Stop Bits: 1
    // Output - Bit Range: 10
    // Output - Type: Binary
    // Startup - Output: -
    // HW Start: -
    // Interface output: [1<Axis1a>][2<Axis2a>]
    // Output Rate: 10ms
    // Shutdown - Output: -
    // HW Stop: -
    
    
    // ==============
    // Initialization
    // ==============
    void setup()
    {
      // Initialize serial comunication with SimTools2
      Serial.begin57600
    }
    
    // =============================
    // Get information from SimTools
    // =============================
    void getSimToolsCommands()
    {
      // Look for start and finish of a command on the serial
      // When we have a command send it form analyze
      while (Serial.available())
      {
        if (bufferCount == -1)
        {
          buffer = Serial.read();
          if (buffer != '[') bufferCount = -1;
          else bufferCount = 0;
        }
        else
        {
          buffer = Serial.read();
          bufferCommand[bufferCount] = buffer;
          bufferCount++;
          if (bufferCount > 3)
          {
            if (bufferCommand[3] == ']') analyzeSimToolsCommand();
            bufferCount = -1;
          }
        }
      }
    }
    
    
    // ================================
    // Analyze command sent by SimTools
    // ================================
    void analyzeSimToolsCommand()
    {
      // Analyze command, see if it's a command and wich actuator is affected
      switch (bufferCommand[0])
      {
        case '1':
          actuator1PretendedPosition = (bufferCommand[1] << 8) | bufferCommand[2];
          break;
        case '2':
          actuator2PretendedPosition = (bufferCommand[1] << 8) | bufferCommand[2];
          break;
        default:
          return;
          break;
      }
    }
    
    
    // =========
    // Main loop
    // =========
    void loop()
    {
      // While to make main loop, avoiding some of the Arduino framework delays
      while (1 == 1)
      {
        getSimToolsCommands();
     //
    //
    // OTHER CODE DEPENDING ON HARDWARE
      }
    }
    
    This can be really optimised and have some holes, specially after reading what I say above.
    • Winner Winner x 2
    • Like Like x 1
  5. Apocrathia

    Apocrathia New Member

    Joined:
    Oct 8, 2018
    Messages:
    6
    Balance:
    52Coins
    Ratings:
    +0 / 0 / -0
    I can definitely see the limitless possibilities. It just feels a lot like nobody can agree on the right implementation. I'm going to assume that the UDP datagram format looks a lot like the serial implementation (probably RS232), where the resolution value essentially delimits a stream of values. So, a 0-255 (8-bit) resolution, with 9 values will mean each message's data field is 144 bits (assuming binary encoding as mentioned above). It's then up to the controller to delimit and distribute those messages to the hardware.

    Am I understanding this correctly? I've worked with the Arduino platform for years, and that's not an issue. I would actually love to build something on the Raspberry Pi (using UDP instead of serial), but real-time performance will be the tricky part if you use the standard Linux kernel. I'd hate to have to go with freeRTOS, because there are some awesome things you could do with the Pi like hosting a small C&C web application. Whatever I do, I want to ensure that all of my code makes it to GitHub, as that seems to be an issue with a lot of projects here. This is a lot of room for some great collaborative efforts if it weren't for the segmentation of how these projects are presented.

    Bonus: Here's why having a million different projects of varying methodologies gets confusing.
    [​IMG]
  6. pmvcda

    pmvcda aka FlyPT

    Joined:
    Nov 3, 2010
    Messages:
    187
    Location:
    Portugal
    Balance:
    1,163Coins
    Ratings:
    +232 / 1 / -0
    My Motion Simulator:
    6DOF
    You can make your own interface plugin: https://www.xsimulator.net/communit...ugin-for-simtools-2-0-api-documentation.8813/
    UDP, what ever.